use std::collections::HashMap;

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum CurrentRuntimeAction {
    StartingMission,
    StartingServer,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct DcsRuntime {
    pub current_action: Option<CurrentRuntimeAction>,
    pub last_full_update: i64,
    pub paused: bool,
    pub mission_info: GetMissionInfoResponse,
    #[serde(flatten)]
    pub mission_list: GetMissionListResponse,
    #[serde(flatten)]
    pub players: GetPlayersResponse,
    #[serde(flatten)]
    pub settings: GetServerSettingsResponse,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct GetMissionInfoResponse {
    pub result_red: Option<i32>,
    pub result_blue: Option<i32>,
    pub mission_filename: String,
    pub mission_time: f32,
    pub mission_name: String,
    pub mission_description: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct GetMissionListResponse {
    #[serde(
        rename = "missionList",
        deserialize_with = "super::deserialize_mission_field"
    )]
    pub mission_list: Vec<String>,
    #[serde(
        rename = "missionTheatres",
        deserialize_with = "super::deserialize_mission_field"
    )]
    pub mission_theatres: Vec<String>,
    #[serde(rename = "listStartIndex")]
    pub list_start_index: i32,
    #[serde(rename = "listShuffle")]
    pub list_shuffle: bool,
    #[serde(rename = "listLoop")]
    pub list_loop: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct GetPlayersResponse {
    pub players: Players,
    pub server_id: i32,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Players {
    #[serde(deserialize_with = "super::deserialize_array_object")]
    pub banned: Vec<BannedPlayer>,
    pub all: HashMap<String, Player>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Player {
    pub ping: i32,
    pub side: i32,
    pub slot: String,
    pub id: i32,
    pub name: String,
    pub score: i32,
    pub ucid: String,
    pub started: bool,
    pub lang: String,
    pub ipaddr: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct BannedPlayer {
    pub banned_from: i64,
    pub banned_until: i64,
    pub ipaddr: String,
    pub name: String,
    pub reason: String,
    pub ucid: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct GetServerSettingsResponse {
    pub mission_list: GetMissionListResponse,
    pub settings: Settings,
    pub ip: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Settings {
    pub description: String,
    pub require_pure_textures: bool,
    #[serde(rename = "listStartIndex")]
    pub list_start_index: i32,
    pub advanced: AdvancedSettings,
    pub port: i32,
    pub mode: i32,
    pub bind_address: String,
    #[serde(rename = "isPublic")]
    pub is_public: bool,
    #[serde(rename = "listShuffle")]
    pub list_shuffle: bool,
    pub password: String,
    #[serde(rename = "listLoop")]
    pub list_loop: bool,
    pub name: String,
    pub require_pure_scripts: bool,
    #[serde(
        rename = "missionList",
        deserialize_with = "super::deserialize_mission_field"
    )]
    pub mission_list: Vec<String>,
    pub require_pure_clients: bool,
    pub require_pure_models: bool,
    #[serde(rename = "maxPlayers")]
    pub max_players: i32,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AdvancedSettings {
    pub allow_change_tailno: bool,
    pub disable_events: bool,
    pub allow_ownship_export: bool,
    pub allow_object_export: bool,
    pub pause_on_load: bool,
    pub allow_sensor_export: bool,
    #[serde(rename = "event_Takeoff")]
    pub event_takeoff: bool,
    pub pause_without_clients: bool,
    pub client_outbound_limit: i32,
    pub client_inbound_limit: i32,
    pub server_can_screenshot: bool,
    pub allow_players_pool: bool,
    pub voice_chat_server: bool,
    pub allow_change_skin: bool,
    #[serde(rename = "event_Connect")]
    pub event_connect: bool,
    #[serde(rename = "event_Ejecting")]
    pub event_ejecting: bool,
    #[serde(rename = "event_Kill")]
    pub event_kill: bool,
    #[serde(rename = "event_Crash")]
    pub event_crash: bool,
    #[serde(rename = "event_Role")]
    pub event_role: bool,
    pub resume_mode: i32,
    #[serde(rename = "maxPing")]
    pub max_ping: i32,
    pub allow_trial_only_clients: bool,
    pub allow_dynamic_radio: bool,
    #[serde(rename = "redPasswordHash")]
    pub red_password_hash: Option<String>,
    #[serde(rename = "bluePasswordHash")]
    pub blue_password_hash: Option<String>,
    #[serde(rename = "redPassword")]
    pub red_password: Option<String>,
    #[serde(rename = "bluePassword")]
    pub blue_password: Option<String>,
}
