"""Gradient data model.

A Gradient defines a reusable color gradient as a list of color stops.
Gradients are referenced by ID from effect, gradient, and audio color
strip sources.  Eight built-in gradients are seeded on first run.
"""

from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Optional


@dataclass
class Gradient:
    """Persistent gradient definition with color stops."""

    id: str
    name: str
    stops: list  # [{"position": float, "color": [R, G, B]}, ...]
    is_builtin: bool
    created_at: datetime
    updated_at: datetime
    description: Optional[str] = None
    tags: List[str] = field(default_factory=list)

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "name": self.name,
            "stops": self.stops,
            "is_builtin": self.is_builtin,
            "description": self.description,
            "tags": self.tags,
            "created_at": self.created_at.isoformat(),
            "updated_at": self.updated_at.isoformat(),
        }

    @staticmethod
    def from_dict(data: dict) -> "Gradient":
        return Gradient(
            id=data["id"],
            name=data["name"],
            stops=data.get("stops", []),
            is_builtin=data.get("is_builtin", False),
            description=data.get("description"),
            tags=data.get("tags", []),
            created_at=datetime.fromisoformat(data["created_at"]),
            updated_at=datetime.fromisoformat(data["updated_at"]),
        )

    @classmethod
    def create_from_kwargs(
        cls,
        *,
        id: str,
        name: str,
        stops: list,
        is_builtin: bool = False,
        created_at: datetime,
        updated_at: datetime,
        description: Optional[str] = None,
        tags: Optional[List[str]] = None,
    ) -> "Gradient":
        return cls(
            id=id,
            name=name,
            stops=stops,
            is_builtin=is_builtin,
            created_at=created_at,
            updated_at=updated_at,
            description=description,
            tags=tags or [],
        )

    def apply_update(self, **kwargs) -> None:
        if kwargs.get("name") is not None:
            self.name = kwargs["name"]
        if kwargs.get("stops") is not None:
            self.stops = kwargs["stops"]
        if kwargs.get("description") is not None:
            self.description = kwargs["description"]
        if kwargs.get("tags") is not None:
            self.tags = kwargs["tags"]
