use libpso::packet::ship::*;
use crate::common::serverstate::ClientId;
use crate::ship::ship::{SendShipPacket, ShipError, Clients};
use crate::entity::gateway::EntityGateway;

pub async fn update_config<EG: EntityGateway>(id: ClientId,
                                        update_config: &UpdateConfig,
                                        clients: &mut Clients,
                                        entity_gateway: &mut EG)
                                        -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
    let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
    client.character.config.update(update_config);
    entity_gateway.save_character(&client.character).await.unwrap();
    Box::new(None.into_iter())
}

pub async fn save_options<EG: EntityGateway>(id: ClientId,
                                            save_options: &SaveOptions,
                                            clients: &mut Clients,
                                            entity_gateway: &mut EG)
                                            -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
    // TODO: don't unwrap?
    let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
    client.character.option_flags = save_options.options;
    entity_gateway.save_character(&client.character).await.unwrap();
    Box::new(None.into_iter())
}

pub async fn keyboard_config<EG: EntityGateway>(id: ClientId,
                                                keyboard_config: &KeyboardConfig,
                                                clients: &mut Clients,
                                                entity_gateway: &mut EG)
                                                -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
    let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
    client.character.keyboard_config.update(keyboard_config);
    entity_gateway.save_character(&client.character).await.unwrap();
    Box::new(None.into_iter())
}

pub async fn gamepad_config<EG: EntityGateway>(id: ClientId,
                                                gamepad_config: &GamepadConfig,
                                                clients: &mut Clients,
                                                entity_gateway: &mut EG)
                                                -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
    let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
    client.character.gamepad_config.update(gamepad_config);
    entity_gateway.save_character(&client.character).await.unwrap();
    Box::new(None.into_iter())
}