use data::tables::{AvatarBaseID, PostGirlConfigID, ProcedureConfigID};
use proto::{BasicDataModelBin, PlayerBasicInfo};

pub struct BasicDataModel {
    pub level: u32,
    pub exp: u32,
    pub profile_icon: u32,
    pub nick_name: Option<String>,
    pub frontend_avatar_id: Option<AvatarBaseID>,
    pub beginner_procedure_id: Option<ProcedureConfigID>,
    pub selected_post_girl_id: Option<PostGirlConfigID>,
}

impl Default for BasicDataModel {
    fn default() -> Self {
        Self {
            level: 1,
            exp: 0,
            profile_icon: 3200000,
            nick_name: None,
            frontend_avatar_id: None,
            beginner_procedure_id: Some(ProcedureConfigID::new_unchecked(1)),
            selected_post_girl_id: None,
        }
    }
}

impl BasicDataModel {
    pub fn player_basic_info(&self) -> PlayerBasicInfo {
        let avatar_id = self
            .frontend_avatar_id
            .map(|i| i.value())
            .unwrap_or_default();

        PlayerBasicInfo {
            nick_name: self.nick_name.clone().unwrap_or_default(),
            exp: self.exp,
            level: self.level,
            avatar_id,
            frontend_avatar_id: avatar_id,
            kbjleelonfe: self.profile_icon,
            has_nickname: match &self.nick_name {
                Some(_name) => 1,
                None => 0,
            },
            ..Default::default()
        }
    }

    pub fn from_bin(bin: BasicDataModelBin) -> Self {
        Self {
            level: bin.level,
            exp: bin.exp,
            profile_icon: bin.profile_icon,
            frontend_avatar_id: match bin.frontend_avatar_id {
                1.. => AvatarBaseID::new(bin.frontend_avatar_id as u32).ok(),
                _ => None,
            },
            beginner_procedure_id: match bin.beginner_procedure_id {
                1.. => ProcedureConfigID::new(bin.beginner_procedure_id as u32).ok(),
                _ => None,
            },
            selected_post_girl_id: PostGirlConfigID::new(bin.selected_post_girl_id).ok(),
            nick_name: match bin.nick_name.is_empty() {
                true => None,
                false => Some(bin.nick_name),
            },
        }
    }

    pub fn to_bin(&self) -> BasicDataModelBin {
        BasicDataModelBin {
            level: self.level,
            exp: self.exp,
            profile_icon: self.profile_icon,
            frontend_avatar_id: self
                .frontend_avatar_id
                .map(|i| i.value() as i32)
                .unwrap_or(-1),
            nick_name: self.nick_name.clone().unwrap_or_default(),
            beginner_procedure_id: self
                .beginner_procedure_id
                .map(|i| i.value() as i32)
                .unwrap_or(-1),
            selected_post_girl_id: match self.selected_post_girl_id {
                Some(post_girl_id) => post_girl_id.value(),
                None => 0,
            },
        }
    }
}
