"""Thin local-state schemas for tasks, lanes, lessons, investigations, artifacts.

Why types here: existing markdown state files (NEXT.md, FRONTIER.md,
SWARM-LANES.md, lesson notes) rely on convention-only structure. A typed
schema makes the contracts explicit and machine-checkable without changing
the markdown surface.

Why thin: each entity holds only fields needed for ordering, tracking,
and handoff. Cross-references point to other entities by id rather than
duplicating their state. No global state — every record is self-contained.
"""

from dataclasses import dataclass, field
from datetime import date
from enum import Enum
from typing import Literal, Optional


class Rating(str, Enum):
    """Current-state quality. Drives priority. See docs/RATING-AND-PRIORITY.md."""

    BAD = "bad"          # broken / urgent / blocker — do first
    MEDIUM = "medium"    # works but should be better — do next
    GOOD = "good"        # works fine — do later (or never)


class TaskStatus(str, Enum):
    OPEN = "open"
    IN_PROGRESS = "in-progress"
    BLOCKED = "blocked"
    DONE = "done"
    ABANDONED = "abandoned"


ArtifactKind = Literal["input", "build", "result", "diff"]


@dataclass
class Artifact:
    """One trackable input / build / result / diff with a date.

    `ref` is whatever points back to the artifact: a file path, commit
    hash, URL, signal id, lane id. `kind` lets the four columns be
    rendered separately (inputs ▸ builds ▸ results ▸ diffs).
    """

    kind: ArtifactKind
    ref: str
    when: date
    note: str = ""


@dataclass
class Task:
    """Thin task: rating drives priority, links drive context.

    Stored as one entry in tasks/TODO.md. Numeric IDs (T-001 ...) are
    monotonic; reuse on delete is forbidden.
    """

    id: str
    title: str
    rating: Rating
    status: TaskStatus
    created: date
    due: Optional[date] = None
    parents: list[str] = field(default_factory=list)
    children: list[str] = field(default_factory=list)
    artifacts: list[Artifact] = field(default_factory=list)
    refs: list[str] = field(default_factory=list)
    notes: str = ""

    def priority_key(self) -> tuple[int, date, date]:
        """Lower is higher priority: (rating_rank, due, created)."""
        rank = {Rating.BAD: 0, Rating.MEDIUM: 1, Rating.GOOD: 2}[self.rating]
        return (rank, self.due or date.max, self.created)


@dataclass
class Investigation:
    """An expandable knowledge page (Wikipedia-style, compress/decompress).

    `levels` maps level keys to body text:
      L0 — TL;DR, ≤5 lines, single paragraph
      L1 — Overview, ≤200 lines, includes mermaid map
      L2 — Deep dive, unbounded, sub-sections
    Adding L3+ is allowed; readers expand until satisfied.
    """

    id: str
    title: str
    rating: Rating
    levels: dict[str, str]
    refs: list[str] = field(default_factory=list)
    inspiration: list[str] = field(default_factory=list)
    mermaid: Optional[str] = None
    open_questions: list[str] = field(default_factory=list)


def order_tasks(tasks: list[Task]) -> list[Task]:
    """Canonical ordering: rating (bad→good), then due date, then created."""
    return sorted(tasks, key=lambda t: t.priority_key())
