"""
Pramana Engine — Unified Verification Pipeline
Combines Nyaya (epistemology) + Vedic (constraints) + Arthashastra (strategy)
into a single verification call.
"""

from dataclasses import dataclass, field
from typing import Any, Optional
from datetime import datetime

from pramana.core.nyaya import NyayaGate, NyayaVerdict, Evidence, PramanaType
from pramana.core.vedic import VedicEngine, VedicVerdict, Sutra, SutraResult
from pramana.core.arthashastra import StrategyGate, StrategyVerdict, StrategicContext


@dataclass
class VerificationResult:
    """Unified result from the Pramana verification pipeline."""
    verdict: str                    # "VERIFIED" | "FLAGGED" | "HALTED"
    confidence: float               # 0.0 - 1.0
    nyaya: Optional[NyayaVerdict] = None
    vedic: Optional[VedicVerdict] = None
    strategy: Optional[StrategyVerdict] = None
    reasoning: list = field(default_factory=list)
    timestamp: str = ""
    metadata: dict = field(default_factory=dict)

    def to_dict(self) -> dict:
        """Serialize to dict for API responses."""
        result = {
            "verdict": self.verdict,
            "confidence": self.confidence,
            "timestamp": self.timestamp,
            "reasoning": self.reasoning,
        }
        if self.nyaya:
            result["nyaya"] = {
                "is_valid": self.nyaya.is_valid,
                "recommendation": self.nyaya.recommendation,
                "reliability_score": self.nyaya.reliability_score,
                "pramana_classification": self.nyaya.pramana_classification,
                "fallacies": self.nyaya.fallacies_detected,
                "reasoning": self.nyaya.reasoning_chain,
            }
        if self.vedic:
            result["vedic"] = {
                "energy_score": self.vedic.energy_score,
                "passed": self.vedic.passed,
                "recommendation": self.vedic.recommendation,
                "sutras": [
                    {
                        "sutra": s.sutra,
                        "passed": s.passed,
                        "score": s.score,
                        "detail": s.detail,
                        "violations": s.violations,
                    }
                    for s in self.vedic.sutras_applied
                ],
                "reasoning": self.vedic.reasoning,
            }
        if self.strategy:
            result["strategy"] = {
                "recommendation": self.strategy.recommendation,
                "posture": self.strategy.recommended_posture,
                "upaya": self.strategy.recommended_upaya,
                "risk_score": self.strategy.risk_score,
                "shakti": self.strategy.shakti_assessment,
                "reasoning": self.strategy.reasoning,
                "conditions": self.strategy.suggested_conditions,
            }
        if self.metadata:
            result["metadata"] = self.metadata
        return result

    def __str__(self):
        return (
            f"Pramana: {self.verdict} (confidence: {self.confidence})\n"
            f"Reasoning: {'; '.join(self.reasoning)}"
        )


class Pramana:
    """
    Unified Pramana verification engine.

    Three-layer pipeline:
    1. Nyaya Gate  — Is the evidence epistemologically valid?
    2. Vedic Engine — Do constraints satisfy mathematically?
    3. Strategy Gate — Is the action strategically sound?

    Usage:
        engine = Pramana()

        # Quick verify — data against constraints
        result = engine.verify(
            claim="Building meets fire code",
            evidence=[
                Evidence(value=True, pramana_type=PramanaType.PRATYAKSHA,
                         source="inspector_report"),
            ],
            constraints={"sprinklers": True, "min_exits": 2},
            data={"sprinklers": True, "exits": 3},
        )

        # Full pipeline with strategic context
        result = engine.verify(
            claim="Deploy new pricing model",
            evidence=[...],
            constraints={...},
            data={...},
            context=StrategicContext(
                task_type="deploy",
                risk_level="high",
                reversible=False,
                cost_usd=500
            )
        )
    """

    def __init__(self, nyaya_config=None, vedic_config=None,
                 strategy_config=None):
        self.nyaya = NyayaGate(**(nyaya_config or {}))
        self.vedic = VedicEngine()
        self.strategy = StrategyGate(**(strategy_config or {}))

    def verify(self, claim: str = "",
               evidence: list = None,
               constraints: dict = None,
               data: dict = None,
               context: StrategicContext = None,
               sutras: list = None,
               layers: list = None) -> VerificationResult:
        """
        Run the full verification pipeline.

        Args:
            claim: What is being verified (human-readable)
            evidence: List of Evidence objects for Nyaya gate
            constraints: Hard constraints for Vedic engine
            data: Current state data for Vedic engine
            context: Strategic context for Arthashastra gate
            sutras: Specific Vedic sutras to apply (auto-detect if None)
            layers: Which layers to run: ["nyaya", "vedic", "strategy"]
                    Default: all applicable layers

        Returns:
            VerificationResult with unified verdict
        """
        if layers is None:
            layers = []
            if evidence:
                layers.append("nyaya")
            if data and constraints:
                layers.append("vedic")
            if context:
                layers.append("strategy")
            if not layers:
                layers = ["vedic"]  # Default to constraint check

        constraints = constraints or {}
        data = data or {}
        evidence = evidence or []
        reasoning = []
        verdicts = []

        # Layer 1: Nyaya — Epistemological verification
        nyaya_result = None
        if "nyaya" in layers and evidence:
            nyaya_result = self.nyaya.evaluate(claim, evidence, constraints)
            verdicts.append(nyaya_result.recommendation)
            reasoning.append(
                f"Nyaya: {nyaya_result.recommendation} "
                f"(reliability: {nyaya_result.reliability_score})"
            )

        # Layer 2: Vedic — Constraint satisfaction
        vedic_result = None
        if "vedic" in layers:
            vedic_result = self.vedic.verify(data, constraints, sutras)
            verdicts.append(vedic_result.recommendation)
            reasoning.append(
                f"Vedic: {vedic_result.recommendation} "
                f"(energy: {vedic_result.energy_score})"
            )

        # Layer 3: Strategy — Arthashastra assessment
        strategy_result = None
        if "strategy" in layers and context:
            strategy_result = self.strategy.assess(context)
            verdicts.append(strategy_result.recommendation)
            reasoning.append(
                f"Strategy: {strategy_result.recommendation} "
                f"(risk: {strategy_result.risk_score}, "
                f"posture: {strategy_result.recommended_posture})"
            )

        # Unified verdict: strictest gate wins
        verdict = self._resolve_verdict(verdicts)
        confidence = self._compute_confidence(
            nyaya_result, vedic_result, strategy_result
        )

        reasoning.append(f"Final: {verdict} (confidence: {confidence})")

        return VerificationResult(
            verdict=verdict,
            confidence=confidence,
            nyaya=nyaya_result,
            vedic=vedic_result,
            strategy=strategy_result,
            reasoning=reasoning,
            timestamp=datetime.utcnow().isoformat() + "Z",
        )

    def verify_quick(self, data: dict, constraints: dict,
                     sutras: list = None) -> VerificationResult:
        """Quick constraint-only verification (Vedic engine only)."""
        return self.verify(
            data=data, constraints=constraints,
            sutras=sutras, layers=["vedic"]
        )

    def verify_claim(self, claim: str, evidence: list,
                     constraints: dict = None) -> VerificationResult:
        """Epistemological verification (Nyaya gate only)."""
        return self.verify(
            claim=claim, evidence=evidence,
            constraints=constraints, layers=["nyaya"]
        )

    def verify_action(self, task_type: str, description: str = "",
                      risk_level: str = "medium",
                      cost_usd: float = 0.0,
                      reversible: bool = True) -> VerificationResult:
        """Strategic assessment only (Arthashastra gate only)."""
        ctx = StrategicContext(
            task_type=task_type,
            description=description,
            risk_level=risk_level,
            cost_usd=cost_usd,
            reversible=reversible,
        )
        return self.verify(context=ctx, layers=["strategy"])

    def _resolve_verdict(self, verdicts: list) -> str:
        """Strictest gate wins. HALT > FLAGGED/CAUTION > VERIFIED/PROCEED."""
        halt_set = {"HALT", "HALTED", "REJECTED"}
        caution_set = {"CAUTION", "FLAGGED"}
        proceed_set = {"PROCEED", "VERIFIED"}

        for v in verdicts:
            if v in halt_set:
                return "HALTED"
        for v in verdicts:
            if v in caution_set:
                return "FLAGGED"
        if verdicts and all(v in proceed_set for v in verdicts):
            return "VERIFIED"
        return "FLAGGED"  # Default to caution

    def _compute_confidence(self, nyaya, vedic, strategy) -> float:
        """Compute unified confidence score."""
        scores = []
        if nyaya:
            scores.append(nyaya.reliability_score)
        if vedic:
            scores.append(1.0 - vedic.energy_score)
        if strategy:
            scores.append(1.0 - strategy.risk_score)

        if not scores:
            return 0.5
        return round(sum(scores) / len(scores), 4)
