use crate::StateTransition;
use crate::context::Context;
use crate::font::FontSize;
use crate::screen::Screen;
use macroquad::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize)]
pub struct JoinMessage {
    pub game_code: String,
    pub user_id: u64,
    pub token: String,
}

#[derive(Debug, Serialize)]
#[serde(tag = "type")]
pub enum NewUserClientMessages {
    JoinAsPlayer(JoinMessage),
    JoinAsHost(JoinMessage),
}

#[derive(Debug, Deserialize)]
#[serde(tag = "type")]
pub enum NewUserServerMessages {
    RegisterResponse,
    HostRegisterResponse,
}

#[derive(Default)]
pub struct LoginScreen {
    sent_join: bool,
    retry_time: f64,
}

impl Screen for LoginScreen {
    fn handle_frame(&mut self, ctx: &mut Context) {
        clear_background(BEIGE);

        draw_text(
            "Starting up...",
            screen_width() * 0.5,
            screen_height() * 0.5,
            FontSize::Large.size() as f32,
            BLACK,
        );

        if !self.sent_join {
            self.sent_join = true;

            let join_msg = JoinMessage {
                game_code: ctx.game_code.clone(),
                user_id: ctx.user_id,
                token: ctx.token.clone(),
            };

            let msg = match ctx.client_type {
                crate::cfg::ClientType::Host => NewUserClientMessages::JoinAsHost(join_msg),
                crate::cfg::ClientType::Player => NewUserClientMessages::JoinAsPlayer(join_msg),
            };

            info!("Sending join request...");
            ctx.send_msg(&msg);
            self.retry_time = get_time() + 2.0;
        }
    }

    fn handle_messages(&mut self, ctx: &mut Context) -> Option<StateTransition> {
        if self.sent_join {
            let msg = ctx.recv_msg();

            if let Some(msg) = msg {
                match msg {
                    NewUserServerMessages::RegisterResponse => {
                        return Some(StateTransition::JoinAsPlayer);
                    }
                    NewUserServerMessages::HostRegisterResponse => {
                        return Some(StateTransition::JoinAsHost);
                    }
                }
            }

            if get_time() > self.retry_time {
                warn!("Join failed, try again...");
                self.sent_join = false;
            }
        }

        None
    }
}
