"""
Pydantic schemas for Compliance Template Rules — profilbasierte Empfehlungs-Regeln
mit Versionierung, Approval-Workflow und Tenant-Overrides.
"""

from datetime import datetime
from typing import Any, Optional

from pydantic import BaseModel, Field


# ----- Bedingungs-Strukturen -----

class RuleClause(BaseModel):
    """Eine einzelne Klausel innerhalb einer Bedingung."""
    field: str
    op: str  # "eq" | "neq" | "gte" | "lte" | "gt" | "lt" | "in" | "not_in" | "exists"
    value: Any = None


class RuleCondition(BaseModel):
    """Strukturierte Bedingung — kombiniert mehrere Klauseln per AND ('all') oder OR ('any')."""
    kind: str = "all"  # "all" oder "any"
    clauses: list[RuleClause] = Field(default_factory=list)


# ----- Rule (Hülle) -----

class RuleCreate(BaseModel):
    rule_key: str
    document_type: str
    title: str


class RuleResponse(BaseModel):
    id: str
    rule_key: str
    document_type: str
    title: str
    current_version_id: Optional[str]
    created_at: datetime
    updated_at: Optional[datetime]


# ----- Version -----

class RuleVersionCreate(BaseModel):
    """Neuer Draft (entweder ganz neu oder fork einer Live-Version)."""
    rule_id: str
    classification: str  # required | recommended | optional
    conditions: RuleCondition
    source_citation: str
    rationale: Optional[str] = None
    created_by: Optional[str] = None


class RuleVersionUpdate(BaseModel):
    """Edit eines Drafts — nur erlaubt während status='draft'."""
    classification: Optional[str] = None
    conditions: Optional[RuleCondition] = None
    source_citation: Optional[str] = None
    rationale: Optional[str] = None
    change_summary: Optional[str] = None


class RuleVersionResponse(BaseModel):
    id: str
    rule_id: str
    version_number: int
    status: str
    is_live: bool
    classification: str
    conditions: dict[str, Any]
    source_citation: str
    rationale: Optional[str]
    change_summary: Optional[str]
    created_by: Optional[str]
    submitted_by: Optional[str]
    submitted_at: Optional[datetime]
    approved_by: Optional[str]
    approved_at: Optional[datetime]
    published_by: Optional[str]
    published_at: Optional[datetime]
    rejected_by: Optional[str]
    rejected_at: Optional[datetime]
    rejection_reason: Optional[str]
    created_at: datetime
    updated_at: Optional[datetime]


# ----- Lifecycle-Actions -----

class SubmitForReviewRequest(BaseModel):
    change_summary: str
    submitter: Optional[str] = None
    comment: Optional[str] = None


class ApprovalActionRequest(BaseModel):
    approver: Optional[str] = None
    comment: Optional[str] = None


class RejectActionRequest(BaseModel):
    rejector: Optional[str] = None
    rejection_reason: str
    comment: Optional[str] = None


class ApprovalHistoryEntry(BaseModel):
    id: str
    version_id: str
    action: str
    approver: Optional[str]
    comment: Optional[str]
    created_at: datetime


# ----- Tenant-Overrides -----

class OverrideCreate(BaseModel):
    rule_id: str
    override_classification: Optional[str] = None  # null = deaktiviert
    reason: str
    created_by: Optional[str] = None


class OverrideResponse(BaseModel):
    id: str
    tenant_id: str
    rule_id: str
    override_classification: Optional[str]
    reason: str
    created_by: Optional[str]
    created_at: datetime
    updated_at: Optional[datetime]


# ----- Recommendation -----

class RecommendationRequest(BaseModel):
    """Input fürs Recommend: Profil-Antworten + optional Compliance-Tiefe."""
    profile: dict[str, Any]
    compliance_depth_level: Optional[str] = None  # "L1"|"L2"|"L3"|"L4"


class RecommendedItem(BaseModel):
    document_type: str
    title: str
    rule_id: str
    rule_key: str
    classification: str  # required | recommended | optional (nach Override-Anwendung)
    base_classification: str  # ohne Override
    source_citation: str
    reason: str  # menschenlesbare Begründung
    override_applied: bool


class RecommendationResult(BaseModel):
    required: list[RecommendedItem]
    recommended: list[RecommendedItem]
    optional: list[RecommendedItem]
    profile_used: dict[str, Any]


__all__ = [
    "RuleClause", "RuleCondition",
    "RuleCreate", "RuleResponse",
    "RuleVersionCreate", "RuleVersionUpdate", "RuleVersionResponse",
    "SubmitForReviewRequest", "ApprovalActionRequest", "RejectActionRequest",
    "ApprovalHistoryEntry",
    "OverrideCreate", "OverrideResponse",
    "RecommendationRequest", "RecommendedItem", "RecommendationResult",
]
