using Microsoft.EntityFrameworkCore;
using RR3CommunityServer.Models;

namespace RR3CommunityServer.Data;

public class RR3DbContext : DbContext
{
    public RR3DbContext(DbContextOptions<RR3DbContext> options) : base(options) { }

    public DbSet<Device> Devices { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Session> Sessions { get; set; }
    public DbSet<Account> Accounts { get; set; }
    public DbSet<DeviceAccount> DeviceAccounts { get; set; }
    public DbSet<Purchase> Purchases { get; set; }
    public DbSet<CatalogItem> CatalogItems { get; set; }
    public DbSet<DailyReward> DailyRewards { get; set; }
    public DbSet<TimeTrial> TimeTrials { get; set; }
    public DbSet<TimeTrialResult> TimeTrialResults { get; set; }
    public DbSet<Car> Cars { get; set; }
    public DbSet<OwnedCar> OwnedCars { get; set; }
    public DbSet<CarUpgrade> CarUpgrades { get; set; }
    public DbSet<CareerProgress> CareerProgress { get; set; }
    public DbSet<GameAsset> GameAssets { get; set; }
    public DbSet<ModPack> ModPacks { get; set; }
    public DbSet<UserSettings> UserSettings { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Seed some default catalog items
        modelBuilder.Entity<CatalogItem>().HasData(
            new CatalogItem
            {
                Id = 1,
                Sku = "com.ea.rr3.gold_1000",
                Name = "1000 Gold",
                Type = "currency",
                Price = 0.99m,
                Available = true
            },
            new CatalogItem
            {
                Id = 2,
                Sku = "com.ea.rr3.car_tier1",
                Name = "Starter Car",
                Type = "car",
                Price = 0m,
                Available = true
            },
            new CatalogItem
            {
                Id = 3,
                Sku = "com.ea.rr3.upgrade_engine",
                Name = "Engine Upgrade",
                Type = "upgrade",
                Price = 4.99m,
                Available = true
            }
        );

        // Seed gold purchase options
        modelBuilder.Entity<CatalogItem>().HasData(
            new CatalogItem
            {
                Id = 4,
                Sku = "com.ea.rr3.gold_100",
                Name = "100 Gold",
                Type = "currency",
                Price = 0m, // FREE in community server
                Available = true
            },
            new CatalogItem
            {
                Id = 5,
                Sku = "com.ea.rr3.gold_500",
                Name = "500 Gold",
                Type = "currency",
                Price = 0m,
                Available = true
            },
            new CatalogItem
            {
                Id = 6,
                Sku = "com.ea.rr3.gold_1000",
                Name = "1000 Gold",
                Type = "currency",
                Price = 0m,
                Available = true
            },
            new CatalogItem
            {
                Id = 7,
                Sku = "com.ea.rr3.gold_5000",
                Name = "5000 Gold",
                Type = "currency",
                Price = 0m,
                Available = true
            }
        );

        // Seed time trials
        modelBuilder.Entity<TimeTrial>().HasData(
            new TimeTrial
            {
                Id = 1,
                Name = "Daily Sprint Challenge",
                TrackName = "Silverstone National",
                CarName = "Any Car",
                StartDate = DateTime.UtcNow,
                EndDate = DateTime.UtcNow.AddDays(7),
                TargetTime = 90.5,
                GoldReward = 50,
                CashReward = 10000,
                Active = true
            },
            new TimeTrial
            {
                Id = 2,
                Name = "Speed Demon Trial",
                TrackName = "Dubai Autodrome",
                CarName = "Any Car",
                StartDate = DateTime.UtcNow,
                EndDate = DateTime.UtcNow.AddDays(7),
                TargetTime = 120.0,
                GoldReward = 100,
                CashReward = 25000,
                Active = true
            }
        );

        // Seed starter cars
        modelBuilder.Entity<Car>().HasData(
            new Car
            {
                Id = 1,
                CarId = "nissan_silvia_s15",
                Name = "Nissan Silvia Spec-R",
                Manufacturer = "Nissan",
                ClassType = "C",
                BasePerformanceRating = 45,
                CashPrice = 25000,
                GoldPrice = 0,
                Available = true
            },
            new Car
            {
                Id = 2,
                CarId = "ford_focus_rs",
                Name = "Ford Focus RS",
                Manufacturer = "Ford",
                ClassType = "B",
                BasePerformanceRating = 58,
                CashPrice = 85000,
                GoldPrice = 150,
                Available = true
            },
            new Car
            {
                Id = 3,
                CarId = "porsche_911_gt3",
                Name = "Porsche 911 GT3 RS",
                Manufacturer = "Porsche",
                ClassType = "A",
                BasePerformanceRating = 72,
                CashPrice = 0,
                GoldPrice = 350,
                Available = true
            },
            new Car
            {
                Id = 4,
                CarId = "ferrari_488_gtb",
                Name = "Ferrari 488 GTB",
                Manufacturer = "Ferrari",
                ClassType = "S",
                BasePerformanceRating = 88,
                CashPrice = 0,
                GoldPrice = 750,
                Available = true
            },
            new Car
            {
                Id = 5,
                CarId = "mclaren_p1_gtr",
                Name = "McLaren P1 GTR",
                Manufacturer = "McLaren",
                ClassType = "R",
                BasePerformanceRating = 105,
                CashPrice = 0,
                GoldPrice = 1500,
                Available = true
            }
        );

        // Seed some upgrade options
        modelBuilder.Entity<CarUpgrade>().HasData(
            // Nissan Silvia upgrades
            new CarUpgrade { Id = 1, CarId = "nissan_silvia_s15", UpgradeType = "engine", Level = 1, CashCost = 5000, PerformanceIncrease = 3 },
            new CarUpgrade { Id = 2, CarId = "nissan_silvia_s15", UpgradeType = "tires", Level = 1, CashCost = 3000, PerformanceIncrease = 2 },
            new CarUpgrade { Id = 3, CarId = "nissan_silvia_s15", UpgradeType = "suspension", Level = 1, CashCost = 4000, PerformanceIncrease = 2 },
            new CarUpgrade { Id = 4, CarId = "nissan_silvia_s15", UpgradeType = "brakes", Level = 1, CashCost = 3500, PerformanceIncrease = 2 },
            new CarUpgrade { Id = 5, CarId = "nissan_silvia_s15", UpgradeType = "drivetrain", Level = 1, CashCost = 4500, PerformanceIncrease = 3 }
        );
    }
}

// Database entities
public class Device
{
    public int Id { get; set; }
    public string DeviceId { get; set; } = string.Empty;
    public string HardwareId { get; set; } = string.Empty;
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime LastSeenAt { get; set; } = DateTime.UtcNow;
}

public class User
{
    public int Id { get; set; }
    public string SynergyId { get; set; } = string.Empty;
    public string? DeviceId { get; set; }
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public string? Nickname { get; set; }
    public int? Gold { get; set; } = 0;
    public int? Cash { get; set; } = 0;
    public int? Level { get; set; } = 1;
    public int? Experience { get; set; } = 0;
    public int? Reputation { get; set; } = 0;
    
    // Navigation properties
    public List<OwnedCar> OwnedCars { get; set; } = new();
    public List<CareerProgress> CareerProgress { get; set; } = new();
}

public class Session
{
    public int Id { get; set; }
    public string SessionId { get; set; } = string.Empty;
    public string? SynergyId { get; set; }
    public string DeviceId { get; set; } = string.Empty;
    public int? UserId { get; set; }
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime ExpiresAt { get; set; }
}

public class Purchase
{
    public int Id { get; set; }
    public string SynergyId { get; set; } = string.Empty;
    public string ItemId { get; set; } = string.Empty;
    public string Sku { get; set; } = string.Empty;
    public string OrderId { get; set; } = string.Empty;
    public DateTime PurchaseTime { get; set; } = DateTime.UtcNow;
    public string Token { get; set; } = string.Empty;
    public decimal Price { get; set; }
    public string Status { get; set; } = "approved";
    // For web panel display
    public int? UserId { get; set; }
    public DateTime PurchaseDate => PurchaseTime;
}

public class CatalogItem
{
    public int Id { get; set; }
    public string Sku { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public string Type { get; set; } = string.Empty;
    public decimal Price { get; set; }
    public bool Available { get; set; } = true;
}

public class DailyReward
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public DateTime RewardDate { get; set; }
    public int GoldAmount { get; set; }
    public int CashAmount { get; set; }
    public bool Claimed { get; set; }
    public DateTime? ClaimedAt { get; set; }
    public int Streak { get; set; }
}

public class TimeTrial
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public string TrackName { get; set; } = string.Empty;
    public string CarName { get; set; } = string.Empty;
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public double TargetTime { get; set; }
    public int GoldReward { get; set; }
    public int CashReward { get; set; }
    public bool Active { get; set; } = true;
}

public class TimeTrialResult
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public int TimeTrialId { get; set; }
    public double TimeSeconds { get; set; }
    public DateTime SubmittedAt { get; set; }
    public bool BeatTarget { get; set; }
    public int GoldEarned { get; set; }
    public int CashEarned { get; set; }
}

public class Car
{
    public int Id { get; set; }
    public string CarId { get; set; } = string.Empty; // Unique identifier like "porsche_911_gt3"
    public string Name { get; set; } = string.Empty;
    public string Manufacturer { get; set; } = string.Empty;
    public string ClassType { get; set; } = string.Empty; // C, B, A, S, R
    public int BasePerformanceRating { get; set; } // Base PR before upgrades
    public int CashPrice { get; set; }
    public int GoldPrice { get; set; }
    public bool Available { get; set; } = true;
    public int Year { get; set; }
    public string? Description { get; set; }
    
    // Custom content fields
    public bool IsCustom { get; set; }
    public string? CustomAuthor { get; set; }
    public string? CustomVersion { get; set; }
    public DateTime? CreatedAt { get; set; }
}

public class OwnedCar
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public string CarId { get; set; } = string.Empty;
    public string CarName { get; set; } = string.Empty;
    public string Manufacturer { get; set; } = string.Empty;
    public string ClassType { get; set; } = string.Empty;
    public int PerformanceRating { get; set; } // Current PR with upgrades
    public int UpgradeLevel { get; set; } // 0-5
    public string PurchasedUpgrades { get; set; } = string.Empty; // Comma-separated list
    public DateTime PurchasedAt { get; set; } = DateTime.UtcNow;
}

public class CarUpgrade
{
    public int Id { get; set; }
    public string CarId { get; set; } = string.Empty;
    public string UpgradeType { get; set; } = string.Empty; // engine, tires, suspension, brakes, drivetrain
    public int Level { get; set; } // 1-5
    public int CashCost { get; set; }
    public int PerformanceIncrease { get; set; }
}

public class CareerProgress
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public string SeriesName { get; set; } = string.Empty; // e.g., "Road Collection", "Endurance Legends"
    public string EventName { get; set; } = string.Empty; // e.g., "Brands Hatch GP Circuit"
    public bool Completed { get; set; }
    public int StarsEarned { get; set; } // 0-3
    public double BestTime { get; set; }
    public DateTime? CompletedAt { get; set; }
}

public class GameAsset
{
    public int Id { get; set; }
    
    // Asset identification
    public string AssetId { get; set; } = string.Empty;
    public string AssetType { get; set; } = string.Empty; // car, track, texture, audio, etc.
    public string FileName { get; set; } = string.Empty;
    public string ContentType { get; set; } = "application/octet-stream";
    
    // EA CDN info
    public string? OriginalUrl { get; set; }
    public string? EaCdnPath { get; set; }
    
    // Local storage
    public string LocalPath { get; set; } = string.Empty;
    public long FileSize { get; set; }
    public string FileSha256 { get; set; } = string.Empty;
    public string? Version { get; set; }
    
    // Metadata
    public DateTime DownloadedAt { get; set; } = DateTime.UtcNow;
    public DateTime LastAccessedAt { get; set; } = DateTime.UtcNow;
    public int AccessCount { get; set; } = 0;
    public bool IsAvailable { get; set; } = true;
    
    // Game-specific (optional)
    public string? CarId { get; set; }
    public string? TrackId { get; set; }
    public string Category { get; set; } = "misc"; // models, textures, audio, etc.
    public long? CompressedSize { get; set; }
    public string? Md5Hash { get; set; }
    
    // Custom content support
    public bool IsCustomContent { get; set; }
    public string? CustomAuthor { get; set; }
}

// Mod Pack entity - bundles of custom content
public class ModPack
{
    public int Id { get; set; }
    public string PackId { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public string Author { get; set; } = string.Empty;
    public string? Description { get; set; }
    public string Version { get; set; } = "1.0";
    
    // Comma-separated IDs
    public string? CarIds { get; set; }
    public string? TrackIds { get; set; }
    
    // Statistics
    public int DownloadCount { get; set; }
    public double Rating { get; set; }
    
    public DateTime CreatedAt { get; set; }
    public DateTime? UpdatedAt { get; set; }
}
