import { MsgCall } from "tsrpc";
import { playerManager } from "../managers/PlayerManager";
import { MsgPlayerMove } from "../shared/protocols/MsgPlayerMove";
import { MsgReqMove } from "../shared/protocols/MsgReqMove";
import { broadcastToAll } from "../utils/broadcast";
import { clientToGamePosition, gameToClientPosition } from "../utils/coordinate";

/**
 * 移动消息处理器
 * 处理玩家移动请求，验证位置合法性，更新玩家位置并广播给其他玩家
 */
export default async function (call: MsgCall<MsgReqMove>) {
    const { x, y } = call.msg;

    // 从连接中获取玩家ID（需要在登录时保存）
    const playerId = (call.conn as any).playerId;

    if (!playerId) {
        call.conn.sendMsg('ResMove', {
            success: false,
            message: '未登录，请先登录'
        });
        return;
    }

    // 获取玩家信息
    const player = playerManager.getPlayer(playerId);

    if (!player) {
        call.conn.sendMsg('ResMove', {
            success: false,
            message: '玩家不存在'
        });
        return;
    }

    // 检查玩家是否存活
    if (!player.isAlive) {
        call.conn.sendMsg('ResMove', {
            success: false,
            message: '玩家已死亡，无法移动'
        });
        return;
    }

    // 验证坐标是否为数字
    if (typeof x !== 'number' || typeof y !== 'number') {
        call.conn.sendMsg('ResMove', {
            success: false,
            message: '坐标格式错误'
        });
        return;
    }

    // 验证坐标是否为整数
    if (!Number.isInteger(x) || !Number.isInteger(y)) {
        call.conn.sendMsg('ResMove', {
            success: false,
            message: '坐标必须为整数'
        });
        return;
    }

    // 将客户端坐标（放大1000倍）转换为游戏内坐标
    const gamePosition = clientToGamePosition({ x, y });

    try {
        // 尝试更新玩家位置（使用游戏内坐标）
        const success = playerManager.updatePlayerPosition(playerId, gamePosition.x, gamePosition.y);

        if (!success) {
            call.conn.sendMsg('ResMove', {
                success: false,
                message: '移动失败，位置无效或超出世界边界'
            });
            return;
        }

        // 获取更新后的位置（转换为客户端坐标）
        const newPosition = gameToClientPosition(gamePosition);
        // 广播移动消息给所有其他玩家（使用客户端坐标）
        const moveMsg: MsgPlayerMove = {
            playerId: player.id,
            playerName: player.name,
            position: newPosition,
            timestamp: Date.now()
        };

        broadcastToAll('PlayerMove', moveMsg, call.conn.id);

        // 返回成功结果
        call.conn.sendMsg('ResMove', {
            success: true,
            message: '移动成功',
            position: newPosition
        });

        console.log(`玩家 ${player.name} 移动到游戏内坐标 (${gamePosition.x}, ${gamePosition.y})，客户端坐标 (${newPosition.x}, ${newPosition.y})`);

    } catch (error) {
        console.error('移动失败:', error);
        call.conn.sendMsg('ResMove', {
            success: false,
            message: `移动失败: ${error instanceof Error ? error.message : '未知错误'}`
        });
    }
}