"""Data models for Ghostty Settings TUI."""

from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Optional


class OptionType(Enum):
    """Types of configuration options."""
    BOOLEAN = "boolean"
    STRING = "string"
    INTEGER = "integer"
    FLOAT = "float"
    COLOR = "color"
    ENUM = "enum"
    PATH = "path"
    KEYBIND = "keybind"


@dataclass(frozen=True)
class OptionDefinition:
    """Immutable schema definition for a Ghostty option."""
    name: str
    option_type: OptionType
    default_value: Optional[str]
    description: str
    category: str
    enum_values: tuple[str, ...] = field(default_factory=tuple)
    is_deprecated: bool = False

    def __hash__(self) -> int:
        return hash(self.name)


@dataclass
class ConfigValue:
    """Mutable current value for an option."""
    name: str
    value: Optional[str] = None
    line_number: Optional[int] = None
    comment: Optional[str] = None
    is_modified: bool = False
    is_commented_out: bool = False

    def reset(self) -> None:
        """Reset modification state."""
        self.is_modified = False


@dataclass
class OptionModel:
    """Combined model for UI rendering - links definition with current value."""
    definition: OptionDefinition
    current: ConfigValue

    @property
    def display_value(self) -> str:
        """Get the value to display (current or default)."""
        if self.current.value is not None:
            return self.current.value
        return self.definition.default_value or ""

    @property
    def is_default(self) -> bool:
        """Check if current value matches default."""
        if self.current.value is None:
            return True
        return self.current.value == self.definition.default_value

    @property
    def is_modified(self) -> bool:
        """Check if value has been modified in this session."""
        return self.current.is_modified


@dataclass
class AppState:
    """Application state container."""
    schema: dict[str, OptionDefinition] = field(default_factory=dict)
    values: dict[str, ConfigValue] = field(default_factory=dict)
    current_category: str = ""
    search_query: str = ""
    config_mtime: float = 0.0

    @property
    def modified_options(self) -> set[str]:
        """Get names of all modified options."""
        return {name for name, val in self.values.items() if val.is_modified}

    @property
    def has_unsaved_changes(self) -> bool:
        """Check if there are unsaved modifications."""
        return len(self.modified_options) > 0
