"""
FreeExile Currency Exchange & Purchasing Power Parity (PPP) Engine.
Calculates localized fiat pricing, exchange rates, web/crypto bonus coin incentives,
and prevents fraudulent cross-border VPN region arbitrage.
"""

from enum import Enum
from typing import Dict, Tuple, Optional


class RegionalPricingTier(str, Enum):
    TIER_1_STANDARD = "TIER_1_STANDARD"  # US, JP, UK, EU (Full PPP = 1.0)
    TIER_2_MODERATE = "TIER_2_MODERATE"  # KR, SG, TW, AU (PPP ~ 0.90)
    TIER_3_EMERGING = "TIER_3_EMERGING"  # VN, TH, BR, ID, PH (PPP ~ 0.50)


class FiatCurrency(str, Enum):
    USD = "USD"
    VND = "VND"
    EUR = "EUR"
    GBP = "GBP"
    JPY = "JPY"
    KRW = "KRW"
    CNY = "CNY"
    THB = "THB"
    BRL = "BRL"


class CurrencyExchangeEngine:
    """Calculates authoritative FX rates, Purchasing Power Parity adjustments, and reward bonuses."""

    # 1 USD standard base rate = 100 in-game Gold Cores
    BASE_COIN_PER_USD = 100

    # Base FX rates per 1 USD
    FX_RATES_PER_USD: Dict[str, float] = {
        "USD": 1.0,
        "VND": 25000.0,
        "EUR": 0.92,
        "GBP": 0.78,
        "JPY": 155.0,
        "KRW": 1350.0,
        "CNY": 7.25,
        "THB": 36.0,
        "BRL": 5.50,
    }

    # Country Code -> Fiat Currency
    COUNTRY_TO_CURRENCY: Dict[str, str] = {
        "US": "USD",
        "VN": "VND",
        "JP": "JPY",
        "KR": "KRW",
        "CN": "CNY",
        "TH": "THB",
        "DE": "EUR",
        "FR": "EUR",
        "GB": "GBP",
        "BR": "BRL",
        "SG": "USD",
    }

    # Purchasing Power Parity (PPP) Multiplier by Tier
    PPP_MULTIPLIERS: Dict[RegionalPricingTier, float] = {
        RegionalPricingTier.TIER_1_STANDARD: 1.00,
        RegionalPricingTier.TIER_2_MODERATE: 0.90,
        RegionalPricingTier.TIER_3_EMERGING: 0.50,
    }

    # Country -> Tier mapping
    COUNTRY_TIERS: Dict[str, RegionalPricingTier] = {
        "US": RegionalPricingTier.TIER_1_STANDARD,
        "JP": RegionalPricingTier.TIER_1_STANDARD,
        "GB": RegionalPricingTier.TIER_1_STANDARD,
        "DE": RegionalPricingTier.TIER_1_STANDARD,
        "FR": RegionalPricingTier.TIER_1_STANDARD,
        "KR": RegionalPricingTier.TIER_2_MODERATE,
        "SG": RegionalPricingTier.TIER_2_MODERATE,
        "TW": RegionalPricingTier.TIER_2_MODERATE,
        "VN": RegionalPricingTier.TIER_3_EMERGING,
        "TH": RegionalPricingTier.TIER_3_EMERGING,
        "ID": RegionalPricingTier.TIER_3_EMERGING,
        "BR": RegionalPricingTier.TIER_3_EMERGING,
    }

    def convert_usd_to_coins(self, usd_amount: float) -> int:
        """Standard baseline conversion: $1.00 = 100 Gold Cores."""
        return int(round(usd_amount * self.BASE_COIN_PER_USD))

    def get_regional_tier(self, country_code: str) -> RegionalPricingTier:
        return self.COUNTRY_TIERS.get(country_code.upper(), RegionalPricingTier.TIER_1_STANDARD)

    def get_currency_for_country(self, country_code: str) -> str:
        return self.COUNTRY_TO_CURRENCY.get(country_code.upper(), "USD")

    def calculate_localized_fiat_price(self, base_usd: float, country_code: str) -> float:
        """
        Calculates localized fiat pricing adjusted for regional Purchasing Power Parity (PPP).
        Example: $10 base in VN (PPP 0.50, FX 25,000) = 10 * 25,000 * 0.50 = 125,000 VND.
        """
        tier = self.get_regional_tier(country_code)
        ppp_factor = self.PPP_MULTIPLIERS[tier]
        currency = self.get_currency_for_country(country_code)
        fx_rate = self.FX_RATES_PER_USD.get(currency, 1.0)

        raw_price = base_usd * fx_rate * ppp_factor

        # Round sensibly for clean display
        if currency in ("VND", "KRW", "JPY"):
            return float(round(raw_price, -3)) # Round to nearest 1,000
        return float(round(raw_price, 2))

    def calculate_coins_reward(
        self,
        base_usd: float,
        platform: str,
        is_web3_crypto: bool = False
    ) -> int:
        """
        Calculates final delivered coins.
        Web Direct Store and Web3 Crypto enjoy a +10% bonus incentive because
        they bypass the 30% Apple/Google mobile platform cut.
        """
        base_coins = self.convert_usd_to_coins(base_usd)

        # 10% bonus on Web Direct or Web3 Crypto
        if is_web3_crypto or platform in ("PLATFORM_WEB_PC", "PLATFORM_ANDROID_SIDELOAD"):
            bonus_coins = int(round(base_coins * 0.10))
            return base_coins + bonus_coins

        return base_coins

    def validate_billing_region(
        self,
        ip_country: str,
        payment_country: str
    ) -> Tuple[bool, str]:
        """
        Guards against VPN region-hopping arbitrage.
        If a user with a Tier 1 IP attempts to pay with a Tier 3 subsidized method, reject or flag.
        """
        ip_norm = ip_country.strip().upper()
        pm_norm = payment_country.strip().upper()

        if ip_norm != pm_norm:
            return False, f"REGION_MISMATCH: IP origin '{ip_norm}' does not match payment method country '{pm_norm}'"

        return True, "REGION_VALID"
