from __future__ import annotations

import re
from typing import Any


SETTINGS_KEY = "layer_studio_color_favorites"
SLOT_COUNT = 5
_HEX_COLOR_RE = re.compile(r"^[0-9a-fA-F]{6}$")


def normalize_color(value: Any) -> str | None:
    if value is None:
        return None
    text = str(value).strip()
    if text.startswith("#"):
        text = text[1:]
    if not _HEX_COLOR_RE.fullmatch(text):
        return None
    return f"#{text.upper()}"


def load_favorites(settings: dict[str, Any] | None) -> list[str | None]:
    raw = settings.get(SETTINGS_KEY, []) if isinstance(settings, dict) else []
    values = raw if isinstance(raw, list) else []
    favorites: list[str | None] = []
    seen: set[str] = set()
    for value in values[:SLOT_COUNT]:
        color = normalize_color(value)
        if color and color in seen:
            color = None
        if color:
            seen.add(color)
        favorites.append(color)
    favorites.extend([None] * (SLOT_COUNT - len(favorites)))
    return favorites


def update_settings(settings: dict[str, Any] | None, values: Any) -> tuple[dict[str, Any], list[str | None]]:
    if not isinstance(values, list):
        raise ValueError("Layer Studio favorite colors must be a list")
    if len(values) > SLOT_COUNT:
        raise ValueError(f"Layer Studio supports at most {SLOT_COUNT} favorite colors")

    favorites: list[str | None] = []
    seen: set[str] = set()
    for index, value in enumerate(values):
        if value is None or not str(value).strip():
            favorites.append(None)
            continue
        color = normalize_color(value)
        if not color:
            raise ValueError(f"Favorite color slot {index + 1} must use #RRGGBB")
        if color in seen:
            raise ValueError(f"Favorite color {color} is already saved")
        seen.add(color)
        favorites.append(color)
    favorites.extend([None] * (SLOT_COUNT - len(favorites)))

    updated = dict(settings) if isinstance(settings, dict) else {}
    updated[SETTINGS_KEY] = favorites
    return updated, favorites
