"""Core data models for cheatly - pure data structures."""

from dataclasses import dataclass, field
from typing import Literal

from .config import Config


@dataclass
class SheetStyle:
    """Styling configuration for sheets.

    Defines colors for different panel elements to create
    tool-specific visual identities.
    """

    border_color: str = "cyan"
    title_color: str = "bright_white"
    key_color: str = "bright_cyan"
    desc_color: str = "white"


@dataclass
class PanelSpec:
    """Specification for a panel - content only, dimensions from Config."""

    title: str
    size: Literal["full", "half"] = "full"
    base: str | None = None
    items: list[dict[str, str]] = field(default_factory=list)

    @property
    def max_items(self) -> int:
        """Maximum items this panel can hold - from Config.LAYOUT."""
        layout = Config.LAYOUT
        return (
            layout.half_panel_items if self.size == "half" else layout.full_panel_items
        )

    @property
    def height(self) -> int:
        """Panel height in terminal lines - from Config.LAYOUT."""
        layout = Config.LAYOUT
        return (
            layout.half_panel_height
            if self.size == "half"
            else layout.full_panel_height
        )

    @property
    def uses_multiline_layout(self) -> bool:
        """Check if this panel uses multi-line layout (cmd/desc format)."""
        return any("cmd" in item for item in self.items if isinstance(item, dict))

    @property
    def effective_max_items(self) -> int:
        """Get max items accounting for multi-line layout.

        For cmd/desc layout, each item takes 2 lines, so we can fit half as many.
        """
        base_max = self.max_items
        if self.uses_multiline_layout:
            return base_max // 2
        return base_max


@dataclass
class CodeSection:
    """A code example section for code mode sheets.

    Attributes:
        name: Section identifier (from @section:)
        title: Display title (from @title: or defaults to name)
        code: The actual code content
        size: Size category for the section
        language: Language for syntax highlighting
    """

    name: str
    title: str
    code: str
    size: Literal["small", "medium", "large"] = "medium"
    language: str | None = None

    def __post_init__(self) -> None:
        """Validate and normalize fields after initialization.

        Validates that the size field contains a valid value from the allowed
        options ('small', 'medium', 'large'). If an invalid size is provided,
        it defaults to 'medium' to ensure consistent behavior.

        Raises:
            None: Validation errors are handled by defaulting to valid values.
        """
        if self.size not in ("small", "medium", "large"):
            self.size = "medium"

    @property
    def line_count(self) -> int:
        """Number of lines in the code."""
        return len(self.code.splitlines())


@dataclass
class Sheet:
    """A sheet with its panels or code sections."""

    name: str
    mode: Literal["reference", "code"] = "reference"
    sections: list[PanelSpec | CodeSection] = field(default_factory=list)
    language: str | None = None
    style: SheetStyle = field(default_factory=SheetStyle)

    def __post_init__(self) -> None:
        """Validate and normalize fields after initialization.

        Validates that the mode field contains a valid value from the allowed
        options ('reference', 'code'). If an invalid mode is provided,
        it defaults to 'reference' to ensure the sheet can be processed.

        Raises:
            None: Validation errors are handled by defaulting to valid values.
        """
        if self.mode not in ("reference", "code"):
            self.mode = "reference"


@dataclass
class Context:
    """Detected context from environment.

    Attributes:
        name: Context name (e.g., 'tmux', 'python')
        type: Category (tool, editor, language, etc.)
        priority: Layer priority (0 = outermost like tmux, higher = inner)
        sheet: Sheet to load (defaults to name if None)
        metadata: Additional context-specific data
    """

    name: str
    type: str
    priority: int
    sheet: str | None = None
    metadata: dict = field(default_factory=dict)

    def __str__(self) -> str:
        return self.name


@dataclass
class ValidationResult:
    """Result of validating a sheet section."""

    file: str
    section: str
    max_width: int
    line_count: int
    valid: bool
    message: str | None = None
