"""
Arthashastra Strategy Gate — Strategic Assessment Engine
Based on Kautilya's Arthashastra (~3rd century BCE).

Evaluates whether an action is strategically sound using three frameworks:

1. Shadgunya (Six Postures):
   - Sandhi (peace/alliance), Vigraha (hostility/compete),
   - Asana (neutrality/wait), Yana (march/advance),
   - Samshraya (seek shelter/partner), Dvaidhibhava (dual policy/hedge)

2. Chaturopaya (Four Means):
   - Sama (persuasion), Dana (incentive),
   - Bheda (division/differentiation), Danda (force/enforcement)

3. Shakti (Three Powers):
   - Mantra (counsel/planning), Prabhava (resources/capability),
   - Utsaha (energy/morale)
"""

from enum import Enum, auto
from dataclasses import dataclass, field
from typing import Optional


class Posture(Enum):
    """Shadgunya — Six strategic postures."""
    SANDHI = "peace"           # Ally, merge, cooperate
    VIGRAHA = "compete"        # Compete, disrupt, challenge
    ASANA = "wait"             # Hold position, observe
    YANA = "advance"           # Move forward, expand
    SAMSHRAYA = "partner"      # Seek alliance, shelter
    DVAIDHIBHAVA = "hedge"     # Dual strategy, hedge bets


class Upaya(Enum):
    """Chaturopaya — Four strategic means."""
    SAMA = "persuade"          # Negotiation, diplomacy
    DANA = "incentivize"       # Reward, invest, pay
    BHEDA = "differentiate"    # Split, distinguish, specialize
    DANDA = "enforce"          # Force, rule, mandate


class Shakti(Enum):
    """Three powers required for action."""
    MANTRA = "planning"        # Strategy, counsel, knowledge
    PRABHAVA = "resources"     # Capital, tools, infrastructure
    UTSAHA = "energy"          # Morale, momentum, bandwidth


@dataclass
class StrategicContext:
    """Context for strategic assessment."""
    task_type: str
    description: str = ""
    risk_level: str = "medium"       # low, medium, high, critical
    reversible: bool = True
    cost_usd: float = 0.0
    resources_required: dict = field(default_factory=dict)
    stakeholders: list = field(default_factory=list)
    time_pressure: str = "normal"    # relaxed, normal, urgent, critical
    metadata: dict = field(default_factory=dict)


@dataclass
class StrategyVerdict:
    """Result of strategic assessment."""
    recommended_posture: str
    recommended_upaya: str
    shakti_assessment: dict     # Power readiness scores
    risk_score: float           # 0.0 (safe) - 1.0 (dangerous)
    recommendation: str         # PROCEED / CAUTION / HALT
    reasoning: list
    suggested_conditions: list  # What conditions would change the verdict


# Risk multipliers by task type
TASK_RISK_PROFILES = {
    # Low risk — read-only, internal
    "notify": 0.1, "ping": 0.1, "query": 0.1, "report": 0.15,
    "rag-query": 0.1, "shastra-query": 0.1, "health-check": 0.05,

    # Medium risk — creates artifacts
    "content-gen": 0.4, "social_post": 0.5, "email-draft": 0.4,
    "data-enrich": 0.3, "lead-score": 0.3, "analysis": 0.25,

    # High risk — external-facing or costly
    "video-gen": 0.6, "thumbnail": 0.5, "video-edit": 0.55,
    "social-publish": 0.7, "email-send": 0.7, "api-call": 0.5,

    # Critical — money, deletion, public
    "payment": 0.9, "delete": 0.85, "deploy": 0.8,
    "public-post": 0.8, "contract-sign": 0.95,
}


class StrategyGate:
    """
    Arthashastra strategic assessment gate.

    Evaluates whether an action should proceed based on:
    - Task risk profile
    - Available resources (shakti)
    - Strategic posture selection
    - Recommended approach (upaya)

    Usage:
        gate = StrategyGate()
        verdict = gate.assess(StrategicContext(
            task_type="video-gen",
            description="Generate video ad for roofing contractor",
            cost_usd=0.15,
            resources_required={"gpu_hours": 0.5, "storage_mb": 200},
            risk_level="medium"
        ))
    """

    def __init__(self, cost_threshold=10.0, risk_threshold=0.7,
                 custom_risk_profiles=None):
        self.cost_threshold = cost_threshold
        self.risk_threshold = risk_threshold
        self.risk_profiles = {**TASK_RISK_PROFILES}
        if custom_risk_profiles:
            self.risk_profiles.update(custom_risk_profiles)

    def assess_shakti(self, context: StrategicContext) -> dict:
        """Assess the three powers for readiness."""
        # Mantra (planning) — is there enough information?
        mantra_score = 1.0
        if not context.description:
            mantra_score -= 0.3
        if context.risk_level in ("high", "critical") and not context.stakeholders:
            mantra_score -= 0.2
        mantra_score = max(0.0, mantra_score)

        # Prabhava (resources) — do we have what's needed?
        prabhava_score = 1.0
        if context.cost_usd > self.cost_threshold:
            prabhava_score -= min(0.5, context.cost_usd / self.cost_threshold * 0.3)
        if context.resources_required:
            # More resources = more risk of exhaustion
            prabhava_score -= min(0.3, len(context.resources_required) * 0.05)
        prabhava_score = max(0.0, prabhava_score)

        # Utsaha (energy) — timing and momentum
        utsaha_score = 1.0
        time_modifiers = {
            "relaxed": 0.0, "normal": 0.0, "urgent": -0.15, "critical": -0.3
        }
        utsaha_score += time_modifiers.get(context.time_pressure, 0)
        utsaha_score = max(0.0, min(1.0, utsaha_score))

        return {
            Shakti.MANTRA.value: round(mantra_score, 2),
            Shakti.PRABHAVA.value: round(prabhava_score, 2),
            Shakti.UTSAHA.value: round(utsaha_score, 2),
        }

    def select_posture(self, context: StrategicContext,
                       risk_score: float) -> str:
        """Select optimal strategic posture based on context."""
        if risk_score > 0.8:
            return Posture.ASANA.value      # Wait — too risky
        if risk_score > 0.6:
            if context.reversible:
                return Posture.SAMSHRAYA.value  # Partner — share risk
            return Posture.ASANA.value
        if context.time_pressure == "critical":
            return Posture.YANA.value        # Advance — no time to wait
        if context.cost_usd > self.cost_threshold * 0.5:
            return Posture.DVAIDHIBHAVA.value  # Hedge — significant cost
        return Posture.YANA.value            # Advance — conditions favorable

    def select_upaya(self, context: StrategicContext,
                     risk_score: float) -> str:
        """Select optimal means of action."""
        if risk_score < 0.3:
            return Upaya.SAMA.value          # Persuade — low risk, just do it
        if context.cost_usd > 0:
            return Upaya.DANA.value          # Incentivize — investment needed
        if risk_score > 0.6:
            return Upaya.BHEDA.value         # Differentiate — break into smaller steps
        return Upaya.SAMA.value

    def compute_risk(self, context: StrategicContext) -> float:
        """Compute composite risk score."""
        # Base risk from task type
        base_risk = self.risk_profiles.get(context.task_type, 0.5)

        # Modifiers
        risk_level_mod = {
            "low": -0.15, "medium": 0, "high": 0.15, "critical": 0.3
        }
        risk = base_risk + risk_level_mod.get(context.risk_level, 0)

        # Irreversible actions are riskier
        if not context.reversible:
            risk += 0.15

        # High cost increases risk
        if context.cost_usd > self.cost_threshold:
            risk += 0.1

        # Time pressure increases risk (rushed decisions)
        if context.time_pressure in ("urgent", "critical"):
            risk += 0.1

        return round(min(1.0, max(0.0, risk)), 4)

    def assess(self, context: StrategicContext) -> StrategyVerdict:
        """
        Full strategic assessment.

        Returns StrategyVerdict with recommendation: PROCEED / CAUTION / HALT
        """
        reasoning = []

        # Compute risk
        risk_score = self.compute_risk(context)
        reasoning.append(
            f"Risk score: {risk_score} "
            f"(task: {context.task_type}, level: {context.risk_level})"
        )

        # Assess shakti (powers)
        shakti = self.assess_shakti(context)
        min_shakti = min(shakti.values())
        reasoning.append(
            f"Shakti: mantra={shakti['planning']}, "
            f"prabhava={shakti['resources']}, "
            f"utsaha={shakti['energy']}"
        )

        # Select posture and upaya
        posture = self.select_posture(context, risk_score)
        upaya = self.select_upaya(context, risk_score)
        reasoning.append(f"Posture: {posture}, Upaya: {upaya}")

        # Determine recommendation
        conditions = []
        if risk_score >= self.risk_threshold:
            recommendation = "HALT"
            reasoning.append(
                f"HALT: risk {risk_score} exceeds threshold {self.risk_threshold}"
            )
            conditions.append("Reduce risk level or break into smaller tasks")
            if not context.reversible:
                conditions.append("Make the action reversible")
        elif risk_score >= 0.4 or min_shakti < 0.5:
            recommendation = "CAUTION"
            reasoning.append(
                f"CAUTION: elevated risk ({risk_score}) "
                f"or low shakti ({min_shakti})"
            )
            if min_shakti < 0.5:
                weak = [k for k, v in shakti.items() if v < 0.5]
                conditions.append(f"Strengthen: {', '.join(weak)}")
        else:
            recommendation = "PROCEED"
            reasoning.append(
                f"PROCEED: risk {risk_score}, all shakti adequate"
            )

        return StrategyVerdict(
            recommended_posture=posture,
            recommended_upaya=upaya,
            shakti_assessment=shakti,
            risk_score=risk_score,
            recommendation=recommendation,
            reasoning=reasoning,
            suggested_conditions=conditions
        )
