"""EmotionScanner and EmotionLabel enum for meshulash-guard SDK.

EmotionScanner detects and acts on text categorized by emotional tone using
the server's 'emotion' TC classification head. Label values are the exact
strings from the server's label_config.json (case-sensitive, mixed casing).
"""

from __future__ import annotations

from typing import Sequence

from ..enums import Action, Condition, _StrValueMixin
from .base import BaseScanner


class EmotionLabel(_StrValueMixin):
    """Labels for emotion detection.

    Values are the exact strings used by the server's 'emotion' TC head.
    Member names are uppercase/underscored for Python ergonomics.
    Note: server uses mixed casing — some labels are Title Case, others lowercase.
    """

    ANGER = "Anger"
    CARING = "Caring"
    FEAR = "Fear"
    GRATITUDE = "Gratitude"
    JOY = "Joy"
    LOVE = "Love"
    NEUTRAL = "Neutral"
    OPTIMISM = "Optimism"
    REALIZATION = "Realization"
    SADNESS = "Sadness"
    SURPRISE = "Surprise"
    ADMIRATION = "admiration"
    AMUSEMENT = "amusement"
    ANNOYANCE = "annoyance"
    APPROVAL = "approval"
    CONFUSION = "confusion"
    CURIOSITY = "curiosity"
    DESIRE = "desire"
    DISAPPOINTMENT = "disappointment"
    DISAPPROVAL = "disapproval"
    DISGUST = "disgust"
    EMBARRASSMENT = "embarrassment"
    EXCITEMENT = "excitement"
    EXPECTATION = "expectation"
    GRIEF = "grief"
    NERVOUSNESS = "nervousness"
    PRIDE = "pride"
    RELIEF = "relief"
    REMORSE = "remorse"
    TRUST = "trust"
    ALL = "__ALL__"


class EmotionScanner(BaseScanner):
    """Scanner for emotion detection.

    Detects text expressing specific emotional states using the server's
    'emotion' TC classification head. Supports 30 emotion labels covering
    a wide range of primary and complex emotions.

    Args:
        labels: One or more EmotionLabel members. Use EmotionLabel.ALL to
            scan all emotion categories. Cannot be empty.
        action: Action to take when the emotion is detected. Defaults to BLOCK.
        condition: Gating condition (ANY, ALL, K_OF, CONTEXTUAL).
        threshold: Optional confidence threshold (0.0–1.0).
        allowlist: Optional list of values to allow through even if detected.
    """

    _TC_HEAD = "emotion"

    def __init__(
        self,
        labels: Sequence[EmotionLabel],
        action: Action = Action.BLOCK,
        condition: Condition = Condition.ANY,
        threshold: float | None = None,
        allowlist: list[str] | None = None,
    ) -> None:
        if not labels:
            raise ValueError(
                "EmotionScanner requires at least one label. "
                "Use EmotionLabel.ALL to scan everything."
            )
        self._labels = list(labels)
        self._action = action
        self._condition = condition
        self._threshold = threshold
        self._allowlist = allowlist or []

    def to_guardline_spec(self) -> dict:
        """Return a guardline spec dict for this scanner configuration."""
        if any(lbl.value == "__ALL__" for lbl in self._labels):
            all_labels = [m for m in type(self._labels[0]) if m.value != "__ALL__"]
        else:
            all_labels = self._labels
        tc_pairs = [[self._TC_HEAD, lbl.value] for lbl in all_labels]
        spec: dict = {
            "name": self.__class__.__name__,
            "condition": str(self._condition),
            "action": str(self._action),
            "level": 2,
            "types": {"regex": False, "ner": False, "tc": True},
            "required": {"regex": [], "ner": [], "tc": tc_pairs},
            "allowlist": list(self._allowlist),
            "bundles": [],
            "k": 0,
        }
        if self._threshold is not None:
            spec["threshold"] = self._threshold
        return spec
