namespace PolyTrader.Core.Trading
{
    /// <summary>
    /// Reine Fee-Logik (geteilte Markt-Infrastruktur im Core – von mehreren Strategiemodulen genutzt).
    /// Polymarket erhebt seit März 2026 Taker-Fees (Maker zahlen 0). Der reale Satz kommt idealerweise
    /// vom Markt-Objekt der CLOB-/Gamma-API (Feldname im Zielland anhand
    /// https://docs.polymarket.com/trading/fees verifizieren); bis dahin greift die Kategorie-Fallback-
    /// Tabelle. Werte in Basispunkten (bps): 100 bps = 1,0 %.
    /// </summary>
    public static class FeeModel
    {
        public const int MakerBps = 0;

        // Fallback-Sätze je Kategorie (Taker, bps) – Näherung laut Plan, im Zielland verifizieren.
        public const int SportsBps = 75;      // 0,75 %
        public const int PoliticsFinanceBps = 100; // 1,0 %
        public const int CryptoBps = 180;     // 1,8 %
        public const int GeopoliticsBps = 0;  // 0 %
        public const int DefaultBps = 100;    // konservativer Default

        /// <summary>
        /// Fallback-Taker-Fee (bps) anhand der Markt-Kategorie, wenn die API keinen Satz liefert.
        /// Robust gegen unbekannte/leere Kategorien (→ konservativer Default).
        /// </summary>
        public static int FallbackBps(string? category)
        {
            string c = (category ?? string.Empty).ToLowerInvariant();
            if (c.Contains("sport")) return SportsBps;
            if (c.Contains("crypto")) return CryptoBps;
            if (c.Contains("geopolit")) return GeopoliticsBps;
            if (c.Contains("politic") || c.Contains("finance") || c.Contains("econom")) return PoliticsFinanceBps;
            return DefaultBps;
        }

        /// <summary>
        /// Effektiver Taker-Satz (bps) für eine Order (M6): den realen Satz aus dem Markt-Objekt
        /// (<paramref name="takerFeeBps"/> &gt; 0) nutzen, sonst den Kategorie-Fallback. Wird in die
        /// signierte Order geschrieben; ein zu niedriger Satz kann auf Fee-Märkten abgelehnt werden.
        /// </summary>
        public static int ResolveBps(int takerFeeBps, string? category) =>
            takerFeeBps > 0 ? takerFeeBps : FallbackBps(category);

        /// <summary>Taker-Fee in USDC für ein Notional (Preis × Shares) bei gegebenem Satz.</summary>
        public static decimal FeeUsd(decimal notionalUsd, int feeBps)
        {
            if (feeBps <= 0 || notionalUsd <= 0m) return 0m;
            return notionalUsd * feeBps / 10000m;
        }
    }
}
