"""Data quality gates for strong financial risk conclusions."""

from __future__ import annotations

from dataclasses import dataclass, field
from decimal import Decimal
from typing import Any

from .models import RiskGraphClaimSnapshot


@dataclass(slots=True)
class RiskDataQualityResult:
    passed: bool
    gate: str
    max_risk_score: int
    missing_fields: list[str] = field(default_factory=list)
    warnings: list[str] = field(default_factory=list)

    def as_dict(self) -> dict[str, Any]:
        return {
            "passed": self.passed,
            "gate": self.gate,
            "max_risk_score": self.max_risk_score,
            "missing_fields": list(self.missing_fields),
            "warnings": list(self.warnings),
        }


class RiskDataQualityGate:
    """Prevent weak source data from becoming strong automated conclusions."""

    def evaluate_claim(self, claim: RiskGraphClaimSnapshot) -> RiskDataQualityResult:
        missing_fields: list[str] = []
        warnings: list[str] = []

        if not str(claim.claim_id or "").strip():
            missing_fields.append("claim_id")
        if not (str(claim.employee_id or "").strip() or str(claim.employee_name or "").strip()):
            missing_fields.append("employee")
        if _to_decimal(claim.amount) <= Decimal("0"):
            missing_fields.append("amount")
        if not str(claim.expense_type or "").strip():
            warnings.append("expense_type")
        if claim.invoice_count > 0 and not claim.items:
            warnings.append("invoice_items")

        if missing_fields:
            return RiskDataQualityResult(
                passed=False,
                gate="capped_missing_required_fields",
                max_risk_score=69,
                missing_fields=missing_fields,
                warnings=warnings,
            )
        if len(warnings) >= 2:
            return RiskDataQualityResult(
                passed=False,
                gate="capped_low_context_quality",
                max_risk_score=69,
                warnings=warnings,
            )
        return RiskDataQualityResult(
            passed=True,
            gate="passed",
            max_risk_score=100,
            warnings=warnings,
        )

    def apply_score_cap(
        self,
        risk_score: int,
        result: RiskDataQualityResult,
    ) -> tuple[int, str]:
        if risk_score > result.max_risk_score:
            return result.max_risk_score, result.gate
        return risk_score, result.gate


def _to_decimal(value: Any) -> Decimal:
    try:
        return Decimal(str(value or "0"))
    except Exception:
        return Decimal("0")
