"""Tasks skill — local task and project tracker."""

from datetime import datetime, timezone

from fliiq.runtime.config import resolve_fliiq_dir
from fliiq.runtime.ulid import generate_id
from fliiq.runtime.yaml_store import YamlStore

_PRIORITY_ORDER = {"urgent": 0, "high": 1, "medium": 2, "low": 3}


def _store() -> YamlStore:
    return YamlStore(resolve_fliiq_dir() / "tasks.yaml", "tasks")


def _now_iso() -> str:
    return datetime.now(timezone.utc).isoformat()


async def handler(params: dict) -> dict:
    action = params["action"]

    if action == "create":
        return _create(params)
    if action == "list":
        return _list(params)
    if action == "update":
        return _update(params)
    if action == "complete":
        return _complete(params)
    if action == "delete":
        return _delete(params)

    raise ValueError(f"Unknown action: {action}")


def _create(params: dict) -> dict:
    title = params.get("title")
    if not title:
        raise ValueError("title is required for create action")

    store = _store()
    items = store.load()
    now = _now_iso()

    task = {
        "id": generate_id("t"),
        "title": title,
        "status": "todo",
        "priority": params.get("priority", "medium"),
        "due": params.get("due"),
        "project": params.get("project"),
        "tags": params.get("tags", []),
        "notes": params.get("notes", ""),
        "created": now,
        "updated": now,
        "completed_at": None,
    }
    items.append(task)
    store.save(items)
    return {"success": True, "message": f"Created task: {title}", "task": task}


def _list(params: dict) -> dict:
    store = _store()
    items = store.load()

    status_filter = params.get("filter_status", "active")
    priority_filter = params.get("filter_priority")
    due_before = params.get("filter_due_before")
    project = params.get("project")
    tags = params.get("tags")

    filtered = []
    for t in items:
        if status_filter == "active":
            if t["status"] not in ("todo", "in_progress"):
                continue
        elif t["status"] != status_filter:
            continue

        if priority_filter and t.get("priority") != priority_filter:
            continue
        if due_before and t.get("due") and t["due"] > due_before:
            continue
        if project and t.get("project") != project:
            continue
        if tags and not set(tags).intersection(set(t.get("tags", []))):
            continue

        filtered.append(t)

    # Sort: urgent first, then by due date (nulls last)
    filtered.sort(key=lambda t: (
        _PRIORITY_ORDER.get(t.get("priority", "medium"), 2),
        t.get("due") or "9999-99-99",
    ))

    return {"success": True, "count": len(filtered), "tasks": filtered}


def _find_task(items: list[dict], task_id: str) -> tuple[int, dict]:
    for i, t in enumerate(items):
        if t["id"] == task_id:
            return i, t
    raise ValueError(f"Task not found: {task_id}")


def _update(params: dict) -> dict:
    task_id = params.get("task_id")
    if not task_id:
        raise ValueError("task_id is required for update action")

    store = _store()
    items = store.load()
    idx, task = _find_task(items, task_id)

    updatable = ("title", "status", "priority", "due", "project", "tags", "notes")
    for key in updatable:
        if key in params:
            task[key] = params[key]

    task["updated"] = _now_iso()
    if task.get("status") == "done" and not task.get("completed_at"):
        task["completed_at"] = _now_iso()

    items[idx] = task
    store.save(items)
    return {"success": True, "message": f"Updated task: {task['title']}", "task": task}


def _complete(params: dict) -> dict:
    task_id = params.get("task_id")
    if not task_id:
        raise ValueError("task_id is required for complete action")

    store = _store()
    items = store.load()
    idx, task = _find_task(items, task_id)

    now = _now_iso()
    task["status"] = "done"
    task["completed_at"] = now
    task["updated"] = now

    items[idx] = task
    store.save(items)
    return {"success": True, "message": f"Completed: {task['title']}", "task": task}


def _delete(params: dict) -> dict:
    task_id = params.get("task_id")
    if not task_id:
        raise ValueError("task_id is required for delete action")

    store = _store()
    items = store.load()
    _find_task(items, task_id)  # raises if not found

    items = [t for t in items if t["id"] != task_id]
    store.save(items)
    return {"success": True, "message": "Task deleted"}
