#!/usr/bin/env python3
"""ASUCB Template Manager — save and load reusable course structure templates.

Templates capture module names, items, types, and point values from a Canvas
course and store them as JSON for reuse in new courses.

Storage: templates/saved/tmpl-{uuid}.json
"""

import argparse
import json
import os
import sys
import uuid

sys.path.insert(0, os.path.dirname(__file__))
import canvas_api
import course_navigator


def _templates_dir():
    """Return the templates/saved directory, creating if needed."""
    root = canvas_api.get_plugin_root()
    path = os.path.join(root, "templates", "saved")
    os.makedirs(path, exist_ok=True)
    return path


def _template_id():
    """Generate a unique template ID."""
    return f"tmpl-{uuid.uuid4().hex[:12]}"


def save_template(config, name, description=""):
    """Save current course structure as a reusable template.

    Returns template dict with id, name, structure summary.
    """
    tree = course_navigator.fetch_course_tree(config)

    # Get course name
    resp = canvas_api._request_with_retry(
        __import__("requests").get,
        f"{config['course_url']}",
        config["headers"],
    )
    course_name = ""
    if resp and resp.status_code == 200:
        course_name = resp.json().get("name", "")

    template_id = _template_id()
    structure = []
    total_items = 0

    for mod in tree:
        module = {"name": mod["name"], "items": []}
        for item in mod["items"]:
            module["items"].append({
                "title": item["title"],
                "item_type": item["type"],
                "indent_level": item.get("indent", 0),
                "published": item.get("published", False),
            })
            total_items += 1
        structure.append(module)

    from datetime import datetime, timezone
    template = {
        "id": template_id,
        "name": name,
        "description": description,
        "source_course_id": config["course_id"],
        "source_course_name": course_name,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "module_count": len(structure),
        "item_count": total_items,
        "structure": structure,
    }

    path = os.path.join(_templates_dir(), f"{template_id}.json")
    with open(path, "w", encoding="utf-8") as f:
        json.dump(template, f, indent=2, ensure_ascii=False)

    print(f"  Saved template: {name} ({len(structure)} modules, {total_items} items)")
    return template


def list_templates():
    """List all saved templates (summary only, no structure)."""
    templates = []
    tdir = _templates_dir()
    for fname in sorted(os.listdir(tdir)):
        if not fname.endswith(".json"):
            continue
        try:
            with open(os.path.join(tdir, fname), "r", encoding="utf-8") as f:
                t = json.load(f)
            templates.append({
                "id": t["id"],
                "name": t["name"],
                "description": t.get("description", ""),
                "source_course_name": t.get("source_course_name", ""),
                "module_count": t.get("module_count", 0),
                "item_count": t.get("item_count", 0),
                "created_at": t.get("created_at", ""),
            })
        except (json.JSONDecodeError, KeyError):
            continue
    return templates


def get_template(template_id):
    """Load a full template by ID, including structure."""
    path = os.path.join(_templates_dir(), f"{template_id}.json")
    if not os.path.exists(path):
        return None
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f)


def delete_template(template_id):
    """Delete a template by ID. Returns True if deleted."""
    path = os.path.join(_templates_dir(), f"{template_id}.json")
    if os.path.exists(path):
        os.remove(path)
        return True
    return False


# ============================================================
# CLI
# ============================================================
def main():
    parser = argparse.ArgumentParser(description="ASUCB Template Manager")

    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--save", action="store_true", help="Save course as template")
    group.add_argument("--list", action="store_true", help="List templates")
    group.add_argument("--get", action="store_true", help="Get template by ID")
    group.add_argument("--delete", action="store_true", help="Delete template")

    parser.add_argument("--name", help="Template name (for --save)")
    parser.add_argument("--description", default="", help="Template description")
    parser.add_argument("--template-id", help="Template ID (for --get/--delete)")
    parser.add_argument("--course-id", help="Course ID override")

    args = parser.parse_args()

    if args.save:
        if not args.name:
            parser.error("--save requires --name")
        config = canvas_api.get_config(course_id=args.course_id)
        canvas_api.require_course_id(config)
        template = save_template(config, args.name, args.description)
        print(json.dumps(template, indent=2))

    elif args.list:
        templates = list_templates()
        print(json.dumps({"templates": templates}, indent=2))

    elif args.get:
        if not args.template_id:
            parser.error("--get requires --template-id")
        template = get_template(args.template_id)
        if template:
            print(json.dumps(template, indent=2))
        else:
            print(json.dumps({"error": "Template not found"}))
            sys.exit(1)

    elif args.delete:
        if not args.template_id:
            parser.error("--delete requires --template-id")
        if delete_template(args.template_id):
            print(json.dumps({"ok": True, "deleted": args.template_id}))
        else:
            print(json.dumps({"ok": False, "error": "Template not found"}))
            sys.exit(1)


if __name__ == "__main__":
    main()
