using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSO2SERVER.Models
{
    public enum AttackType
    {
        Mel = 0,
        Rng = 1,
        Tec = 2
    }

    public class LevelStats
    {
        public ulong ExpToNext { get; set; } = 0;
        public float Hp { get; set; } = 0;
        public float Pp { get; set; } = 0;
        public float MelPow { get; set; } = 0;
        public float RngPow { get; set; } = 0;
        public float TecPow { get; set; } = 0;
        public float Dex { get; set; } = 0;
        public float MelDef { get; set; } = 0;
        public float RngDef { get; set; } = 0;
        public float TecDef { get; set; } = 0;
    }

    public class StatMultipliers
    {
        public sbyte Hp { get; set; } = 0;
        public sbyte MelPow { get; set; } = 0;
        public sbyte RngPow { get; set; } = 0;
        public sbyte TecPow { get; set; } = 0;
        public sbyte Dex { get; set; } = 0;
        public sbyte MelDef { get; set; } = 0;
        public sbyte RngDef { get; set; } = 0;
        public sbyte TecDef { get; set; } = 0;
    }

    public class ClassStatsStored
    {
        public ClassType Class { get; set; }
        public List<LevelStats> Stats { get; set; } = new List<LevelStats>();
    }

    public class PlayerStats
    {
        public List<List<LevelStats>> Stats { get; set; } = new List<List<LevelStats>>();
        public List<StatMultipliers> Modifiers { get; set; } = new List<StatMultipliers>();
    }

    public class RaceModifierStored
    {
        public StatMultipliers HumanMale { get; set; } = new StatMultipliers();
        public StatMultipliers HumanFemale { get; set; } = new StatMultipliers();
        public StatMultipliers NewmanMale { get; set; } = new StatMultipliers();
        public StatMultipliers NewmanFemale { get; set; } = new StatMultipliers();
        public StatMultipliers CastMale { get; set; } = new StatMultipliers();
        public StatMultipliers CastFemale { get; set; } = new StatMultipliers();
        public StatMultipliers DeumanMale { get; set; } = new StatMultipliers();
        public StatMultipliers DeumanFemale { get; set; } = new StatMultipliers();
    }

    public class EnemyLevelBaseStats
    {
        public uint Level { get; set; } = 0;
        public float Exp { get; set; } = 0;
        public float Hp { get; set; } = 0;
        public float MaxMelDmg { get; set; } = 0;
        public float MinMelDmg { get; set; } = 0;
        public float MaxRngDmg { get; set; } = 0;
        public float MinRngDmg { get; set; } = 0;
        public float MaxTecDmg { get; set; } = 0;
        public float MinTecDmg { get; set; } = 0;
        public float MelDef { get; set; } = 0;
        public float RngDef { get; set; } = 0;
        public float TecDef { get; set; } = 0;
        public float Dex { get; set; } = 0;
    }

    public class EnemyHitbox
    {
        public string Name { get; set; } = string.Empty;
        public uint HitboxId { get; set; } = 0;
        public float DamageMul { get; set; } = 1.0f;
        public float MelMul { get; set; } = 1.0f;
        public float RngMul { get; set; } = 1.0f;
        public float TecMul { get; set; } = 1.0f;
        public float FireMul { get; set; } = 1.0f;
        public float IceMul { get; set; } = 1.0f;
        public float ThunderMul { get; set; } = 1.0f;
        public float WindMul { get; set; } = 1.0f;
        public float LightMul { get; set; } = 1.0f;
        public float DarkMul { get; set; } = 1.0f;
    }

    public class EnemyBaseStats
    {
        public List<EnemyLevelBaseStats> Levels { get; set; } = new List<EnemyLevelBaseStats>();
    }

    public class EnemyStats
    {
        public List<EnemyLevelBaseStats> Levels { get; set; } = new List<EnemyLevelBaseStats>();
        public List<EnemyHitbox> Hitboxes { get; set; } = new List<EnemyHitbox>();
    }

    public class NamedEnemyStats
    {
        public string Name { get; set; } = string.Empty;
        public EnemyStats Stats { get; set; } = new EnemyStats();
    }

    public class AllEnemyStats
    {
        public EnemyBaseStats Base { get; set; } = new EnemyBaseStats();
        public Dictionary<string, EnemyStats> Enemies { get; set; } = new Dictionary<string, EnemyStats>();
    }

    public class AttackStatsReadable
    {
        public string AttackName { get; set; } = string.Empty;
        public string DamageName { get; set; } = string.Empty;
        public AttackType AttackType { get; set; } = AttackType.Mel;
        public AttackType DefenseType { get; set; } = AttackType.Mel;
        public DamageTypeReadable Damage { get; set; } = new DamageTypeReadable();
    }

    public class AttackStats
    {
        public uint AttackId { get; set; } = 0;
        public uint DamageId { get; set; } = 0;
        public AttackType AttackType { get; set; } = AttackType.Mel;
        public AttackType DefenseType { get; set; } = AttackType.Mel;
        public DamageType Damage { get; set; } = new DamageType();
    }

    public class DamageTypeReadable
    {
        public static DamageTypeReadable Default => new DamageTypeReadable { Mul = 1.0f };

        public float Mul { get; set; } = 1.0f;
        public string Name { get; set; } = string.Empty;
    }

    public class DamageType
    {
        public float Mul { get; set; } = 1.0f;
        public Tuple<uint, float> Pa { get; set; } = new Tuple<uint, float>(0, 1.0f);

        public DamageType() { }

        public DamageType(float mul)
        {
            Mul = mul;
        }

        public DamageType(Tuple<uint, float> pa)
        {
            Pa = pa;
        }
    }

    public class DamageTypeConverter
    {
        public static DamageType ConvertToDamageType(DamageTypeReadable value)
        {
            return new DamageType(value.Mul);
        }
    }

    public struct EXPReceiver
    {
        // 玩家获得经验的对象
        public ObjectHeader Object;  // 如果 ObjectHeader 是结构体，则可以这样使用；如果是类，需要修改或替代

        public byte Unk1;            // 未知字段 1
        public byte Unk2;            // 未知字段 2
        public byte[] Unk3;          // 6 字节的数组（未知数据），这部分需要额外处理

        // 主职业获得的经验
        public ulong Gained;

        // 主职业的总经验
        public ulong Total;

        // 主职业的新子等级（?）
        public ushort Level2;

        // 主职业的新等级
        public ushort Level;

        // 主职业
        public ClassType Class;  // 假设 ClassType 是一个枚举类型或者结构体

        public byte[] Pad1;      // 填充字节数组（3 字节），需要额外处理

        // 副职业获得的经验
        public ulong GainedSub;

        // 副职业的总经验
        public ulong TotalSub;

        // 副职业的新子等级（?）
        public ushort Level2Sub;

        // 副职业的新等级
        public ushort LevelSub;

        // 副职业
        public ClassType Subclass;  // 假设 ClassType 是一个枚举类型或者结构体

        public byte[] Pad2;      // 填充字节数组（3 字节），需要额外处理

        // 结构体构造函数，用于初始化数组和其他默认值
        public EXPReceiver(ObjectHeader objectHeader, byte unk1, byte unk2, byte[] unk3, ulong gained, ulong total,
                           ushort level2, ushort level, ClassType classType, byte[] pad1, ulong gainedSub,
                           ulong totalSub, ushort level2Sub, ushort levelSub, ClassType subclass, byte[] pad2)
        {
            Object = objectHeader;
            Unk1 = unk1;
            Unk2 = unk2;
            Unk3 = unk3 ?? new byte[6];  // 默认值为6字节数组
            Gained = gained;
            Total = total;
            Level2 = level2;
            Level = level;
            Class = classType;
            Pad1 = pad1 ?? new byte[3];  // 默认值为3字节数组
            GainedSub = gainedSub;
            TotalSub = totalSub;
            Level2Sub = level2Sub;
            LevelSub = levelSub;
            Subclass = subclass;
            Pad2 = pad2 ?? new byte[3];  // 默认值为3字节数组
        }
    }
}
