use libpso::packet::login::{Login, LoginResponse, AccountStatus, Session};
use libpso::packet::ship::*;
use crate::common::serverstate::ClientId;
use crate::ship::ship::{SendShipPacket, ShipError, ClientState, Clients};
use crate::login::login::get_login_status;
use crate::entity::gateway::EntityGateway;
use crate::ship::items::ActiveItemDatabase;

pub fn validate_login<EG: EntityGateway>(id: ClientId,
                                         pkt: &Login,
                                         entity_gateway: &mut EG,
                                         clients: &mut Clients,
                                         item_database: &mut ActiveItemDatabase,
                                         ship_name: &String)
                                         -> Result<Vec<SendShipPacket>, ShipError> {
    Ok(match get_login_status(entity_gateway, pkt) {
        Ok(user) => {
            let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new());
            response.guildcard = user.id.0 as u32;
            response.team_id = user.team_id.map_or(31, |ti| ti) as u32;
            let characters = entity_gateway.get_characters_by_user(&user);
            let character = characters
                .get(pkt.session.character_slot as usize)
                .ok_or(ShipError::InvalidSlot(id, pkt.session.character_slot as u32))?.as_ref()
                .ok_or(ShipError::NoCharacterInSlot(id, pkt.session.character_slot as u32))?
                .clone();
            let settings = entity_gateway.get_user_settings_by_user(&user)
                .ok_or(ShipError::ClientNotFound(id))?;
            let inventory = item_database.get_character_inventory(entity_gateway, &character);

            clients.insert(id, ClientState::new(user, settings, character, inventory, pkt.session));
            vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&&ship_name, 3))]
        },
        Err(err) => {
            vec![SendShipPacket::LoginResponse(LoginResponse::by_status(err, Session::new()))]
        }
    })
}