from dataclasses import dataclass, asdict
from datetime import datetime
from typing import Any, Dict, List
import uuid


SEVERITY_LEVELS = ("info", "warning", "error")


@dataclass(frozen=True)
class Decision:
    id: str
    category: str
    component: str
    action: str
    reason: str
    parameters: Dict[str, Any]
    impact: str
    severity: str
    timestamp: str
    reproducible: bool

    @staticmethod
    def create(
        category: str,
        component: str,
        action: str,
        reason: str,
        parameters: Dict[str, Any],
        impact: str,
        severity: str = "info",
        reproducible: bool = True,
    ) -> "Decision":
        if severity not in SEVERITY_LEVELS:
            raise ValueError(f"Invalid severity level: {severity}")

        return Decision(
            id=str(uuid.uuid4()),
            category=category,
            component=component,
            action=action,
            reason=reason,
            parameters=parameters,
            impact=impact,
            severity=severity,
            timestamp=datetime.utcnow().isoformat(),
            reproducible=reproducible,
        )

    def to_dict(self) -> Dict[str, Any]:
        return asdict(self)


class DecisionLog:
    def __init__(self) -> None:
        self._decisions: List[Decision] = []

    def add(self, decision: Decision) -> None:
        self._decisions.append(decision)

    def all(self) -> List[Decision]:
        return list(self._decisions)

    def by_severity(self, severity: str) -> List[Decision]:
        return [d for d in self._decisions if d.severity == severity]

    def has_errors(self) -> bool:
        return any(d.severity == "error" for d in self._decisions)

    def to_dict(self) -> List[Dict[str, Any]]:
        return [d.to_dict() for d in self._decisions]
