from enum import Enum
from typing import Any, Literal, Optional

from pydantic import BaseModel, Field

from ..typings import PydanticModelConfig


class AgenticActionWarningLevel(str, Enum):
    SAFE = "SAFE"
    MUTATION = "MUTATION"
    DESTRUCTION = "DESTRUCTION"


class AgenticActionPayload(BaseModel):
    model_config = PydanticModelConfig.default()
    message: str = Field(
        description="A simple, human-friendly message explaining why you want to do this action (used for confirmation). Don’t include IDs, keys, or technical terms due to most user may be complete out-of-context and non-developer."
    )
    warning_level: AgenticActionWarningLevel = Field(
        description="The level of warning associated with the action; When no data mutation/or descruction is involved, use SAFE; otherwise, use MUTATION or DESTRUCTION accordingly"
    )
    object: Literal["agentic_action_payload"] = Field(
        default="agentic_action_payload",
        description="A string representing the object type.",
    )

    @classmethod
    def extract_agentic_action_payload(
        cls, args: Any
    ) -> Optional["AgenticActionPayload"]:
        def _normalize_candidate(candidate: Any) -> dict[str, Any] | None:
            if not isinstance(candidate, dict):
                return None
            if (
                "object" not in candidate
                or candidate["object"] != "agentic_action_payload"
            ):  # a literal string name in the dict, to identify the object type
                return None
            if "message" not in candidate:
                raise ValueError("agentic_action_payload missing 'message' field")
            if "warning_level" in candidate:
                warning_level = candidate["warning_level"]
            elif "warningLevel" in candidate:
                warning_level = candidate["warningLevel"]
            else:
                raise ValueError(
                    "agentic_action_payload missing 'warning_level'/'warningLevel' field"
                )
            return {"message": candidate["message"], "warning_level": warning_level}

        def _find_candidate(value: Any) -> dict[str, Any] | None:
            normalized = _normalize_candidate(value)
            if normalized is not None:
                return normalized
            if isinstance(value, dict):
                for v in value.values():
                    found = _find_candidate(v)
                    if found is not None:
                        return found
            elif isinstance(value, list):
                for v in value:
                    found = _find_candidate(v)
                    if found is not None:
                        return found
            return None

        candidate = _find_candidate(args)
        if candidate is None:
            return None
        return AgenticActionPayload(**candidate)
