pub mod game_actions;
pub mod login;
pub mod map_actions;

use game_actions::SpawnToken;
use serde::{Deserialize, Serialize};

use crate::game::{character_sheet::EntryType, chat_message::ChatMessage, entry::ActionResult};

#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "snake_case")]
pub enum Request {
    #[default]
    Error,
    // Connection requests
    Login(login::LoginRequest),
    Quit,
    Kick(String),
    Shutdown,
    // Character stuff
    CreateCharacter,
    CharacterDisplay {
        id: usize,
    },
    CharacterInputs {
        id: usize,
    },
    CharacterGetField {
        id: usize,
        field: String,
    },
    CharacterSetField {
        id: usize,
        field: String,
        val: EntryType,
    },
    CharacterAssign {
        id: usize,
        user: String,
    },
    // Chat requests
    Message(ChatMessage),
    GetChatHistory {
        amount: usize,
        from: usize,
    },
    GetLastMessages {
        amount: usize,
    },
    // Map requests
    GetScene {
        id: usize,
    },
    GetSceneList,
    GetTokens {
        scene: usize,
    },
    SpawnToken {
        map_id: usize,
        character: String,
        x: f32,
        y: f32,
        img_path: String,
    },
    MoveToken {
        token_id: usize,
        x: f32,
        y: f32,
    },
    // Actions requests
    ActionResult(ActionResult),
}

#[derive(Serialize, Clone, Debug)]
#[serde(rename_all = "snake_case")]
pub enum Response {
    Error(RequestError),
    Login(login::LoginResult),
    Message(ChatMessage),
    GetChatHistory(Vec<ChatMessage>),
    ShowScene {
        scene: usize,
        tokens: Vec<SpawnToken>,
        background: Option<String>,
        grid_cell_size: Option<f32>,
        grid_offset: Option<[f32; 2]>,
    },
    SceneList {
        scenes: Vec<(usize, String)>,
    },
    MoveToken {
        token_id: usize,
        x: f32,
        y: f32,
    },
    SpawnToken(SpawnToken),
    CharacterCreated(usize),
    Quit {
        id: String,
    },
    Shutdown,
}

#[derive(Serialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub enum RequestError {
    InvalidRequest,
    AlreadyLoggedIn,
}
