using System.ComponentModel.DataAnnotations;
using System;
using System.ComponentModel.DataAnnotations.Schema;

namespace StarsAssistant.Model;

/// <summary>
/// Primary Racial Trait, only PRTs with relevant rules are currently listed.
/// </summary>
public enum PRT {
    Other = 0,
    HE = 1,
    JOAT = 2
}

public class Race
{
    #region Persistant and derived properties

    [Key]
    public required string Name { get; set; }

    public bool PlayerRace { get; set; } = false;

    public int? PlayerFileId { get; set; }

    public int ColonistsPerResource { get; set; } = 1_000;

    public int GrowthRatePercent { get; set; } = 15;

    private PRT _PRT = PRT.Other;
    public PRT PRT { 
        get => _PRT; 
        set {
            _PRT = value;
            UpdatePopDerivedValues();
        }
    }

    private bool _hasOBRM = false;
    public bool HasOBRM { 
        get => _hasOBRM; 
        set {
            _hasOBRM = value;
            UpdatePopDerivedValues();
        }
    }

    [NotMapped]
    public int MaxPopOnPlanet { get; private set; } = 1_000_000;

    [NotMapped]
    public int MaxEffectivePopOnRed { get; private set; }

    [NotMapped]
    public int MaxEffectivePopOnGreen { get; private set; }

    private bool _factoryCost3 = false;
    public bool FactoryCost3 { 
        get => _factoryCost3; 
        set {
            _factoryCost3 = value;
            FactoryGerCost = _factoryCost3 ? 3 : 4;
        }
    }

    [NotMapped]
    public int FactoryGerCost { get; private set; }

    public int FactoryNumberPer10k { get; set; } = 10;

    public int FactoryResCost { get; set; } = 10;

    public int FactoryResPer10 { get; set; } = 10;

    public int MineResCost { get; set; } = 5;

    public int MineNumberPer10k { get; set; } = 10;

    public int MineMineralsPer10 { get; set; } = 10;

    #endregion

    #region Relationships

    public ICollection<Planet> Planets { get; set; } = [];

    public ICollection<Fleet> Fleets { get; set; } = [];

    #endregion

    #region Public Helpers

    #endregion

    #region Internal Helpers

    private void UpdatePopDerivedValues() {
        const int basePop = 1_000_000;
        var prtMod = PRT switch
        {
            PRT.HE => 0.5,
            PRT.JOAT => 1.2,
            _ => 1,
        };
        double obrmMod = HasOBRM ? 1.1 : 1.0;
        MaxPopOnPlanet = Convert.ToInt32(basePop * prtMod * obrmMod);
        MaxEffectivePopOnRed = MaxPopOnPlanet * Services.GameEngine.MinEffectiveValue / 100 * 3;
        MaxEffectivePopOnGreen = MaxPopOnPlanet * 3;
    }

    #endregion
}