"""Compliance module types: enums and dataclasses."""

from __future__ import annotations

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


# ---------------------------------------------------------------------------
# Enums
# ---------------------------------------------------------------------------

class ComplianceAction(str, Enum):
    """Action taken by the compliance system."""
    APPROVED = "approved"
    REJECTED = "rejected"
    PENDING_APPROVAL = "pending_approval"
    FLAGGED = "flagged"
    KILL_SWITCH = "kill_switch"


class AuditEventType(str, Enum):
    """Types of auditable events."""
    ORDER_SUBMITTED = "order_submitted"
    ORDER_FILLED = "order_filled"
    ORDER_CANCELED = "order_canceled"
    ORDER_REJECTED = "order_rejected"
    ORDER_AMENDED = "order_amended"
    POSITION_CHANGED = "position_changed"
    CONFIG_CHANGED = "config_changed"
    KILL_SWITCH_ACTIVATED = "kill_switch_activated"
    KILL_SWITCH_DEACTIVATED = "kill_switch_deactivated"
    APPROVAL_REQUESTED = "approval_requested"
    APPROVAL_GRANTED = "approval_granted"
    APPROVAL_DENIED = "approval_denied"
    APPROVAL_EXPIRED = "approval_expired"
    SURVEILLANCE_ALERT = "surveillance_alert"
    LIMIT_BREACH = "limit_breach"
    REPORT_GENERATED = "report_generated"
    DATA_PURGED = "data_purged"


class SurveillanceAlertType(str, Enum):
    """Types of surveillance alerts."""
    WASH_TRADING = "wash_trading"
    SPOOFING = "spoofing"
    LAYERING = "layering"
    FRONT_RUNNING = "front_running"
    CONCENTRATION = "concentration"
    UNUSUAL_VOLUME = "unusual_volume"
    RAPID_FIRE = "rapid_fire"


class Role(str, Enum):
    """Access control roles."""
    TRADER = "trader"
    RISK_MANAGER = "risk_manager"
    COMPLIANCE_OFFICER = "compliance_officer"
    ADMIN = "admin"
    VIEWER = "viewer"


class ApprovalStatus(str, Enum):
    """Approval request lifecycle states."""
    PENDING = "pending"
    APPROVED = "approved"
    DENIED = "denied"
    EXPIRED = "expired"
    AUTO_APPROVED = "auto_approved"


# ---------------------------------------------------------------------------
# Dataclasses
# ---------------------------------------------------------------------------

@dataclass(frozen=True)
class AuditEvent:
    """Immutable audit log entry with hash-chain integrity."""
    event_id: str
    event_type: AuditEventType
    timestamp: float
    actor: str
    details: dict[str, Any]
    market_id: str | None = None
    order_id: str | None = None
    exchange: str | None = None
    prev_hash: str | None = None
    event_hash: str | None = None

    def to_dict(self) -> dict[str, Any]:
        return {
            "event_id": self.event_id,
            "event_type": self.event_type.value,
            "timestamp": self.timestamp,
            "actor": self.actor,
            "details": self.details,
            "market_id": self.market_id,
            "order_id": self.order_id,
            "exchange": self.exchange,
            "prev_hash": self.prev_hash,
            "event_hash": self.event_hash,
        }


@dataclass(frozen=True)
class SurveillanceAlert:
    """A surveillance alert with evidence."""
    alert_id: str
    alert_type: SurveillanceAlertType
    severity: str  # "info", "warning", "critical"
    timestamp: float
    market_id: str
    description: str
    evidence: dict[str, Any]
    resolved: bool = False
    resolution_notes: str = ""

    def to_dict(self) -> dict[str, Any]:
        return {
            "alert_id": self.alert_id,
            "alert_type": self.alert_type.value,
            "severity": self.severity,
            "timestamp": self.timestamp,
            "market_id": self.market_id,
            "description": self.description,
            "evidence": self.evidence,
            "resolved": self.resolved,
            "resolution_notes": self.resolution_notes,
        }


@dataclass(frozen=True)
class ApprovalRequest:
    """A human-in-the-loop approval request."""
    request_id: str
    order_data: dict[str, Any]
    market_id: str
    requester: str
    reason: str
    timestamp: float
    expires_at: float
    status: ApprovalStatus = ApprovalStatus.PENDING
    reviewer: str | None = None
    review_timestamp: float | None = None
    review_notes: str = ""


# ---------------------------------------------------------------------------
# Config dataclasses
# ---------------------------------------------------------------------------

@dataclass
class RegulatoryLimitConfig:
    """Regulatory position and exposure limits (distinct from RiskConfig).

    These are firm-wide limits set by the compliance officer.
    They cannot be overridden by the trader role.
    """
    max_position_per_market: dict[str, float] = field(default_factory=dict)
    max_total_notional: float = float("inf")
    max_concentration_pct: float = 25.0
    restricted_markets: set[str] = field(default_factory=set)
    max_daily_volume: float = float("inf")
    max_orders_per_minute: int = 120
    max_cancel_ratio: float = 0.95


@dataclass
class ComplianceConfig:
    """Top-level compliance configuration."""
    enabled: bool = True
    audit_enabled: bool = True
    surveillance_enabled: bool = True
    approval_enabled: bool = False
    regulatory_limits: RegulatoryLimitConfig = field(default_factory=RegulatoryLimitConfig)
    approval_threshold_notional: float = 5000.0
    approval_timeout_secs: float = 300.0
    retention_days: int = 2555  # ~7 years (SEC Rule 17a-4)
    db_path: str | None = None
    surveillance_window_secs: float = 300.0
    wash_trade_threshold_secs: float = 5.0
    spoof_cancel_threshold_secs: float = 2.0
    layering_depth: int = 3
    roles: dict[str, Role] = field(default_factory=dict)
    kill_switch_requires_role: Role = Role.RISK_MANAGER
    approval_callback: Any = None  # Callable[[ApprovalRequest], None] or None
    webhook_url: str | None = None


# ---------------------------------------------------------------------------
# Report dataclasses
# ---------------------------------------------------------------------------

@dataclass(frozen=True)
class DailyTradeReport:
    """Aggregated daily trade report for regulatory filing."""
    date: str
    total_orders: int
    total_fills: int
    total_cancels: int
    total_volume: float
    by_market: list[dict[str, Any]]
    by_exchange: list[dict[str, Any]]
    surveillance_alerts: int
    generated_at: float


@dataclass(frozen=True)
class PositionReport:
    """Current position snapshot with concentration analysis."""
    timestamp: float
    positions: list[dict[str, Any]]
    total_notional: float
    concentration: dict[str, float]
    limit_utilization: dict[str, float]


@dataclass(frozen=True)
class ComplianceReport:
    """Combined compliance report for a time period."""
    period_start: float
    period_end: float
    trade_report: DailyTradeReport
    position_report: PositionReport
    surveillance_summary: dict[str, int]
    approval_summary: dict[str, int]
    kill_switch_events: int
    chain_integrity: bool
