"""Data models for the ARQERA SDK."""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any


class GovernanceVerdict(str, Enum):
    """Result of a governance evaluation."""

    PROCEED = "proceed"
    ESCALATE = "escalate"
    BLOCK = "block"


class LawCheckResult(str, Enum):
    """Result of a single law check."""

    PASS = "pass"
    WARN = "warn"
    FAIL = "fail"
    SKIP = "skip"


class AraActionStatus(str, Enum):
    """Status of an Ara action."""

    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"
    EXECUTED = "executed"
    FAILED = "failed"


@dataclass
class LawEvaluation:
    """Evaluation result for a single governance law."""

    law_id: int
    law_name: str
    result: LawCheckResult
    reason: str
    details: dict[str, Any] = field(default_factory=dict)
    duration_ms: float = 0.0

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> LawEvaluation:
        return cls(
            law_id=data["law_id"],
            law_name=data["law_name"],
            result=LawCheckResult(data["result"]),
            reason=data.get("reason", ""),
            details=data.get("details", {}),
            duration_ms=data.get("duration_ms", 0.0),
        )


@dataclass
class GovernanceResult:
    """Complete governance evaluation result.

    Contains the overall verdict and per-law evaluation details.
    """

    verdict: GovernanceVerdict
    action: str
    explanation: str
    evaluations: list[LawEvaluation]
    duration_ms: float = 0.0
    evaluated_at: datetime | None = None

    @property
    def passed(self) -> bool:
        """Whether the action is allowed to proceed."""
        return self.verdict == GovernanceVerdict.PROCEED

    @property
    def blocked(self) -> bool:
        """Whether the action is blocked by governance."""
        return self.verdict == GovernanceVerdict.BLOCK

    @property
    def needs_approval(self) -> bool:
        """Whether the action requires human approval."""
        return self.verdict == GovernanceVerdict.ESCALATE

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> GovernanceResult:
        return cls(
            verdict=GovernanceVerdict(data["verdict"]),
            action=data["action"],
            explanation=data.get("explanation", ""),
            evaluations=[
                LawEvaluation.from_dict(e)
                for e in data.get("evaluations", [])
            ],
            duration_ms=data.get("duration_ms", 0.0),
            evaluated_at=data.get("evaluated_at"),
        )


@dataclass
class EvidenceArtifact:
    """An evidence artifact from the audit trail."""

    id: str
    artifact_type: str
    payload: dict[str, Any]
    tenant_id: int | None = None
    user_id: int | None = None
    created_at: datetime | None = None
    metadata: dict[str, Any] = field(default_factory=dict)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> EvidenceArtifact:
        return cls(
            id=data["id"],
            artifact_type=data["artifact_type"],
            payload=data.get("payload", {}),
            tenant_id=data.get("tenant_id"),
            user_id=data.get("user_id"),
            created_at=data.get("created_at"),
            metadata=data.get("metadata", {}),
        )


@dataclass
class AraAction:
    """An action processed by Ara."""

    id: str
    action: str
    status: AraActionStatus
    description: str | None = None
    governance_verdict: GovernanceVerdict | None = None
    result: dict[str, Any] = field(default_factory=dict)
    created_at: datetime | None = None

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> AraAction:
        verdict = data.get("governance_verdict")
        return cls(
            id=data["id"],
            action=data["action"],
            status=AraActionStatus(data["status"]),
            description=data.get("description"),
            governance_verdict=GovernanceVerdict(verdict) if verdict else None,
            result=data.get("result", {}),
            created_at=data.get("created_at"),
        )
