#![allow(dead_code)]
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
use serde::{Serialize, Deserialize};
use crate::ship::room::{Difficulty, Episode, RoomMode};


#[derive(Debug)]
pub enum MonsterParseError {
    UnknownMonster(String),
}

pub struct MonsterStatError;

#[derive(Debug, Serialize, Deserialize, Copy, Clone, Hash, Eq, PartialEq, enum_utils::FromStr, derive_more::Display)]
pub enum MonsterType {
    Hildebear,
    Hildeblue,
    Mothmant,
    Monest,
    RagRappy,
    AlRappy,
    SavageWolf,
    BarbarousWolf,
    Booma,
    Gobooma,
    Gigobooma,
    GrassAssassin,
    PoisonLily,
    NarLily,
    NanoDragon,
    EvilShark,
    PalShark,
    GuilShark,
    PofuillySlime,
    PouillySlime,
    PanArms,
    Hidoom,
    Migium,
    Dubchic,
    Garanz,
    SinowBeat,
    SinowGold,
    Canadine,
    Canane,
    RingCanadine,
    Delsaber,
    ChaosSorcerer,
    BeeR,
    BeeL,
    DarkGunner,
    DeathGunner,
    ChaosBringer,
    DarkBelra,
    Claw,
    Bulk,
    Bulclaw,
    Dimenian,
    LaDimenian,
    SoDimenian,
    Dragon,
    DeRolLe,
    DeRolLeBody,
    DeRolLeMine,
    VolOptPartA,
    VolOptPillar,
    VolOptMonitor,
    VolOptAmp,
    VolOptCore,
    VolOptUnused,
    VolOpt,
    VolOptTrap,
    DarkFalz,
    DarkFalz1,
    DarkFalz2,
    DarkFalz3,
    Darvant,
    UltDarvant,
    Dubwitch,
    Gillchic,
    EventRappy,
    Merillia,
    Meriltas,
    Gee,
    GiGue,
    Mericarol,
    Merikle,
    Mericus,
    UlGibbon,
    ZolGibbon,
    Gibbles,
    SinowBerill,
    SinowSpigell,
    Dolmolm,
    Dolmdarl,
    Morfos,
    Recobox,
    Recon,
    SinowZoa,
    SinowZele,
    Deldepth,
    Delbiter,
    BarbaRay,
    PigRay,
    GolDragon,
    GalGryphon,
    OlgaFlow,
    OlgaFlow1,
    OlgaFlow2,
    Gael,
    Giel,
    StRappy,
    HalloRappy,
    EasterRappy,
    LoveRappy,
    IllGill,
    DelLily,
    Epsilon,
    Epsiguard,
    Boota,
    ZeBoota,
    BaBoota,
    SandRappyCrater,
    SandRappyDesert,
    ZuCrater,
    PazuzuCrater,
    Astark,
    SatelliteLizardCrater,
    YowieCrater,
    Dorphon,
    DorphonEclair,
    Goran,
    GoranDetonator,
    PyroGoran,
    DelRappyCrater,
    DelRappyDesert,
    MerissaA,
    MerissaAA,
    ZuDesert,
    PazuzuDesert,
    SatelliteLizardDesert,
    YowieDesert,
    Girtablulu,
    SaintMillion,
    Shambertin,
    Kondrieu,
}


#[derive(serde::Deserialize, Debug)]
pub struct MonsterStats {
    pub atp: u16,
    pub mst: u16,
    pub evp: u16,
    pub hp: u16,
    pub dfp: u16,
    pub ata: u16,
    pub lck: u16,
    pub esp: u16,
    pub exp: u32,
}

fn load_battle_param(filename: &str) -> HashMap<MonsterType, MonsterStats> {
    let mut path = PathBuf::from("data/battle_param/");
    path.push(filename);

    let mut f = File::open(path).unwrap();
    let mut s = String::new();
    f.read_to_string(&mut s).unwrap();
    toml::from_str::<HashMap<String, MonsterStats>>(s.as_str()).unwrap()
        .into_iter()
        .map(|(monster_name, stats)| {
            (monster_name.parse().unwrap(), stats)
        }).collect()
}

pub fn load_monster_stats_table(mode: &RoomMode) -> Result<HashMap<MonsterType, MonsterStats>, MonsterStatError> {
    match mode {
        RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep1_multi_normal.toml")),
        RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep1_multi_hard.toml")),
        RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep1_multi_veryhard.toml")),
        RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep1_multi_ultimate.toml")),

        RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep2_multi_normal.toml")),
        RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep2_multi_hard.toml")),
        RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep2_multi_veryhard.toml")),
        RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep2_multi_ultimate.toml")),

        RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep4_multi_normal.toml")),
        RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep4_multi_hard.toml")),
        RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep4_multi_veryhard.toml")),
        RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep4_multi_ultimate.toml")),

        RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep1_solo_normal.toml")),
        RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep1_solo_hard.toml")),
        RoomMode::Single {episode: Episode::One, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep1_solo_veryhard.toml")),
        RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep1_solo_ultimate.toml")),

        RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep2_solo_normal.toml")),
        RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep2_solo_hard.toml")),
        RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep2_solo_veryhard.toml")),
        RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep2_solo_ultimate.toml")),

        RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Normal} => Ok(load_battle_param("ep4_solo_normal.toml")),
        RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Hard} => Ok(load_battle_param("ep4_solo_hard.toml")),
        RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::VeryHard} => Ok(load_battle_param("ep4_solo_veryhard.toml")),
        RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Ultimate} => Ok(load_battle_param("ep4_solo_ultimate.toml")),
        _ => Err(MonsterStatError),
    }
}