use std::{error::Error, rc::Rc};

use common::net::tools::Packet;
use prost::Message;
use proto::{CombatTypeArgument, EntityMoveInfo};

use crate::player::Player;

use super::{get_proto, scene_handler};

pub fn on_combat_invocations_notify(
    player: &Rc<Player>,
    packet: Packet,
) -> Result<(), Box<dyn Error>> {
    let notify = get_proto!(packet, CombatInvocationsNotify);

    for entry in notify.invoke_list {
        match entry.argument_type() {
            CombatTypeArgument::EntityMove => {
                let Ok(entity_move_info) = EntityMoveInfo::decode(&*entry.combat_data) else {
                    tracing::warn!("combat invoke type: proto::EntityMoveInfo fail to parse, len:{}, base64:{}, player:{}", entry.combat_data.len(), rbase64::encode(&*entry.combat_data), player.uid);
                    return Ok(());
                };

                let (cur_scene, cur_avatar) = {
                    (
                        player
                            .player_scene_comp
                            .borrow()
                            .get_cur_scene()
                            .unwrap()
                            .clone(),
                        player
                            .player_avatar_comp
                            .borrow()
                            .get_cur_avatar()
                            .unwrap()
                            .clone(),
                    )
                };

                let mut sync_uid_vec = Vec::new();
                if let Err(ret) = scene_handler::process_entity_move_info(
                    cur_scene,
                    player,
                    cur_avatar,
                    &entity_move_info,
                    &mut sync_uid_vec,
                ) {
                    tracing::warn!("process_entity_move_info fails, ret:{ret:?}");
                }
            }
            unhandled => tracing::warn!(
                "wrong combat type, player:{}, type:{unhandled:?}",
                player.uid,
            ),
        }
    }

    Ok(())
}
