from __future__ import annotations

"""Pydantic models for SDK responses."""

from datetime import datetime
from typing import Any

from pydantic import BaseModel


class DecisionRecord(BaseModel):
    """A recorded decision from the Nexure ledger."""

    id: str
    decision_type: str
    sequence_number: int
    hash: str
    previous_hash: str
    package_id: str
    brief_id: str | None = None
    action: str
    conditions: str | None = None
    reasoning: str | None = None
    decided_by: str
    decided_at: datetime
    overrode_model: bool = False
    overrode_brief: bool = False
    override_reason: str | None = None
    evidence_snapshot: dict[str, Any]
    trust_score: int | None = None
    classification: str | None = None
    tenant_id: str
    created_at: datetime


class DecisionList(BaseModel):
    """Paginated list of decisions."""

    decisions: list[DecisionRecord]
    total: int
    page: int = 1
    page_size: int = 20
    has_more: bool = False
    limit: int | None = None
    offset: int | None = None


class DecisionPackage(BaseModel):
    """A decision evidence package."""

    id: str
    decision_type: str
    subject: dict[str, Any] | None = None
    evidence: dict[str, Any]
    policy_context: dict[str, Any] | None = None
    model_output: dict[str, Any] | None = None
    source_system: str | None = None
    source_agent: str | None = None
    metadata: dict[str, Any] | None = None
    tenant_id: str
    created_at: datetime


class DecisionBrief(BaseModel):
    """An AI-generated decision brief."""

    id: str
    package_id: str | None = None
    template_id: str
    template_version: str
    synthesis: str = ""
    key_metrics_assessment: str = ""
    risk_narrative: str = ""
    flags: list[dict[str, Any]] = []
    comparables: dict[str, Any] | None = None
    pattern_match: str | None = None
    quality_score: int = 50
    quality_level: str = "moderate"
    quality_components: dict[str, int] = {}
    quality_summary: str = ""
    model_used: str | None = None
    generation_time_ms: int = 0
    tenant_id: str
    created_at: str


class ForensicReport(BaseModel):
    """Full forensic reconstruction of a decision."""

    record: DecisionRecord
    package: DecisionPackage
    brief: DecisionBrief | None = None
    chain_verified: bool
    chain_position: int
    chain_length: int


class TemplateInfo(BaseModel):
    """Template summary information."""

    id: str
    version: str
    display_name: str
    description: str = ""
    industry: str | None = None
    author: str | None = None


class TemplateDetail(TemplateInfo):
    """Full template detail including config."""

    config: dict[str, Any]


class TemplateList(BaseModel):
    """List of templates."""

    templates: list[TemplateInfo]


class LedgerVerification(BaseModel):
    """Result of hash chain verification."""

    valid: bool
    records_checked: int
    first_break_at: int | None = None
    error: str | None = None
    tenant_id: str
    verified_at: datetime


# ── Analytics Models ──────────────────────────────────────────────


class ActionBreakdownItem(BaseModel):
    action: str
    count: int
    percentage: float


class DailyDecisionCountItem(BaseModel):
    date: str
    count: int


class AnalyticsOverview(BaseModel):
    total_decisions: int
    decisions_in_period: int
    override_rate: float
    avg_trust_score: float | None = None
    action_breakdown: list[ActionBreakdownItem]
    decisions_by_day: list[DailyDecisionCountItem] = []
    tenant_id: str
    period_start: datetime
    period_end: datetime


class OverrideDirectionInfo(BaseModel):
    allow_to_block: int = 0
    block_to_allow: int = 0
    other: int = 0


class ReviewerOverrideInfo(BaseModel):
    reviewer: str
    total_decisions: int
    overrides: int
    override_rate: float
    is_anomaly: bool = False
    deviation_from_mean: float = 0.0
    override_direction: OverrideDirectionInfo | None = None


class OverrideTrendWeekItem(BaseModel):
    week: str
    rate: float


class AnalyticsOverrides(BaseModel):
    team_override_rate: float
    reviewers: list[ReviewerOverrideInfo]
    anomaly_threshold: float
    by_decision_type: dict[str, float] = {}
    trend: list[OverrideTrendWeekItem] = []
    tenant_id: str


class WeeklyMetricItem(BaseModel):
    week_start: datetime
    approval_rate: float
    denial_rate: float
    override_rate: float
    decision_count: int
    avg_trust_score: float | None = None


class DriftAlertItem(BaseModel):
    metric: str
    direction: str
    severity: str = "low"
    current_value: float
    baseline_value: float
    change_pct: float
    message: str


class AnalyticsDrift(BaseModel):
    weeks: list[WeeklyMetricItem]
    alerts: list[DriftAlertItem]
    tenant_id: str


class ComparisonPairItem(BaseModel):
    record_a_id: str
    record_b_id: str
    record_a_action: str
    record_b_action: str
    record_a_decided_by: str
    record_b_decided_by: str
    similarity_score: float
    key_evidence_a: dict[str, Any]
    key_evidence_b: dict[str, Any]
    key_differences: list[str] = []


class AnalyticsComparisons(BaseModel):
    pairs: list[ComparisonPairItem]
    total_comparisons_checked: int
    tenant_id: str


class VisibilityComponentItem(BaseModel):
    name: str
    weight: float
    score: float
    raw_value: float
    description: str


class VisibilityScore(BaseModel):
    score: float
    components: list[VisibilityComponentItem]
    total_decisions: int
    tenant_id: str


# ── API Key Models ───────────────────────────────────────────────


class ApiKeyInfo(BaseModel):
    """API key summary (masked)."""

    id: str
    name: str
    key_prefix: str
    is_active: bool
    last_used_at: datetime | None = None
    created_at: datetime


class ApiKeyCreated(ApiKeyInfo):
    """Returned on creation — includes raw key."""

    raw_key: str


class ApiKeyList(BaseModel):
    """List of API keys."""

    keys: list[ApiKeyInfo]
    total: int


# ── Anomaly Alert Models ────────────────────────────────────────


class AnomalySummary(BaseModel):
    """Anomaly summary for list views."""

    id: str
    metric_type: str
    dimension: str | None = None
    baseline_value: float
    current_value: float
    deviation_sigma: float
    percent_change: float
    severity: str
    status: str
    title: str
    detected_at: datetime


class AnomalyList(BaseModel):
    """Paginated list of anomalies."""

    anomalies: list[AnomalySummary]
    total: int
    limit: int
    offset: int


class TrendPoint(BaseModel):
    """Single point in a metric trend."""

    week: str
    value: float


class AnomalyDetail(AnomalySummary):
    """Full anomaly detail with trend."""

    description: str | None = None
    acknowledged_at: datetime | None = None
    resolved_at: datetime | None = None
    dismissed_at: datetime | None = None
    dismiss_reason: str | None = None
    related_decision_ids: list[str] = []
    trend: list[TrendPoint] = []
    tenant_id: str
    created_at: datetime


class DetectionResult(BaseModel):
    """Result of running anomaly detection."""

    anomalies_detected: int
    metrics_checked: int
    note: str | None = None


class BaselineResult(BaseModel):
    """Result of baseline calculation."""

    baselines_updated: int
    sample_size: int


# ── Outcome Tracking Models ─────────────────────────────────


class OutcomeTypeInfo(BaseModel):
    """Outcome type definition."""

    id: str
    decision_type: str
    code: str
    label: str
    sentiment: str
    description: str | None = None
    display_order: int = 0
    is_terminal: bool = True


class OutcomeTypeList(BaseModel):
    """List of outcome types."""

    outcome_types: list[OutcomeTypeInfo]
    total: int


class OutcomeRecord(BaseModel):
    """A single recorded outcome."""

    id: str
    decision_id: str
    outcome_type_id: str
    outcome_code: str
    outcome_date: datetime
    days_to_outcome: int | None = None
    outcome_value: float | None = None


class OutcomeItemResult(BaseModel):
    """Result for a single item in a batch."""

    index: int
    status: str
    id: str | None = None
    decision_id: str | None = None
    error: str | None = None


class BatchOutcomeResult(BaseModel):
    """Result of batch outcome import."""

    batch_id: str
    total: int
    succeeded: int
    failed: int
    results: list[OutcomeItemResult]


class DecisionOutcomeItem(BaseModel):
    """Single outcome in a decision's outcome list."""

    id: str
    outcome_code: str
    outcome_label: str
    sentiment: str
    outcome_date: datetime
    days_to_outcome: int | None = None
    outcome_value: float | None = None
    is_terminal: bool = True
    source: str


class DecisionOutcomes(BaseModel):
    """All outcomes for a decision."""

    decision_id: str
    outcomes: list[DecisionOutcomeItem]
    current_status: str | None = None
    total: int


class OutcomeCodeStatsItem(BaseModel):
    """Stats for a single outcome code."""

    code: str
    label: str
    sentiment: str
    count: int
    percentage: float
    avg_days_to_outcome: float | None = None
    avg_outcome_value: float | None = None


class OutcomeStats(BaseModel):
    """Overall outcome statistics."""

    decision_type: str
    total_outcomes: int
    by_sentiment: dict[str, int]
    by_code: list[OutcomeCodeStatsItem]
    positive_rate: float
    negative_rate: float


class ReviewerOutcomeStatsItem(BaseModel):
    """Per-reviewer outcome statistics."""

    reviewer: str
    total_outcomes: int
    positive: int
    negative: int
    neutral: int
    positive_rate: float
    vs_team_avg: float


class ReviewerOutcomes(BaseModel):
    """Outcome stats broken down by reviewer."""

    decision_type: str
    team_positive_rate: float
    reviewers: list[ReviewerOutcomeStatsItem]


class OverrideGroupStatsItem(BaseModel):
    """Stats for overridden or non-overridden decisions."""

    total: int
    positive: int
    negative: int
    positive_rate: float
    negative_rate: float


class OverrideOutcomes(BaseModel):
    """Override vs non-override outcome comparison."""

    decision_type: str
    overridden: OverrideGroupStatsItem
    non_overridden: OverrideGroupStatsItem
    insight: str | None = None


# ── Customer Explanation Models ──────────────────────────────


class ExplanationTemplateInfo(BaseModel):
    """Explanation template summary."""

    id: str
    name: str
    decision_type: str
    action_filter: str | None = None
    template_type: str
    language: str = "en"
    max_factors: int = 5
    use_llm_enhancement: bool = False
    is_default: bool = False
    is_active: bool = True


class ExplanationTemplateList(BaseModel):
    """List of explanation templates."""

    templates: list[ExplanationTemplateInfo]
    total: int


class ExplanationTemplateDetail(ExplanationTemplateInfo):
    """Full explanation template with content fields."""

    header_template: str | None = None
    opening_template: str | None = None
    factors_intro: str | None = None
    factor_template: str | None = None
    evidence_section: str | None = None
    next_steps: str | None = None
    footer_template: str | None = None
    legal_disclaimer: str | None = None


class ExplanationInfo(BaseModel):
    """Generated explanation."""

    id: str
    decision_id: str
    template_id: str | None = None
    explanation_type: str
    language: str = "en"
    generated_text: str
    generated_html: str | None = None
    factors_included: list[dict[str, Any]] = []
    generation_method: str
    generation_time_ms: int | None = None
    created_at: datetime


class ExplanationSummary(BaseModel):
    """Explanation summary for list views."""

    id: str
    decision_id: str
    template_id: str | None = None
    explanation_type: str
    language: str = "en"
    generation_method: str
    generation_time_ms: int | None = None
    created_at: datetime


class ExplanationListResult(BaseModel):
    """List of explanations for a decision."""

    decision_id: str
    explanations: list[ExplanationSummary]
    total: int


class PortalLink(BaseModel):
    """Portal access link for a customer."""

    explanation_id: str
    token: str
    expires_at: datetime
    portal_url: str


class PortalExplanation(BaseModel):
    """Public portal explanation (accessed via token)."""

    explanation_id: str
    explanation_type: str
    language: str = "en"
    generated_text: str
    generated_html: str | None = None
    factors_included: list[dict[str, Any]] = []
    generation_method: str
    created_at: datetime
