using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using PolyTrader.Modules.Accounting.Models;

namespace PolyTrader.Modules.Accounting.Logic
{
    /// <summary>
    /// Reiner CSV-Export (A-2/A-4-neutral): erzeugt maschinen-/prüfbare CSV-Strings aus Ledger und
    /// Abrechnung. Kulturinvariant (Punkt-Dezimal, ISO-Datum), RFC-4180-Quoting. Der Dateizugriff
    /// liegt in der UI; die Formatierung ist hier pur + testbar.
    /// </summary>
    public static class CsvExporter
    {
        private static string F(decimal d) => d.ToString("0.######", CultureInfo.InvariantCulture);
        private static string T(DateTime d) => d.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);

        private static string Q(string s)
        {
            s ??= string.Empty;
            bool needsQuote = s.Contains(',') || s.Contains('"') || s.Contains('\n') || s.Contains('\r');
            if (needsQuote) s = "\"" + s.Replace("\"", "\"\"") + "\"";
            return s;
        }

        /// <summary>Vollständiger Ledger-Export (eine Zeile je Buchungssatz, inkl. Nachweisspalten).</summary>
        public static string Ledger(IEnumerable<LedgerEntry> entries)
        {
            var sb = new StringBuilder();
            sb.AppendLine("Timestamp,AccountId,EventType,Side,MarketSlug,Outcome,Size,PriceUsdc,GrossUsdc,FeeUsdc,NetUsdc,TxHash,LogIndex,Source,IdempotencyKey");
            foreach (var e in entries.OrderBy(e => e.Timestamp))
            {
                sb.Append(T(e.Timestamp)).Append(',')
                  .Append(e.AccountId).Append(',')
                  .Append(e.EventType).Append(',')
                  .Append(Q(e.Side)).Append(',')
                  .Append(Q(e.MarketSlug)).Append(',')
                  .Append(Q(e.Outcome)).Append(',')
                  .Append(F(e.Size)).Append(',')
                  .Append(F(e.PriceUsdc)).Append(',')
                  .Append(F(e.GrossUsdc)).Append(',')
                  .Append(F(e.FeeUsdc)).Append(',')
                  .Append(F(e.NetUsdc)).Append(',')
                  .Append(Q(e.TxHash)).Append(',')
                  .Append(e.LogIndex).Append(',')
                  .Append(Q(e.Source)).Append(',')
                  .Append(Q(e.IdempotencyKey)).Append('\n');
            }
            return sb.ToString();
        }

        /// <summary>Aggregat-Export einer Abrechnung (Kennzahl,USDC) – prüfbare Zusammenfassung.</summary>
        public static string Statement(PeriodStatement s)
        {
            var sb = new StringBuilder();
            sb.AppendLine("Kennzahl,USDC");
            void Row(string k, decimal v) => sb.Append(Q(k)).Append(',').Append(F(v)).Append('\n');
            sb.AppendLine(Q($"Zeitraum {T(s.From)} .. {T(s.To)}" + (s.AccountId.HasValue ? $" | Konto {s.AccountId}" : " | alle Konten")) + ",");
            Row("Anfangssaldo", s.OpeningBalanceUsdc);
            Row("Einzahlungen", s.Deposits);
            Row("Auszahlungen", s.Withdrawals);
            Row("Handelsvolumen", s.TradeVolume);
            Row("Redeems", s.Redeems);
            Row("Rewards", s.Rewards);
            Row("Fees", s.Fees);
            Row("Netto-Handelsergebnis (Cash)", s.NetTradingResultUsdc);
            Row("Endsaldo", s.ClosingBalanceUsdc);
            sb.Append(Q("Anzahl Trades")).Append(',').Append(s.TradeCount).Append('\n');
            sb.Append(Q("Anzahl Buchungen")).Append(',').Append(s.EntryCount).Append('\n');
            return sb.ToString();
        }
    }
}
