"""Overlay constraints for visual-first final videos."""

from __future__ import annotations

from collections import Counter
from dataclasses import dataclass
from enum import Enum
from typing import Sequence


class OverlayKind(str, Enum):
    CAPTION = "caption"
    LABEL = "label"
    STAMP = "stamp"
    TAKEAWAY = "takeaway"
    TEXTBOX = "textbox"
    PREVIEW_FRAME = "preview_frame"
    DEBUG_BAR = "debug_bar"
    UI_CARD = "ui_card"
    DOCUMENT_TEXT = "document_text"


@dataclass(frozen=True)
class OverlayElement:
    kind: OverlayKind
    scene_id: str
    screen_area_ratio: float


@dataclass(frozen=True)
class FinalOverlayPolicy:
    max_labels_per_scene: int = 1
    max_caption_area_ratio: float = 0.33
    max_textbox_area_ratio: float = 0.35
    max_ui_card_area_ratio: float = 0.35
    forbidden_kinds: tuple[OverlayKind, ...] = (OverlayKind.PREVIEW_FRAME, OverlayKind.DEBUG_BAR, OverlayKind.DOCUMENT_TEXT)

    @classmethod
    def default(cls) -> "FinalOverlayPolicy":
        return cls()


@dataclass(frozen=True)
class OverlayPolicyResult:
    allowed: bool
    reason: str
    violations: tuple[str, ...]


def evaluate_final_overlay_policy(
    elements: Sequence[OverlayElement], *, policy: FinalOverlayPolicy | None = None
) -> OverlayPolicyResult:
    policy = policy or FinalOverlayPolicy.default()
    violations: list[str] = []
    label_counts: Counter[str] = Counter()

    for element in elements:
        if element.kind in policy.forbidden_kinds:
            violations.append(f"forbidden overlay kind: {element.kind.value}")
        if element.kind in (OverlayKind.LABEL, OverlayKind.STAMP):
            label_counts[element.scene_id] += 1
        if element.kind is OverlayKind.CAPTION and element.screen_area_ratio > policy.max_caption_area_ratio:
            violations.append(f"caption area exceeds lower-third limit in {element.scene_id}")
        if element.kind is OverlayKind.TEXTBOX and element.screen_area_ratio > policy.max_textbox_area_ratio:
            violations.append(f"large textbox exceeds 35% screen in {element.scene_id}")
        if element.kind is OverlayKind.UI_CARD and element.screen_area_ratio > policy.max_ui_card_area_ratio:
            violations.append(f"large ui card exceeds 35% screen in {element.scene_id}")

    for scene_id, count in label_counts.items():
        if count > policy.max_labels_per_scene:
            violations.append(f"too many labels in {scene_id}: {count}")

    if violations:
        return OverlayPolicyResult(False, "overlay_overload", tuple(violations))
    return OverlayPolicyResult(True, "final_overlay_policy_valid", ())
