using Microsoft.EntityFrameworkCore;
using PolyTrader.Modules.ResolutionFarming.Models;

namespace PolyTrader.Modules.ResolutionFarming.Persistence.Ef
{
    /// <summary>
    /// EF-Core-Kontext des ResolutionFarming-Moduls (gleiche MySQL-DB wie der Core, eigene Tabellen
    /// mit Präfix rf_). Autoincrement-PKs von Anfang an (keine code-vergebenen Schlüssel – vermeidet
    /// die im Copytrading nachträglich aufgefallene TradeId-Kollisionsklasse).
    /// </summary>
    public class ResolutionFarmingDbContext : DbContext
    {
        public ResolutionFarmingDbContext(DbContextOptions<ResolutionFarmingDbContext> options) : base(options) { }

        public DbSet<RfSettings> Settings => Set<RfSettings>();
        public DbSet<RfCandidate> Candidates => Set<RfCandidate>();
        public DbSet<RfPosition> Positions => Set<RfPosition>();
        public DbSet<RfClosedTrade> ClosedTrades => Set<RfClosedTrade>();

        protected override void OnModelCreating(ModelBuilder b)
        {
            b.Entity<RfSettings>(e =>
            {
                e.ToTable("rf_settings");
                e.HasKey(x => x.AccountId);
                e.Property(x => x.AccountId).ValueGeneratedNever();
                e.Property(x => x.MinPrice).HasPrecision(18, 6);
                e.Property(x => x.MaxPrice).HasPrecision(18, 6);
                e.Property(x => x.MinEdgePct).HasPrecision(18, 6);
                e.Property(x => x.MaxPerMarketUsd).HasPrecision(18, 6);
                e.Property(x => x.MaxPerClusterPct).HasPrecision(18, 6);
                e.Property(x => x.MaxTotalExposurePct).HasPrecision(18, 6);
                e.Property(x => x.DailyLossKillSwitchUsd).HasPrecision(18, 6);
                e.Property(x => x.CategoryWhitelistCsv).HasMaxLength(500);
                e.Property(x => x.BlacklistCsv).HasMaxLength(1000);
            });

            b.Entity<RfCandidate>(e =>
            {
                e.ToTable("rf_candidates");
                e.HasKey(x => x.Id);
                e.Property(x => x.Id).ValueGeneratedOnAdd();
                e.Property(x => x.TokenId).HasMaxLength(120);
                e.Property(x => x.MarketSlug).HasMaxLength(300);
                e.Property(x => x.EventSlug).HasMaxLength(300);
                e.Property(x => x.MarketQuestion).HasMaxLength(1000);
                e.Property(x => x.Outcome).HasMaxLength(200);
                e.Property(x => x.Category).HasMaxLength(100);
                e.Property(x => x.ClusterKey).HasMaxLength(300);
                e.Property(x => x.RejectReason).HasMaxLength(300);
                e.Property(x => x.Ask).HasPrecision(18, 6);
                e.Property(x => x.NetEdgePct).HasPrecision(18, 6);
                e.Property(x => x.Score).HasPrecision(18, 6);
                e.HasIndex(x => x.ScannedAt);
                e.HasIndex(x => new { x.AccountId, x.Accepted });
            });

            b.Entity<RfPosition>(e =>
            {
                e.ToTable("rf_positions");
                e.HasKey(x => new { x.AccountId, x.TokenId });
                e.Property(x => x.TokenId).HasMaxLength(120);
                e.Property(x => x.MarketSlug).HasMaxLength(300);
                e.Property(x => x.MarketQuestion).HasMaxLength(1000);
                e.Property(x => x.Outcome).HasMaxLength(200);
                e.Property(x => x.Category).HasMaxLength(100);
                e.Property(x => x.ClusterKey).HasMaxLength(300);
                e.Property(x => x.Status).HasMaxLength(20);
                e.Property(x => x.EntryPrice).HasPrecision(18, 6);
                e.Property(x => x.Size).HasPrecision(18, 6);
                e.Property(x => x.AmountUsd).HasPrecision(18, 6);
            });

            b.Entity<RfClosedTrade>(e =>
            {
                e.ToTable("rf_closed_trades");
                e.HasKey(x => x.Id);
                e.Property(x => x.Id).ValueGeneratedOnAdd();
                e.Property(x => x.TokenId).HasMaxLength(120);
                e.Property(x => x.MarketSlug).HasMaxLength(300);
                e.Property(x => x.MarketQuestion).HasMaxLength(1000);
                e.Property(x => x.Outcome).HasMaxLength(200);
                e.Property(x => x.Category).HasMaxLength(100);
                e.Property(x => x.ClusterKey).HasMaxLength(300);
                e.Property(x => x.ExitReason).HasMaxLength(200);
                e.Property(x => x.RedeemStatus).HasMaxLength(20);
                e.Property(x => x.EntryPrice).HasPrecision(18, 6);
                e.Property(x => x.ExitPrice).HasPrecision(18, 6);
                e.Property(x => x.Size).HasPrecision(18, 6);
                e.Property(x => x.RealizedPnl).HasPrecision(18, 6);
                e.Property(x => x.PnlPercent).HasPrecision(18, 6);
                e.Property(x => x.TotalFees).HasPrecision(18, 6);
                e.HasIndex(x => new { x.AccountId, x.TokenId });
                e.HasIndex(x => x.ClosedAt);
            });
        }
    }
}
