# standard
from pathlib import Path
from typing import Optional

# third party
import typer

# custom
from sunwaee.modules.tasks.model import Task, TaskPriority, TaskStatus
from sunwaee.config import get_default_workspace
from sunwaee.core.audit import append_log
from sunwaee.core.fs import list_md
from sunwaee.core.output import console, success
from ._helpers import _enrich, _load, _resolve_dirs


def list_tasks(
    status: Optional[TaskStatus] = typer.Option(None, "--status", "-s"),
    priority: Optional[TaskPriority] = typer.Option(None, "--priority", "-p"),
    tags: Optional[str] = typer.Option(
        None, "--tags", help="Filter by tag (comma-separated)"
    ),
    query: Optional[str] = typer.Option(
        None, "--query", "-q", help="Search term (matches title, tags, body)"
    ),
    workspace: Optional[str] = typer.Option(
        None, "--workspace", "-w", help="Workspace (default: all workspaces)"
    ),
) -> None:
    """List tasks as a tab-separated table."""
    dirs = _resolve_dirs(workspace)

    triples: list[tuple[Task, Path, str]] = []
    for ws, directory in dirs:
        for p in list_md(directory):
            triples.append((_load(p), p, ws))

    if status:
        triples = [(t, p, w) for t, p, w in triples if t.status == status]
    if priority:
        triples = [(t, p, w) for t, p, w in triples if t.priority == priority]
    if tags:
        filter_tags = {t.strip().lower() for t in tags.split(",")}
        triples = [
            (t, p, w)
            for t, p, w in triples
            if any(tag.lower() in filter_tags for tag in t.tags)
        ]
    if query:
        q = query.lower()
        triples = [
            (t, p, w)
            for t, p, w in triples
            if q in t.title.lower()
            or q in t.body.lower()
            or any(q in tag.lower() for tag in t.tags)
        ]

    result = [_enrich(t, w, p) for t, p, w in triples]

    _log_args: dict = {"results": len(triples)}
    if status:
        _log_args["status"] = status.value
    if priority:
        _log_args["priority"] = priority.value
    if tags:
        _log_args["tags"] = tags
    if query:
        _log_args["query"] = query
    append_log(workspace or get_default_workspace(), "tasks", "list", args=_log_args)

    def human_output() -> None:  # pragma: no cover
        from datetime import date

        today = date.today().isoformat()

        _STATUS_COLOR = {"todo": "white", "in_progress": "cyan", "done": "green"}
        _PRIORITY_COLOR = {"high": "red", "medium": "yellow", "low": "dim"}

        def _due_color(due: str) -> str:
            if due == today:
                return "orange1"
            return "red" if due < today else "green"

        header = ("ID", "TITLE", "STATUS", "PRIORITY", "DUE", "TAGS", "PATH")

        home = str(Path.home())

        def _short(p: Path) -> str:
            s = str(p)
            return "~" + s[len(home):] if s.startswith(home) else s

        plain = [
            (t.id, t.title, t.status.value, t.priority.value, t.due_date or "", ",".join(t.tags), _short(p))
            for t, p, _ in triples
        ]
        widths = [max(len(r[i]) for r in [header, *plain]) for i in range(len(header) - 1)]

        console.print("  ".join(f"[bold]{h.ljust(w)}[/bold]" for h, w in zip(header[:-1], widths)) + f"  [bold]{header[-1]}[/bold]")

        for row, (t, p, _) in zip(plain, triples):
            due_plain = row[4]
            colored = (
                row[0],
                row[1],
                f"[{_STATUS_COLOR[t.status.value]}]{row[2]}[/{_STATUS_COLOR[t.status.value]}]",
                f"[{_PRIORITY_COLOR[t.priority.value]}]{row[3]}[/{_PRIORITY_COLOR[t.priority.value]}]",
                f"[{_due_color(due_plain)}]{due_plain}[/{_due_color(due_plain)}]" if due_plain else "",
                row[5],
            )
            padded = "  ".join(c + " " * (w - len(pl)) for c, pl, w in zip(colored, row[:-1], widths))
            console.print(f"{padded}  {row[-1]}")

    success(result, human_fn=human_output)
