"""View data models — presentation-separated data layer.

These dataclasses represent pure data for each view. No DB imports,
no Textual imports — just data structures. This enables:
- Testing views without database
- Future --plain mode without refactoring
- Clear separation between data and presentation

The data layer (queries.py) produces these structures.
The widget layer consumes them for rendering.
"""

from __future__ import annotations

from dataclasses import dataclass, field


@dataclass(frozen=True)
class HeaderData:
    """Data for the investigation header widget.

    Attributes:
        campaign_name: Name/identifier of the campaign.
        repo_name: Name of the repository being investigated.
        theme_name: Display name of the active theme.
        completed: Number of completed missions.
        total: Total number of missions.
        available: Number of available (unlocked, not started) missions.
    """

    campaign_name: str
    repo_name: str
    theme_name: str
    completed: int
    total: int
    available: int


@dataclass(frozen=True)
class CommandInfo:
    """Information about a single command.

    Attributes:
        canonical: The canonical command name (e.g., "next").
        alias: The themed alias (e.g., "investigate").
        description: Brief description of what the command does.
    """

    canonical: str
    alias: str
    description: str


@dataclass(frozen=True)
class FileRefData:
    """Data for a mission file reference.

    Attributes:
        file_path: Path to the file, relative to repo root.
        line_start: Starting line number, or None for whole-file reference.
        line_end: Ending line number, or None for whole-file reference.
        description: Context about why this file is relevant.
    """

    file_path: str
    line_start: int | None
    line_end: int | None
    description: str


@dataclass(frozen=True)
class MissionSummary:
    """Summary data for a mission in a list view.

    Attributes:
        id: Mission database ID.
        title: Themed mission title (may include narrative elements).
        title_plain: Plain-text version for search/sorting.
        category: Investigation category name.
        difficulty: Difficulty tier name.
        time_minutes: Estimated time to complete.
        status: Current status (available, locked, completed, in_progress).
        security_tag: Whether this mission relates to security concerns.
    """

    id: int
    title: str
    title_plain: str
    category: str
    difficulty: str
    time_minutes: int
    status: str
    security_tag: bool


@dataclass(frozen=True)
class MissionDetail:
    """Detailed data for a single mission view.

    Attributes:
        id: Mission database ID.
        title: Themed mission title.
        title_plain: Plain-text version for search/sorting.
        description: Detailed instructions for completing the mission.
        category: Investigation category name.
        difficulty: Difficulty tier name.
        time_minutes: Estimated time to complete.
        status: Current status.
        completion_condition: Clear criteria for mission completion.
        security_tag: Whether this mission relates to security concerns.
        narrative_intro: Optional themed introduction text.
        narrative_outro: Optional themed completion text.
        file_refs: List of file references for this mission.
        prerequisites: Titles of prerequisite missions.
    """

    id: int
    title: str
    title_plain: str
    description: str
    category: str
    difficulty: str
    time_minutes: int
    status: str
    completion_condition: str
    security_tag: bool
    narrative_intro: str
    narrative_outro: str
    file_refs: list[FileRefData] = field(default_factory=list)
    prerequisites: list[str] = field(default_factory=list)


@dataclass(frozen=True)
class CategoryProgressData:
    """Progress statistics for a single investigation category.

    Attributes:
        name: Category enum value (e.g., "architecture").
        display_name: Human-readable category name.
        completed: Number of completed missions.
        total: Total missions in this category.
        available: Number ready to start.
        locked: Number with unmet prerequisites.
        percent: Completion percentage (0-100).
    """

    name: str
    display_name: str
    completed: int
    total: int
    available: int
    locked: int
    percent: int


@dataclass(frozen=True)
class ChainSummary:
    """Summary data for a mission chain.

    Attributes:
        name: Themed chain name (may include narrative elements).
        name_plain: Plain-text version for search/sorting.
        category: Primary investigation category for the chain.
        mission_count: Total missions in the chain.
        completed_count: Number of completed missions in the chain.
    """

    name: str
    name_plain: str
    category: str
    mission_count: int
    completed_count: int


@dataclass(frozen=True)
class StatusData:
    """Data for the case board (status) view.

    Attributes:
        campaign_name: Name of the campaign.
        overall_percent: Overall completion percentage (0-100).
        completed: Total completed missions.
        total: Total missions.
        available: Missions ready to start.
        locked: Missions with unmet prerequisites.
        in_progress: Missions currently in progress.
        security_total: Total security-tagged missions.
        security_completed: Completed security missions.
        categories: Progress for each category.
        chains: Summary of all chains.
    """

    campaign_name: str
    overall_percent: int
    completed: int
    total: int
    available: int
    locked: int
    in_progress: int
    security_total: int
    security_completed: int
    categories: list[CategoryProgressData] = field(default_factory=list)
    chains: list[ChainSummary] = field(default_factory=list)


@dataclass(frozen=True)
class BriefingData:
    """Data for the briefing (case file) view.

    Attributes:
        summary: LLM-generated codebase summary.
        tech_stack: List of technologies used.
        security_posture: Security assessment from LLM.
    """

    summary: str
    tech_stack: list[str] = field(default_factory=list)
    security_posture: str = ""


@dataclass(frozen=True)
class CompletionData:
    """Data shown after completing a mission.

    Attributes:
        mission_title: Title of the completed mission.
        narrative_outro: Themed completion text.
        unlocked_titles: Titles of newly unlocked missions.
        new_available: Count of newly available missions.
        total_completed: Total missions completed so far.
        total_missions: Total missions in campaign.
    """

    mission_title: str
    narrative_outro: str
    unlocked_titles: list[str] = field(default_factory=list)
    new_available: int = 0
    total_completed: int = 0
    total_missions: int = 0


# --- Category Display Names ---

CATEGORY_DISPLAY_NAMES: dict[str, str] = {
    "architecture": "Architecture",
    "domain_business_logic": "Domain & Business Logic",
    "data_flow": "Data Flow",
    "dependencies": "Dependencies",
    "conventions": "Conventions",
    "testing": "Testing",
    "technical_debt": "Technical Debt",
}


def get_category_display_name(category: str) -> str:
    """Get the human-readable display name for a category.

    Args:
        category: Category enum value (e.g., "domain_business_logic").

    Returns:
        Human-readable name (e.g., "Domain & Business Logic").
    """
    return CATEGORY_DISPLAY_NAMES.get(category, category.replace("_", " ").title())


__all__ = [
    "HeaderData",
    "CommandInfo",
    "FileRefData",
    "MissionSummary",
    "MissionDetail",
    "CategoryProgressData",
    "ChainSummary",
    "StatusData",
    "BriefingData",
    "CompletionData",
    "CATEGORY_DISPLAY_NAMES",
    "get_category_display_name",
]
