use std::error::Error;

use common::{
    config::IpString,
    net::{tools::Packet, AServerSession, NetError},
};
use proto::CmdID;

use crate::{gameserver_service, handler::login_handler};

pub struct GateserverSession {
    _server_session: AServerSession,
}

impl GateserverSession {
    pub async fn new(app_id: u32, service_ip: IpString, cur_app_id: u32) -> Result<Self, NetError> {
        Ok(Self {
            _server_session: AServerSession::new(app_id, service_ip, cur_app_id),
        })
    }

    pub async fn on_recv(&self, packet: Packet) -> Result<(), Box<dyn Error>> {
        match packet.cmd_id {
            proto::PlayerLoginReq::CMD_ID => login_handler::on_player_login_req(packet).await,
            proto::PlayerForceExitReq::CMD_ID => {
                login_handler::on_player_force_exit_req(packet).await
            }
            _ => {
                let Some(session) = gameserver_service()
                    .player_sessions
                    .get(&packet.head.user_id)
                else {
                    tracing::warn!("user_session_id: {} not found", packet.head.user_session_id);
                    return Ok(());
                };

                if let Some(player_coroutine) = session.exec_coroutine.read().as_ref() {
                    player_coroutine.push_packet(packet);
                }

                Ok(())
            }
        }
    }
}
