"""
Fee Engine – Das Herzstück des Visa-Modells.
Berechnet und routet Gebühren bei jeder Transaktion.

Skalierbar: Fee-Stufen, Volumen-Rabatte, Custom Fees pro Service.
"""
from __future__ import annotations
from dataclasses import dataclass, field


@dataclass
class FeeConfig:
    """Konfiguration der Gebührenstruktur."""
    base_fee_percent: float = 0.01          # 1% Standard-Fee
    min_fee_usd: float = 0.001              # Mindestgebühr: $0.001
    max_fee_usd: float = 100.0              # Maximalgebühr: $100
    admin_wallet: str = ""                  # Wallet für Fee-Einnahmen
    fee_tiers: dict = field(default_factory=lambda: {
        # Volumen-basierte Staffelung (monatliches TX-Volumen in USD)
        0: 0.01,           # 0-10k:     1.0%
        10_000: 0.008,     # 10k-100k:  0.8%
        100_000: 0.005,    # 100k-1M:   0.5%
        1_000_000: 0.003,  # 1M+:       0.3%
    })


class FeeEngine:
    """
    Berechnet Transaktionsgebühren.
    Unterstützt Staffelpreise basierend auf Volumen.
    """

    def __init__(self, config: FeeConfig | None = None):
        self.config = config or FeeConfig()
        # Sync base tier with base_fee_percent
        if 0 in self.config.fee_tiers:
            self.config.fee_tiers[0] = self.config.base_fee_percent
        self._monthly_volume: dict[str, float] = {}  # wallet -> volume

    def calculate_fee(self, amount_usd: float, sender_wallet: str = "") -> dict:
        """
        Berechnet die Fee für eine Transaktion.

        Args:
            amount_usd: Transaktionsbetrag in USD
            sender_wallet: Wallet des Senders (für Volumen-Rabatte)

        Returns:
            Dict mit fee_amount, fee_percent, service_amount, total
        """
        # Fee-Prozent basierend auf Volumen bestimmen
        volume = self._monthly_volume.get(sender_wallet, 0)
        fee_percent = self.config.base_fee_percent

        for threshold, rate in sorted(self.config.fee_tiers.items(), reverse=True):
            if volume >= threshold:
                fee_percent = rate
                break

        # Fee berechnen
        fee_amount = amount_usd * fee_percent
        fee_amount = max(fee_amount, self.config.min_fee_usd)
        fee_amount = min(fee_amount, self.config.max_fee_usd)

        service_amount = amount_usd - fee_amount

        return {
            "total": amount_usd,
            "service_amount": round(service_amount, 6),
            "fee_amount": round(fee_amount, 6),
            "fee_percent": fee_percent,
            "admin_wallet": self.config.admin_wallet,
        }

    def record_volume(self, sender_wallet: str, amount_usd: float):
        """Trackt Transaktionsvolumen für Staffelpreise."""
        self._monthly_volume[sender_wallet] = (
            self._monthly_volume.get(sender_wallet, 0) + amount_usd
        )

    def get_fee_schedule(self) -> list[dict]:
        """Gibt die aktuelle Gebührenstruktur zurück."""
        return [
            {"min_volume_usd": threshold, "fee_percent": rate}
            for threshold, rate in sorted(self.config.fee_tiers.items())
        ]
