"""
Mathematical Economic Simulation & Anti-Inflation Engine for FreeExile.
Implements Dynamic Equilibrium modeling (Faucets vs Sinks), Trade Tax Burning,
and Automatic Inflation Stabilizer across 1,000,000 CCU.
"""

from __future__ import annotations
import math
from enum import Enum, auto
from dataclasses import dataclass, field
from typing import List, Dict, Tuple, Optional


class CurrencyFlowType(Enum):
    FAUCET_MONSTER_DROP = "FAUCET_MONSTER_DROP"
    FAUCET_QUEST_REWARD = "FAUCET_QUEST_REWARD"
    SINK_CRAFTING = "SINK_CRAFTING"
    SINK_TRADE_TAX = "SINK_TRADE_TAX"
    SINK_MAP_DEVICE = "SINK_MAP_DEVICE"
    SINK_HIDEOUT = "SINK_HIDEOUT"


@dataclass(slots=True)
class EconomyState:
    total_supply: int
    sink_efficiency_ratio: float = 1.0
    daily_inflation_rate: float = 0.0
    hyperinflation_warning: bool = False


@dataclass(slots=True)
class DailySimulationReport:
    day_index: int
    faucets: int
    sinks: int
    net_currency_delta: int
    sink_efficiency_ratio: float
    hyperinflation_detected: bool
    action_recommendation: str


@dataclass(slots=True)
class DynamicSinkMultipliers:
    crafting_cost_multiplier: float
    map_device_fee_multiplier: float


class EconomicSimulationEngine:
    """
    Mathematical governor that monitors currency creation and destruction.
    Maintains Sink Efficiency Ratio (SER = Sinks / Faucets) near 1.00 (+/- 0.05).
    """

    def __init__(self, initial_currency_supply: int = 10_000_000) -> None:
        self._total_supply = initial_currency_supply
        self._history: List[DailySimulationReport] = []
        self._current_ser = 1.0
        self._hyperinflation_active = False

    def get_state(self) -> EconomyState:
        return EconomyState(
            total_supply=self._total_supply,
            sink_efficiency_ratio=self._current_ser,
            daily_inflation_rate=0.0 if not self._history else (self._history[-1].net_currency_delta / max(1, self._total_supply)),
            hyperinflation_warning=self._hyperinflation_active
        )

    def apply_trade_tax_burn(self, trade_volume: int, tax_rate: float = 0.05) -> int:
        """
        Permanently burns a percentage of currency on every market transaction.
        Removes currency directly from total supply into the void.
        """
        burned_amount = int(trade_volume * tax_rate)
        self._total_supply = max(0, self._total_supply - burned_amount)
        return burned_amount

    def simulate_day(
        self,
        faucets_generated: int,
        crafting_sink: int,
        trade_tax_sink: int,
        map_device_sink: int
    ) -> DailySimulationReport:
        """
        Simulates 1 economy cycle (24-hour window) and updates supply & health indices.
        """
        total_sinks = crafting_sink + trade_tax_sink + map_device_sink
        net_delta = faucets_generated - total_sinks
        self._total_supply += net_delta

        ser = (total_sinks / faucets_generated) if faucets_generated > 0 else 1.0
        self._current_ser = ser

        # Hyperinflation detection: when sinks fail to absorb at least 70% of minted currency
        hyperinflation_detected = ser < 0.70
        self._hyperinflation_active = hyperinflation_detected

        if hyperinflation_detected:
            rec = "DEFICIT_SINK_CRITICAL: Increase Map Device activation fees, raise crafting stone requirements, and activate market burn."
        elif ser > 1.20:
            rec = "EXCESS_SINK_DEFLATION: Currency is deflating rapidly. Boost monster base drop rates slightly."
        else:
            rec = "EQUILIBRIUM_HEALTHY: Faucets and sinks in optimal dynamic balance (SER ~ 1.0)."

        report = DailySimulationReport(
            day_index=len(self._history) + 1,
            faucets=faucets_generated,
            sinks=total_sinks,
            net_currency_delta=net_delta,
            sink_efficiency_ratio=ser,
            hyperinflation_detected=hyperinflation_detected,
            action_recommendation=rec
        )
        self._history.append(report)
        return report

    def calculate_dynamic_sink_multipliers(self, current_ser: float) -> DynamicSinkMultipliers:
        """
        Automatic counter-inflation regulator.
        If SER falls below 1.0, scales up crafting and map device fees to curb inflation.
        """
        if current_ser < 0.8:
            craft_mul = 1.0 + (0.8 - current_ser) * 1.5
            map_mul = 1.0 + (0.8 - current_ser) * 2.0
        else:
            craft_mul = 1.0
            map_mul = 1.0

        return DynamicSinkMultipliers(
            crafting_cost_multiplier=round(craft_mul, 2),
            map_device_fee_multiplier=round(map_mul, 2)
        )
