use std::fmt::Display;

use num_enum::FromPrimitive;

#[derive(Debug, PartialEq, Eq, Clone, Copy, FromPrimitive)]
#[repr(u32)]
pub enum ESceneType {
    #[default]
    Unknown = 0,
    Hall = 1,
    Hollow = 2,
    Fight = 3,
    Fresh = 4,
    MultiFight = 5,
    LongFight = 7,
}

#[allow(dead_code)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u32)]
pub enum EQuestType {
    ArchiveFile = 1,
    DungeonInner = 2,
    Hollow = 3,
    Manual = 4,
    MainCity = 5,
    HollowChallenge = 6,
    ArchiveBattle = 7,
    Knowledge = 8,
    Daily = 9,
}

#[allow(dead_code)]
#[derive(Debug, PartialEq, Eq, Clone, Copy, FromPrimitive)]
#[repr(u32)]
pub enum EHollowQuestType {
    ChallengeChaos = 6,
    BossRushBattle = 14,
    World = 8,
    MainQuest = 1,
    SideQuest = 2,
    #[default]
    Common = 0,
    Challenge = 5,
    PromoteBattle = 11,
    DifficutyBattle = 12,
    AvatarSide = 7,
    RallyBattle = 13,
    Urgent = 3,
    UrgentSupplement = 4,
    NormalBattle = 10,
}

#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, FromPrimitive)]
#[repr(u32)]
pub enum ESystem {
    #[default]
    None = 0xFFFFFFFF,
    VhsStore = 7,
    Gacha = 21,
    Hadal = 43,
    MonsterCard = 40,
    AbyssCollect = 45,
    Vhs = 1,
    ActivityPv = 48,
    StoryModeSwitch = 12,
    RamenStore = 8,
    QteSwitch = 13,
    DoubleElite = 36,
    LandRevive = 35,
    HadalShop = 47,
    Role = 2,
    Grocery = 10,
    AvatarBase = 33,
    Activity = 27,
    BuddyInstall = 26,
    AvatarEquip = 34,
    TartarusHounds = 20,
    BossBig = 38,
    Buddy = 25,
    Interknot = 6,
    Workbench = 9,
    HIA = 39,
    Smithy = 3,
    Trash = 23,
    UseStoryMode = 15,
    Photowall = 44,
    AbyssShop = 46,
    AbyssHeat = 29,
    DailyQuest = 41,
    Newsstand = 17,
    Cafe = 22,
    Rally = 42,
    HollowQuest = 0,
    Package = 4,
    VideoShop = 11,
    BattleDaily = 24,
    Arcade = 19,
    BossSmall = 37,
    LineupSelect = 14,
    ArcadeRoom = 30,
    Teleport = 5,
    Train = 32,
    UseManualQteMode = 16,
    ArcadeGame = 31,
    Abyss = 28,
    Toy = 18,
}

#[derive(Default, Debug, Clone, Copy, FromPrimitive)]
#[repr(u32)]
pub enum EOperator {
    Enter = 0,
    Log = 1,
    Leave = 2,
    #[default]
    Undefined = 0xFFFFFFFF,
}

#[derive(Debug, Clone, Copy)]
#[repr(u32)]
pub enum TimePeriodType {
    Morning = 0,
    Evening = 1,
    Night = 2,
}

impl TimePeriodType {
    pub fn from_str(s: &str) -> Self {
        match s {
            "Morning" => Self::Morning,
            "Evening" => Self::Evening,
            "Night" => Self::Night,
            _ => Self::Morning,
        }
    }
}

impl Display for TimePeriodType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(self, f)
    }
}

#[derive(Default, Debug, Clone, Copy)]
#[repr(u32)]
pub enum WeatherType {
    SunShine = 0,
    Fog = 1,
    Cloudy = 2,
    Rain = 3,
    Thunder = 4,
    ThickFog = 5,
    ThickCloudy = 6,
    #[default]
    None = 0xFFFFFFFF,
}

impl WeatherType {
    pub fn from_str(s: &str) -> Self {
        match s {
            "SunShine" => Self::SunShine,
            "Fog" => Self::Fog,
            "Cloudy" => Self::Cloudy,
            "Rain" => Self::Rain,
            "Thunder" => Self::Thunder,
            "ThickFog" => Self::ThickFog,
            "ThickCloudy" => Self::ThickCloudy,
            _ => Self::SunShine,
        }
    }
}

impl Display for WeatherType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(self, f)
    }
}

#[allow(dead_code)]
#[derive(Debug, Clone, Copy)]
#[repr(u32)]
pub enum ENPCInteraction {
    OnStart = 0,
    OnEnd = 1,
    OnInteract = 2,
    OnAddInteract = 3,
    OnRemoveInteract = 4,
}

impl Display for ENPCInteraction {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(self, f)
    }
}

#[derive(Default, Debug, Clone, Copy)]
pub enum ELocalPlayType {
    TrainingRoom = 290,
    BigBossBattle = 211,
    BossLittleBattleLongfight = 215,
    PureHollowBattle = 280,
    DualElite = 208,
    PureHollowBattleHardmode = 282,
    OperationBetaDemo = 216,
    AvatarDemoTrial = 213,
    BossRushBattle = 218,
    BossBattle = 210,
    GuideSpecial = 203,
    DailyChallenge = 206,
    OperationTeamCoop = 219,
    TrainingRoomFight = 291,
    LevelZero = 205,
    ArchiveLongFight = 212,
    MpBigBossBattle = 214,
    RallyLongFight = 207,
    BigBossBattleLongfight = 217,
    ArchiveBattle = 201,
    PureHollowBattleLonghfight = 281,
    HadalZone = 209,
    ChessBoardBattle = 202,
    #[default]
    Unknown = 0,
}

#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum BaseProperty {
    CurHP = 0,
    MaxHpFinal = 36,
    AddedDamageRatioFire = 52,
    AddedDamageRatioElecBattle = 583,
    FeverGetRatio = 45,
    AtkBattle = 560,
    MaxArmor = 18,
    ElementMysteryBattle = 577,
    DamageTakeRatio = 42,
    Defence = 3,
    CritRes = 23,
    MaxShield = 20,
    CritDmgBattle = 565,
    DamageTakeRatioBattle = 573,
    BreakStunBattle = 561,
    AddedElementAccumulationRatio = 48,
    CurSP = 7,
    DefBattle = 562,
    CritResBattle = 564,
    CritDmg = 6,
    ElementMystery = 46,
    AddedDamageRatioEtherBattle = 584,
    EnduranceBattle = 569,
    CritBattle = 563,
    CurBuddyBattery = 56,
    MaxHP = 1,
    CurBreakPoint = 27,
    Unknown = 4294967295,
    SPRecover = 31,
    PenRatio = 21,
    ResistBreakLevel = 35,
    CritDmgRes = 24,
    AddedDamageRatioPhysics = 51,
    AddedDamageRatioFireBattle = 581,
    AddedDamageRatioBattle = 572,
    PenDelta = 22,
    AutoRecoverStunRate = 37,
    AddedDamageRatioIce = 53,
    SpGetRatio = 44,
    MaxBuddyBattery = 57,
    AddedDamageRatioEther = 55,
    HpHealRatioBattle = 571,
    AddedDamageRatioIceBattle = 582,
    Level = 49,
    ElementAbnormalPower = 50,
    StunMaxBase = 551,
    Attack = 2,
    MaxSP = 8,
    CurMaxHpHealPercent = 32,
    MaxStunRuntime = 33,
    AllDamageResistBattle = 574,
    AddedDamageRatio = 41,
    AddedElementAccumulationRatioBattle = 578,
    Custom = 10,
    Crit = 4,
    SpGetRatioBattle = 575,
    ResistBreakPoint = 28,
    AddedDamageRatioElec = 54,
    MaxStun = 12,
    HpMaxBase = 550,
    CurStun = 11,
    CurrentArmor = 17,
    HpRecoverRate = 47,
    ElementAbnormalPowerBattle = 579,
    FeverGetRatioBattle = 576,
    CritDmgResBattle = 566,
    SpRecoverBattle = 570,
    CurEndurance = 25,
    PenDeltaBattle = 568,
    AccumulationValue = 58,
    MaxEndurance = 26,
    DestroyRecoverStunRate = 38,
    HpHealRatio = 40,
    SpMaxBase = 552,
    PenRatioBattle = 567,
    AddedDamageRatioPhysicsBattle = 580,
    BreakStun = 13,
    CurrentShield = 19,
    Luck = 5,
    AllDamageResist = 43,
}

#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(i32)]
pub enum BuddyTeamType {
    RallyGuidance = 0,
    Fighting = 1,
    Assisting = 2,
}

impl BuddyTeamType {
    pub fn to_protocol(&self) -> ::proto::BuddyTeamType {
        match *self {
            Self::RallyGuidance => ::proto::BuddyTeamType::RallyGuidance,
            Self::Fighting => ::proto::BuddyTeamType::Fighting,
            Self::Assisting => ::proto::BuddyTeamType::Assisting,
        }
    }
}
