"""Data models for ddcutil monitor control. Pure, no GTK."""

from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum


class ValueType(Enum):
    """VCP feature value type as reported by ddcutil."""

    CONTINUOUS = "C"
    SIMPLE_NC = "SNC"
    COMPLEX_NC = "CNC"
    NON_CONT = "NC"
    TABLE = "T"
    UNKNOWN = "?"


class Access(Enum):
    """VCP feature access mode."""

    READ_WRITE = "RW"
    READ_ONLY = "RO"
    WRITE_ONLY = "WO"
    UNKNOWN = "?"


@dataclass(frozen=True)
class Display:
    """A detected monitor."""

    number: int
    bus: int | None
    drm_connector: str
    mfg: str
    model: str
    serial: str
    vcp_version: str = ""

    @property
    def name(self) -> str:
        """Human-readable monitor name (model, else connector, else number)."""
        return self.model or self.drm_connector or f"Display {self.number}"

    @property
    def label(self) -> str:
        return f"{self.number}  ·  {self.name}"

    @property
    def monitor_id(self) -> str:
        return f"{self.mfg}:{self.model}:{self.serial}"


@dataclass
class FeatureCaps:
    """Monitor-specific capability for one feature, from `ddcutil capabilities`."""

    code: int
    name: str
    values: dict[int, str] = field(default_factory=dict)


@dataclass
class FeatureMeta:
    """Static MCCS metadata for one feature, from `ddcutil vcpinfo`."""

    code: int
    name: str
    access: Access
    vtype: ValueType
    values: dict[int, str] = field(default_factory=dict)


@dataclass
class FeatureValue:
    """Current value of one feature, from `ddcutil getvcp --terse`."""

    code: int
    vtype: ValueType
    supported: bool = True
    current: int | None = None
    maximum: int | None = None
    raw: str = ""


@dataclass
class Feature:
    """Composite feature: capability + metadata + current value, consumed by UI."""

    code: int
    name: str
    access: Access
    vtype: ValueType
    values: dict[int, str]
    value: FeatureValue | None = None

    @property
    def code_hex(self) -> str:
        return f"{self.code:02X}"

    @property
    def is_editable(self) -> bool:
        return self.access in (Access.READ_WRITE, Access.WRITE_ONLY)
