# api/mc.py
# Mission Control — Projects & Tasks API
# Rose's persönliches PM-System

import json
import uuid
from pathlib import Path
from datetime import datetime, date, timedelta

HERMES_HOME = Path.home() / ".hermes"
DATA_DIR = HERMES_HOME / "data" / "mc"
DATA_DIR.mkdir(parents=True, exist_ok=True)

TASKS_FILE = DATA_DIR / "tasks.json"
PROJECTS_FILE = DATA_DIR / "projects.json"

TASKS_FILE.write_text(json.dumps({"version": "3.0.0", "tasks": []}, indent=2))
PROJECTS_FILE.write_text(json.dumps({"version": "3.0.0", "projects": []}, indent=2))

# ─────────────────────────────────────────────────────────────────────────────
# AGENT REGISTRY
# ─────────────────────────────────────────────────────────────────────────────

AGENTS = {
    "root":          {"name": "🌳 Root",           "emoji": "🌳", "domain": "Infrastruktur, Server, Docker, Backups"},
    "forget-me-not": {"name": "🌼 Forget-me-not",  "emoji": "🌼", "domain": "Kalender, Termine, Geburtstage"},
    "sunflower":     {"name": "🌻 Sunflower",      "emoji": "🌻", "domain": "Finanzen, Abos, Rechnungen"},
    "iris":          {"name": "⚜️ Iris",            "emoji": "⚜️", "domain": "Karriere, Lernen, Focus"},
    "lotus":         {"name": "🪷 Lotus",           "emoji": "🪷", "domain": "Gesundheit, Fitness, Hobbys"},
    "ivy":           {"name": "🌿 Ivy",             "emoji": "🌿", "domain": "Smart Home, Home Assistant"},
    "dandelion":     {"name": "🛡 Dandelion",       "emoji": "🛡", "domain": "Kommunikation, Notifications, Spam"},
    "rose":          {"name": "🌹 Rose",            "emoji": "🌹", "domain": "Orchestrierung, Koordination"},
}

# ─────────────────────────────────────────────────────────────────────────────
# INTERNAL HELPERS
# ─────────────────────────────────────────────────────────────────────────────

def _load_tasks():
    if TASKS_FILE.exists():
        with TASKS_FILE.open(encoding="utf-8") as f:
            return json.loads(f.read())
    return {"version": "3.0.0", "tasks": []}

def _save_tasks(data):
    TASKS_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False))

def _load_projects():
    if PROJECTS_FILE.exists():
        with PROJECTS_FILE.open(encoding="utf-8") as f:
            return json.loads(f.read())
    return {"version": "3.0.0", "projects": []}

def _save_projects(data):
    PROJECTS_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False))

def _new_id(prefix="task"):
    return f"{prefix}-{datetime.now().strftime('%y%m%d%H%M%S')}-{uuid.uuid4().hex[:4]}"

def _now():
    return datetime.now().isoformat()

def _today():
    return date.today().isoformat()

def _auto_done_subtasks(item):
    """Check if all subtasks are done (for auto-done logic)."""
    subtasks = item.get("subtasks", [])
    if not subtasks:
        return None
    all_done = all(s.get("done", False) for s in subtasks)
    return all_done

# ─────────────────────────────────────────────────────────────────────────────
# TASKS — CRUD
# ─────────────────────────────────────────────────────────────────────────────

def list_tasks(filters=None):
    """GET /api/mc/tasks — alle Tasks mit optionalen Filtern."""
    data = _load_tasks()
    tasks = data.get("tasks", [])

    if not filters:
        return tasks

    # Filter: project_id
    if "project_id" in filters and filters["project_id"]:
        tasks = [t for t in tasks if t.get("project_id") == filters["project_id"]]

    # Filter: phase_id
    if "phase_id" in filters and filters["phase_id"]:
        tasks = [t for t in tasks if t.get("phase_id") == filters["phase_id"]]

    # Filter: task_type
    if "task_type" in filters and filters["task_type"]:
        tasks = [t for t in tasks if t.get("task_type") == filters["task_type"]]

    # Filter: type (user/agent)
    if "type" in filters and filters["type"]:
        tasks = [t for t in tasks if t.get("type") == filters["type"]]

    # Filter: assigned_agent
    if "assigned_agent" in filters and filters["assigned_agent"]:
        tasks = [t for t in tasks if t.get("assigned_agent") == filters["assigned_agent"]]

    # Filter: status
    if "status" in filters and filters["status"]:
        tasks = [t for t in tasks if t.get("status") == filters["status"]]

    # Filter: priority
    if "priority" in filters and filters["priority"]:
        tasks = [t for t in tasks if t.get("priority") == filters["priority"]]

    # Filter: task_type = one-time | daily (shorthand)
    if "task_type" in filters and filters["task_type"]:
        tasks = [t for t in tasks if t.get("task_type") == filters["task_type"]]

    return tasks

def get_task(task_id):
    """GET /api/mc/tasks/:id — einzelner Task."""
    data = _load_tasks()
    return next((t for t in data["tasks"] if t["id"] == task_id), None)

def create_task(body):
    """POST /api/mc/tasks — Task erstellen."""
    data = _load_tasks()

    task = {
        "id": _new_id("task"),
        "title": body.get("title", "Untitled Task"),
        "task_type": body.get("task_type", "one-time"),
        "type": body.get("type", "user"),
        "project_id": body.get("project_id"),
        "phase_id": body.get("phase_id"),
        "status": body.get("status", "todo"),
        "priority": body.get("priority", "p2"),
        "due": body.get("due"),
        "due_time": body.get("due_time"),
        "tags": body.get("tags", []),
        "daily_schedule": body.get("daily_schedule"),
        "daily_completed_today": False,
        "daily_last_done": None,
        "assigned_agent": body.get("assigned_agent"),
        "agent_status": "pending" if body.get("type") == "agent" else None,
        "agent_note": body.get("agent_note"),
        "cron_schedule": body.get("cron_schedule"),
        "cron_last_run": None,
        "cron_next_run": None,
        "subtasks": [],
        "created_by": body.get("created_by", "user"),
        "created_at": _now(),
        "updated_at": _now(),
        "completed_at": None,
    }

    data["tasks"].append(task)
    _save_tasks(data)
    return task

def update_task(task_id, body):
    """PUT /api/mc/tasks/:id — Task updaten."""
    data = _load_tasks()

    for t in data["tasks"]:
        if t["id"] == task_id:
            # Erlaubte Felder
            for key in ["title", "task_type", "type", "project_id", "phase_id",
                         "status", "priority", "due", "due_time", "tags",
                         "daily_schedule", "assigned_agent", "agent_status",
                         "agent_note", "cron_schedule", "cron_last_run",
                         "cron_next_run", "daily_completed_today", "daily_last_done"]:
                if key in body:
                    t[key] = body[key]

            # Status → completed_at
            if body.get("status") == "done" and t["completed_at"] is None:
                t["completed_at"] = _now()
            elif body.get("status") and body.get("status") != "done":
                t["completed_at"] = None

            t["updated_at"] = _now()

            # Auto-done via subtasks
            all_done = _auto_done_subtasks(t)
            if all_done is True and t["status"] != "done":
                t["status"] = "done"
                t["completed_at"] = _now()
            elif all_done is False and t["status"] == "done":
                t["status"] = "todo"

            _save_tasks(data)
            return t

    return None

def delete_task(task_id):
    """DELETE /api/mc/tasks/:id — Task löschen."""
    data = _load_tasks()
    before = len(data["tasks"])
    data["tasks"] = [t for t in data["tasks"] if t["id"] != task_id]
    _save_tasks(data)
    return len(data["tasks"]) < before

# ─────────────────────────────────────────────────────────────────────────────
# DAILY TASKS
# ─────────────────────────────────────────────────────────────────────────────

def list_daily():
    """GET /api/mc/daily — alle Daily Tasks."""
    return list_tasks({"task_type": "daily"})

def toggle_daily_done(task_id):
    """POST /api/mc/daily/:id/done — Daily Task heute erledigt togglen."""
    data = _load_tasks()

    for t in data["tasks"]:
        if t["id"] == task_id and t.get("task_type") == "daily":
            t["daily_completed_today"] = not t["daily_completed_today"]
            if t["daily_completed_today"]:
                t["daily_last_done"] = _today()
                t["status"] = "done"
                t["completed_at"] = _now()
            else:
                t["status"] = "todo"
                t["completed_at"] = None
            t["updated_at"] = _now()
            _save_tasks(data)
            return t

    return None

def reset_daily_tasks():
    """POST /api/mc/daily/reset — Alle daily_completed_today = false (Mitternacht)."""
    data = _load_tasks()
    for t in data["tasks"]:
        if t.get("task_type") == "daily":
            t["daily_completed_today"] = False
            if t["status"] == "done" and t.get("daily_last_done") != _today():
                t["status"] = "todo"
                t["completed_at"] = None
    _save_tasks(data)
    return {"ok": True, "reset_at": _now()}

# ─────────────────────────────────────────────────────────────────────────────
# SUBTASKS — TASK LEVEL
# ─────────────────────────────────────────────────────────────────────────────

def add_subtask_task(task_id, body):
    """POST /api/mc/tasks/:id/subtasks — Subtask zu Task."""
    data = _load_tasks()
    for t in data["tasks"]:
        if t["id"] == task_id:
            subtask = {
                "id": _new_id("sub"),
                "title": body.get("title", "Subtask"),
                "done": False,
                "order": len(t.get("subtasks", [])) + 1,
                "created_at": _now(),
            }
            if "subtasks" not in t:
                t["subtasks"] = []
            t["subtasks"].append(subtask)
            t["updated_at"] = _now()
            _save_tasks(data)
            return subtask
    return None

def update_subtask_task(task_id, subtask_id, body):
    """PUT /api/mc/tasks/:id/subtasks/:sid — Subtask updaten."""
    data = _load_tasks()
    for t in data["tasks"]:
        if t["id"] == task_id:
            for s in t.get("subtasks", []):
                if s["id"] == subtask_id:
                    if "title" in body:
                        s["title"] = body["title"]
                    if "done" in body:
                        s["done"] = body["done"]
                    if "order" in body:
                        s["order"] = body["order"]
                    t["updated_at"] = _now()

                    # Auto-done check
                    all_done = _auto_done_subtasks(t)
                    if all_done is True and t["status"] != "done":
                        t["status"] = "done"
                        t["completed_at"] = _now()
                    elif all_done is False and t["status"] == "done":
                        t["status"] = "todo"
                        t["completed_at"] = None

                    _save_tasks(data)
                    return s
    return None

def delete_subtask_task(task_id, subtask_id):
    """DELETE /api/mc/tasks/:id/subtasks/:sid — Subtask löschen."""
    data = _load_tasks()
    for t in data["tasks"]:
        if t["id"] == task_id:
            before = len(t.get("subtasks", []))
            t["subtasks"] = [s for s in t.get("subtasks", []) if s["id"] != subtask_id]
            t["updated_at"] = _now()
            _save_tasks(data)
            return len(t["subtasks"]) < before
    return False

# ─────────────────────────────────────────────────────────────────────────────
# PROJECTS — CRUD
# ─────────────────────────────────────────────────────────────────────────────

def list_projects():
    """GET /api/mc/projects — alle Projekte mit Phasen."""
    data = _load_projects()
    return data.get("projects", [])

def get_project(project_id):
    """GET /api/mc/projects/:id — einzelnes Projekt."""
    data = _load_projects()
    return next((p for p in data["projects"] if p["id"] == project_id), None)

def create_project(body):
    """POST /api/mc/projects — Projekt erstellen."""
    data = _load_projects()

    project = {
        "id": body.get("id") or _new_id("proj").replace("proj-", ""),
        "name": body.get("name", "Neues Projekt"),
        "color": body.get("color", "#6366f1"),
        "description": body.get("description", ""),
        "status": body.get("status", "active"),
        "created_at": _now(),
        "updated_at": _now(),
        "subtasks": [],
        "phases": [],
    }

    data["projects"].append(project)
    _save_projects(data)
    return project

def update_project(project_id, body):
    """PUT /api/mc/projects/:id — Projekt updaten."""
    data = _load_projects()

    for p in data["projects"]:
        if p["id"] == project_id:
            for key in ["name", "color", "description", "status"]:
                if key in body:
                    p[key] = body[key]
            p["updated_at"] = _now()
            _save_projects(data)
            return p

    return None

def delete_project(project_id):
    """DELETE /api/mc/projects/:id — Projekt löschen."""
    data = _load_projects()
    before = len(data["projects"])
    data["projects"] = [p for p in data["projects"] if p["id"] != project_id]
    _save_projects(data)

    # Auch alle Tasks dieses Projekts löschen
    tasks_data = _load_tasks()
    tasks_data["tasks"] = [t for t in tasks_data["tasks"] if t.get("project_id") != project_id]
    _save_tasks(tasks_data)

    return len(data["projects"]) < before

# ─────────────────────────────────────────────────────────────────────────────
# PROJECT SUBTASKS
# ─────────────────────────────────────────────────────────────────────────────

def add_subtask_project(project_id, body):
    """POST /api/mc/projects/:id/subtasks."""
    data = _load_projects()
    for p in data["projects"]:
        if p["id"] == project_id:
            subtask = {
                "id": _new_id("sub"),
                "title": body.get("title", "Subtask"),
                "done": False,
                "order": len(p.get("subtasks", [])) + 1,
                "created_at": _now(),
            }
            if "subtasks" not in p:
                p["subtasks"] = []
            p["subtasks"].append(subtask)
            p["updated_at"] = _now()
            _save_projects(data)
            return subtask
    return None

def update_subtask_project(project_id, subtask_id, body):
    """PUT /api/mc/projects/:id/subtasks/:sid."""
    data = _load_projects()
    for p in data["projects"]:
        if p["id"] == project_id:
            for s in p.get("subtasks", []):
                if s["id"] == subtask_id:
                    if "title" in body:
                        s["title"] = body["title"]
                    if "done" in body:
                        s["done"] = body["done"]
                    if "order" in body:
                        s["order"] = body["order"]
                    p["updated_at"] = _now()
                    _save_projects(data)
                    return s
    return None

def delete_subtask_project(project_id, subtask_id):
    """DELETE /api/mc/projects/:id/subtasks/:sid."""
    data = _load_projects()
    for p in data["projects"]:
        if p["id"] == project_id:
            before = len(p.get("subtasks", []))
            p["subtasks"] = [s for s in p.get("subtasks", []) if s["id"] != subtask_id]
            p["updated_at"] = _now()
            _save_projects(data)
            return len(p["subtasks"]) < before
    return False

# ─────────────────────────────────────────────────────────────────────────────
# PHASES
# ─────────────────────────────────────────────────────────────────────────────

def add_phase(project_id, body):
    """POST /api/mc/projects/:id/phases — Phase hinzufügen."""
    data = _load_projects()

    for p in data["projects"]:
        if p["id"] == project_id:
            phase = {
                "id": _new_id("phase"),
                "name": body.get("name", "Neue Phase"),
                "description": body.get("description", ""),
                "testing": body.get("testing", ""),
                "testing_status": body.get("testing_status", "pending"),
                "reflection": body.get("reflection"),
                "status": body.get("status", "todo"),
                "order": len(p.get("phases", [])) + 1,
                "completed_at": None,
                "subtasks": [],
            }
            if "phases" not in p:
                p["phases"] = []
            p["phases"].append(phase)
            p["updated_at"] = _now()
            _save_projects(data)
            return phase

    return None

def update_phase(phase_id, body):
    """PUT /api/mc/phases/:id — Phase updaten."""
    data = _load_projects()

    for p in data["projects"]:
        for ph in p.get("phases", []):
            if ph["id"] == phase_id:
                for key in ["name", "description", "testing", "testing_status",
                             "reflection", "status", "order"]:
                    if key in body:
                        ph[key] = body[key]

                if body.get("status") == "done" and ph["completed_at"] is None:
                    ph["completed_at"] = _now()
                elif body.get("status") and body.get("status") != "done":
                    ph["completed_at"] = None

                p["updated_at"] = _now()
                _save_projects(data)
                return ph

    return None

def delete_phase(phase_id):
    """DELETE /api/mc/phases/:id — Phase löschen."""
    data = _load_projects()

    for p in data["projects"]:
        before = len(p.get("phases", []))
        p["phases"] = [ph for ph in p.get("phases", []) if ph["id"] != phase_id]
        if len(p["phases"]) < before:
            p["updated_at"] = _now()
            _save_projects(data)

            # Tasks dieser Phase auf standalone setzen
            tasks_data = _load_tasks()
            for t in tasks_data["tasks"]:
                if t.get("phase_id") == phase_id:
                    t["phase_id"] = None
            _save_tasks(tasks_data)

            return True

    return False

def complete_phase(phase_id):
    """PUT /api/mc/phases/:id/complete — Phase als done markieren."""
    return update_phase(phase_id, {"status": "done", "completed_at": _now()})

# ─────────────────────────────────────────────────────────────────────────────
# PHASE SUBTASKS
# ─────────────────────────────────────────────────────────────────────────────

def add_subtask_phase(phase_id, body):
    """POST /api/mc/phases/:id/subtasks."""
    data = _load_projects()

    for p in data["projects"]:
        for ph in p.get("phases", []):
            if ph["id"] == phase_id:
                subtask = {
                    "id": _new_id("sub"),
                    "title": body.get("title", "Subtask"),
                    "done": False,
                    "order": len(ph.get("subtasks", [])) + 1,
                    "created_at": _now(),
                }
                if "subtasks" not in ph:
                    ph["subtasks"] = []
                ph["subtasks"].append(subtask)
                p["updated_at"] = _now()
                _save_projects(data)
                return subtask

    return None

def update_subtask_phase(phase_id, subtask_id, body):
    """PUT /api/mc/phases/:id/subtasks/:sid."""
    data = _load_projects()

    for p in data["projects"]:
        for ph in p.get("phases", []):
            if ph["id"] == phase_id:
                for s in ph.get("subtasks", []):
                    if s["id"] == subtask_id:
                        if "title" in body:
                            s["title"] = body["title"]
                        if "done" in body:
                            s["done"] = body["done"]
                        if "order" in body:
                            s["order"] = body["order"]
                        p["updated_at"] = _now()

                        # Auto-done check für phase
                        all_done = all(st.get("done", False) for st in ph.get("subtasks", []))
                        if all_done and ph["status"] != "done":
                            ph["status"] = "done"
                            ph["completed_at"] = _now()

                        _save_projects(data)
                        return s
    return None

def delete_subtask_phase(phase_id, subtask_id):
    """DELETE /api/mc/phases/:id/subtasks/:sid."""
    data = _load_projects()

    for p in data["projects"]:
        for ph in p.get("phases", []):
            if ph["id"] == phase_id:
                before = len(ph.get("subtasks", []))
                ph["subtasks"] = [s for s in ph.get("subtasks", []) if s["id"] != subtask_id]
                p["updated_at"] = _now()
                _save_projects(data)
                return len(ph["subtasks"]) < before

    return False

# ─────────────────────────────────────────────────────────────────────────────
# AGENT ACTIONS
# ─────────────────────────────────────────────────────────────────────────────

def agent_progress(task_id, body):
    """POST /api/mc/tasks/:id/progress — Agent meldet Fortschritt."""
    return update_task(task_id, {
        "agent_status": body.get("agent_status"),
        "agent_note": body.get("agent_note"),
        "cron_last_run": body.get("cron_last_run"),
        "cron_next_run": body.get("cron_next_run"),
    })

def agent_note(task_id, body):
    """POST /api/mc/tasks/:id/note — Agent setzt Notiz."""
    return update_task(task_id, {"agent_note": body.get("note")})

def get_agents():
    """GET /api/mc/agents — Agent-Registry."""
    return AGENTS

# ─────────────────────────────────────────────────────────────────────────────
# STATS
# ─────────────────────────────────────────────────────────────────────────────

def get_stats():
    """GET /api/mc/stats — Statistiken."""
    tasks_data = _load_tasks()
    projects_data = _load_projects()
    tasks = tasks_data.get("tasks", [])
    projects = projects_data.get("projects", [])

    total = len(tasks)
    done = len([t for t in tasks if t.get("status") == "done"])
    today = _today()

    # Overdue
    overdue = len([t for t in tasks if t.get("due") and t["due"] < today and t.get("status") != "done"])

    # By priority
    by_priority = {"p1": 0, "p2": 0, "p3": 0}
    for t in tasks:
        p = t.get("priority", "p2")
        if p in by_priority:
            by_priority[p] += 1

    # By type
    by_type = {"one-time": 0, "daily": 0}
    for t in tasks:
        tt = t.get("task_type", "one-time")
        if tt in by_type:
            by_type[tt] += 1

    # By status
    by_status = {"todo": 0, "in_progress": 0, "review": 0, "done": 0}
    for t in tasks:
        s = t.get("status", "todo")
        if s in by_status:
            by_status[s] += 1

    # Daily done today
    daily_done_today = len([t for t in tasks if t.get("task_type") == "daily" and t.get("daily_completed_today", False)])

    # Streak: consecutive days with completions going backwards
    streak = 0
    check_date = date.today()
    done_dates = set()
    for t in tasks:
        c = t.get("completed_at")
        if c:
            done_dates.add(c[:10])
    while True:
        d = check_date.isoformat()
        if d in done_dates:
            streak += 1
            check_date -= timedelta(days=1)
        else:
            break

    # Agent activity
    agent_activity = {}
    for agent_id, agent in AGENTS.items():
        agent_tasks = [t for t in tasks if t.get("assigned_agent") == agent_id]
        active = next((t for t in agent_tasks if t.get("agent_status") in ("running", "pending")), None)
        agent_activity[agent_id] = {
            **agent,
            "task_count": len(agent_tasks),
            "status": "active" if active else "idle",
            "current_task": active["title"] if active else None,
        }

    # Project progress
    project_progress = []
    for pr in projects:
        pr_tasks = [t for t in tasks if t.get("project_id") == pr["id"]]
        pr_tasks_done = len([t for t in pr_tasks if t.get("status") == "done"])
        phases_total = len(pr.get("phases", []))
        phases_done = len([ph for ph in pr.get("phases", []) if ph.get("status") == "done"])
        project_progress.append({
            "id": pr["id"],
            "name": pr["name"],
            "color": pr.get("color"),
            "status": pr.get("status"),
            "tasks_total": len(pr_tasks),
            "tasks_done": pr_tasks_done,
            "phases_total": phases_total,
            "phases_done": phases_done,
        })

    return {
        "total": total,
        "done": done,
        "overdue": overdue,
        "streak": streak,
        "daily_done_today": daily_done_today,
        "by_priority": by_priority,
        "by_type": by_type,
        "by_status": by_status,
        "project_progress": project_progress,
        "agent_activity": agent_activity,
    }
