"""Required fields by stage/status check."""

from __future__ import annotations

from typing import Any, Dict, List, Tuple

from .base import BaseScoutCheck, PreflightResult
from ..crm_provider import Filter, FilterExpr, FilterOp
from ..models import EvidenceRow, RecommendedAction


class RequiredFieldsByStageCheck(BaseScoutCheck):
    def preflight(self) -> PreflightResult:
        rules = self.params.get("stage_rules", {}) or {}
        if not isinstance(rules, dict) or not rules:
            return PreflightResult(
                ok=False,
                unsupported=True,
                reason="Configure stage_rules parameter to define required fields per stage.",
            )
        obj = str(self.params.get("object_type", "opportunity"))
        if not self.provider.supports_object(obj):
            return PreflightResult(ok=False, unsupported=True, reason=f"Unsupported: {obj}")
        return PreflightResult(ok=True)

    def build_count_filters(self) -> Tuple[str, List[FilterExpr]]:
        obj = str(self.params.get("object_type", "opportunity"))
        rules = self.params.get("stage_rules", {}) or {}
        stage_field = str(self.params.get("stage_field", "StageName"))
        stages = list(rules.keys())
        filters: List[FilterExpr] = [Filter(stage_field, FilterOp.IN, stages)]
        if self.params.get("exclude_closed", True) and obj == "opportunity":
            filters.append(Filter("IsClosed", FilterOp.EQ, False))
        return obj, filters

    def build_sample_request(self) -> Tuple[str, List[str], List[FilterExpr], str | None, str, bool]:
        obj = str(self.params.get("object_type", "opportunity"))
        rules = self.params.get("stage_rules", {}) or {}
        stage_field = str(self.params.get("stage_field", "StageName"))
        all_fields = {"Id", "Name", "OwnerId", stage_field}
        for field_list in rules.values():
            if isinstance(field_list, list):
                all_fields.update(field_list)
        filters = self.build_count_filters()[1]
        return obj, sorted(all_fields), filters, stage_field, "ASC", False

    def evaluate(self, rows: List[Dict[str, Any]]) -> List[EvidenceRow]:
        rules = self.params.get("stage_rules", {}) or {}
        stage_field = str(self.params.get("stage_field", "StageName"))
        obj = str(self.params.get("object_type", "opportunity"))
        evidence: List[EvidenceRow] = []

        for row in rows:
            stage = row.get(stage_field, "")
            required = rules.get(stage, []) if isinstance(rules, dict) else []
            missing = [f for f in required if not row.get(f)]
            if missing:
                evidence.append(
                    EvidenceRow(
                        record_id=row.get("Id", ""),
                        sobject=obj,
                        fields={**row, "missing_fields": missing, "stage": stage},
                        reason=f"Missing {', '.join(missing)} at stage {stage}",
                        reason_code="MISSING_REQUIRED_FIELDS",
                        severity=self.definition.severity_default,
                    )
                )

        return evidence

    def get_recommended_actions(self) -> List[RecommendedAction]:
        return [
            RecommendedAction(
                action_type="export_csv",
                label="Export records missing required fields",
                risk_level="safe",
            ),
            RecommendedAction(
                action_type="create_task",
                label="Create tasks for missing required fields",
                risk_level="low",
            ),
            RecommendedAction(
                action_type="flag_record",
                label="Flag records missing required fields",
                risk_level="low",
            ),
        ]


__all__ = ["RequiredFieldsByStageCheck"]
