"""Key colors output target — extracts key colors from image rectangles."""

from dataclasses import dataclass, field
from datetime import datetime, timezone

from wled_controller.storage.output_target import OutputTarget
from wled_controller.storage.utils import resolve_ref


@dataclass
class KeyColorRectangle:
    """A named rectangle in relative coordinates (0.0 to 1.0)."""

    name: str
    x: float
    y: float
    width: float
    height: float

    def to_dict(self) -> dict:
        return {
            "name": self.name,
            "x": self.x,
            "y": self.y,
            "width": self.width,
            "height": self.height,
        }

    @classmethod
    def from_dict(cls, data: dict) -> "KeyColorRectangle":
        return cls(
            name=data["name"],
            x=float(data.get("x", 0.0)),
            y=float(data.get("y", 0.0)),
            width=float(data.get("width", 1.0)),
            height=float(data.get("height", 1.0)),
        )


@dataclass
class KeyColorsSettings:
    """Settings for key colors extraction."""

    fps: int = 10
    interpolation_mode: str = "average"
    smoothing: float = 0.3
    pattern_template_id: str = ""
    brightness: float = 1.0
    brightness_value_source_id: str = ""

    def to_dict(self) -> dict:
        return {
            "fps": self.fps,
            "interpolation_mode": self.interpolation_mode,
            "smoothing": self.smoothing,
            "pattern_template_id": self.pattern_template_id,
            "brightness": self.brightness,
            "brightness_value_source_id": self.brightness_value_source_id,
        }

    @classmethod
    def from_dict(cls, data: dict) -> "KeyColorsSettings":
        return cls(
            fps=data.get("fps", 10),
            interpolation_mode=data.get("interpolation_mode", "average"),
            smoothing=data.get("smoothing", 0.3),
            pattern_template_id=data.get("pattern_template_id", ""),
            brightness=data.get("brightness", 1.0),
            brightness_value_source_id=data.get("brightness_value_source_id", ""),
        )


@dataclass
class KeyColorsOutputTarget(OutputTarget):
    """Key colors extractor target — extracts key colors from image rectangles."""

    picture_source_id: str = ""
    settings: KeyColorsSettings = field(default_factory=KeyColorsSettings)

    def register_with_manager(self, manager) -> None:
        """Register this KC target with the processor manager."""
        manager.add_kc_target(
            target_id=self.id,
            picture_source_id=self.picture_source_id,
            settings=self.settings,
        )

    def sync_with_manager(self, manager, *, settings_changed: bool,
                          source_changed: bool = False,
                          css_changed: bool = False,
                          device_changed: bool = False,
                          brightness_vs_changed: bool = False) -> None:
        """Push changed fields to the processor manager."""
        if settings_changed:
            manager.update_target_settings(self.id, self.settings)
        if source_changed:
            manager.update_target_source(self.id, self.picture_source_id)
        if brightness_vs_changed:
            manager.update_target_brightness_vs(self.id, self.settings.brightness_value_source_id)

    def update_fields(self, *, name=None, device_id=None, picture_source_id=None,
                      settings=None, key_colors_settings=None, description=None,
                      tags=None,
                      **_kwargs) -> None:
        """Apply mutable field updates for KC targets."""
        super().update_fields(name=name, description=description, tags=tags)
        if picture_source_id is not None:
            self.picture_source_id = resolve_ref(picture_source_id, self.picture_source_id)
        if key_colors_settings is not None:
            self.settings = key_colors_settings

    @property
    def has_picture_source(self) -> bool:
        return True

    def to_dict(self) -> dict:
        d = super().to_dict()
        d["picture_source_id"] = self.picture_source_id
        d["settings"] = self.settings.to_dict()
        return d

    @classmethod
    def from_dict(cls, data: dict) -> "KeyColorsOutputTarget":
        settings_data = data.get("settings", {})
        settings = KeyColorsSettings.from_dict(settings_data)

        return cls(
            id=data["id"],
            name=data["name"],
            target_type="key_colors",
            picture_source_id=data.get("picture_source_id", ""),
            settings=settings,
            description=data.get("description"),
            tags=data.get("tags", []),
            created_at=datetime.fromisoformat(data.get("created_at", datetime.now(timezone.utc).isoformat())),
            updated_at=datetime.fromisoformat(data.get("updated_at", datetime.now(timezone.utc).isoformat())),
        )
