from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Optional
import uuid


class Decision(str, Enum):
    ALLOW = "ALLOW"
    DENY = "DENY"


class KeyScope(str, Enum):
    ADMIN    = "admin"     # full access — all endpoints
    READ     = "read"      # GET endpoints + POST /v1/context/evaluate
    EVALUATE = "evaluate"  # POST /v1/context/evaluate only


class SensitivityLevel(str, Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    RESTRICTED = "restricted"


SENSITIVITY_ORDER = ["low", "medium", "high", "restricted"]


@dataclass
class ContextRequest:
    query: str
    agent_role: str
    user_id: str
    source_id: str
    sensitivity_level: SensitivityLevel = SensitivityLevel.MEDIUM
    session_id: str = field(default_factory=lambda: str(uuid.uuid4()))
    timestamp: datetime = field(default_factory=datetime.utcnow)
    task_type: Optional[str] = None
    catalog_data_classes: list[str] = field(default_factory=list)


@dataclass
class AgentAction:
    action_id:     str
    event_id:      str          # links to AuditEvent that drove this action
    session_id:    str
    agent_role:    str
    action_type:   str          # e.g. "loan_decision", "tool_call", "response"
    action_detail: dict
    timestamp:     datetime
    outcome:       Optional[str] = None


@dataclass
class AuditEvent:
    event_id: str
    session_id: str
    agent_role: str
    user_id: str
    source_id: str
    query: str
    decision: Decision
    policy_name: str
    reason: str
    timestamp: datetime
    context_hash: Optional[str] = None
    sensitivity_level: Optional[str] = None   # low | medium | high | restricted
    source_type: str = "rest"                  # rest | mcp | sdk
    catalog_enriched: bool = False             # True if sensitivity was upgraded by catalog
    catalog_connection_id: Optional[str] = None  # which catalog connection enriched this event
    chain_hash: Optional[str] = None           # SHA-256 tamper-evidence chain hash
    prev_hash: Optional[str] = None            # hash of the preceding event in this tenant


# ── Catalog integration models ─────────────────────────────────────────────────

@dataclass
class CatalogConnection:
    connection_id: str
    tenant_id: str
    catalog_type: str              # unity_catalog | collibra | alation | purview | ...
    display_name: str
    base_url: str
    credentials_enc: str          # Fernet-encrypted JSON (or plaintext JSON if no key set)
    sync_interval_minutes: int
    is_enabled: bool
    created_at: datetime
    updated_at: datetime
    last_sync_at: Optional[datetime] = None
    webhook_secret: Optional[str] = None
    status: str = "active"        # active | degraded | disabled


@dataclass
class CatalogClassification:
    classification_id: str
    connection_id: str
    tenant_id: str
    asset_fqn: str                 # fully-qualified name: catalog.schema.table or table-level
    asset_type: str                # table | column | schema
    sensitivity_label: str         # mapped AutoPIL level: low|medium|high|restricted
    raw_label: str                 # original label string from the catalog
    data_classes: list[str]        # e.g. ["PII", "PHI", "Financial"]
    is_certified: Optional[bool]
    trust_score: Optional[float]   # Alation-specific; None for others
    catalog_policy_ids: list[str]  # upstream policy references
    fetched_at: datetime
    expires_at: datetime


@dataclass
class SyncResult:
    sync_id: str
    connection_id: str
    tenant_id: str
    status: str                    # success | partial | failed
    assets_synced: int
    assets_skipped: int
    started_at: datetime
    error_message: Optional[str] = None
    completed_at: Optional[datetime] = None
