use crate::abilities::HeadAbility;
use bevy::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Debug, Default, Reflect, Serialize, Deserialize, PartialEq, Eq)]
pub enum HeadControls {
    #[default]
    Walk,
    Plane,
}

#[derive(Debug, Default, Reflect, Serialize, Deserialize)]
pub struct HeadStats {
    pub key: String,
    #[serde(default)]
    pub ability: HeadAbility,
    #[serde(default)]
    pub range: f32,
    #[serde(default)]
    pub controls: HeadControls,
    #[serde(default)]
    pub projectile: String,
    #[serde(default = "default_ammo")]
    pub ammo: u32,
    #[serde(default)]
    pub damage: u32,
    // ability per second
    #[serde(default = "default_aps")]
    pub aps: f32,
}

fn default_aps() -> f32 {
    1.
}

fn default_ammo() -> u32 {
    10
}

#[derive(Debug, Asset, Reflect, Serialize, Deserialize)]
pub struct HeadDatabaseAsset(pub Vec<HeadStats>);

#[derive(Debug, Resource, Reflect)]
#[reflect(Resource)]
pub struct HeadsDatabase {
    pub heads: Vec<HeadStats>,
}

impl HeadsDatabase {
    pub fn head_key(&self, id: usize) -> &str {
        &self.heads[id].key
    }

    pub fn head_stats(&self, id: usize) -> &HeadStats {
        &self.heads[id]
    }
}

// #[cfg(test)]
// mod test {
//     use super::*;

//     #[test]
//     fn test_serialize() {
//         let asset = HeadDatabaseAsset(vec![
//             HeadStats {
//                 key: String::from("foo"),
//                 range: 90.,
//                 ..Default::default()
//             },
//             HeadStats {
//                 key: String::from("bar"),
//                 ability: HeadAbility::Gun,
//                 range: 0.,
//             },
//         ]);

//         std::fs::write("assets/test.headsb.ron", ron::to_string(&asset).unwrap()).unwrap();
//     }
// }
