import { _decorator, Component, Node, EventKeyboard, KeyCode, Input, input, Vec3 } from 'cc';
import { NetManager } from '../../Framework/Net/NetManager';
import { ReqMove, ResMove } from '../../Shared/protocols/PtlMove';
import { PlayerInfo } from '../../Shared/protocols/PtlLogin';
import { RoleController } from '../../CC/RoleController';

const { ccclass } = _decorator;

/**
 * PlayerController 本地玩家控制器
 * 负责处理本地玩家的输入、移动和动画
 */
@ccclass('PlayerController')
export class PlayerController extends Component {
    /** 玩家信息 */
    private playerInfo: PlayerInfo = null;

    /** 角色控制器(控制动画) */
    private roleController: RoleController = null;

    /** 移动速度 */
    private moveSpeed: number = 5;

    /** 当前移动方向 */
    private moveDirection: Vec3 = new Vec3(0, 0, 0);

    /** 按键状态 */
    private keyStates: Map<KeyCode, boolean> = new Map();

    /** 是否正在移动 */
    private isMoving: boolean = false;

    /** 上次发送移动请求的位置 */
    private lastSentPosition: Vec3 = new Vec3();

    /** 移动阈值(超过这个距离才发送移动请求) */
    private moveSendThreshold: number = 0.5;

    /**
     * 初始化玩家控制器
     */
    public init(playerInfo: PlayerInfo): void {
        this.playerInfo = playerInfo;
        this.lastSentPosition.set(playerInfo.position.x, 0, playerInfo.position.y);

        // 获取 RoleController 组件
        this.roleController = this.node.getComponentInChildren(RoleController);
        if (!this.roleController) {
            console.warn('[PlayerController] 未找到 RoleController 组件');
        } else {
            // 初始播放待机动画
            this.roleController.PlayAnimation('idle', true);
        }

        console.log('[PlayerController] 初始化完成:', playerInfo.name);
    }

    protected onEnable(): void {
        // 注册键盘事件
        input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
        input.on(Input.EventType.KEY_UP, this.onKeyUp, this);
    }

    protected onDisable(): void {
        // 取消注册键盘事件
        input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this);
        input.off(Input.EventType.KEY_UP, this.onKeyUp, this);
    }

    /**
     * 键盘按下事件
     */
    private onKeyDown(event: EventKeyboard): void {
        this.keyStates.set(event.keyCode, true);
    }

    /**
     * 键盘抬起事件
     */
    private onKeyUp(event: EventKeyboard): void {
        this.keyStates.set(event.keyCode, false);
    }

    protected update(dt: number): void {
        // 计算移动方向
        this.updateMoveDirection();

        // 如果有移动方向,移动角色
        if (this.moveDirection.lengthSqr() > 0) {
            this.move(dt);
        } else {
            // 没有移动,播放待机动画
            if (this.isMoving) {
                this.isMoving = false;
                if (this.roleController) {
                    this.roleController.PlayAnimation('idle', true);
                }
            }
        }
    }

    /**
     * 更新移动方向
     */
    private updateMoveDirection(): void {
        this.moveDirection.set(0, 0, 0);

        // W - 向前
        if (this.keyStates.get(KeyCode.KEY_W)) {
            this.moveDirection.z -= 1;
        }
        // S - 向后
        if (this.keyStates.get(KeyCode.KEY_S)) {
            this.moveDirection.z += 1;
        }
        // A - 向左
        if (this.keyStates.get(KeyCode.KEY_A)) {
            this.moveDirection.x -= 1;
        }
        // D - 向右
        if (this.keyStates.get(KeyCode.KEY_D)) {
            this.moveDirection.x += 1;
        }

        // 归一化移动方向
        if (this.moveDirection.lengthSqr() > 0) {
            this.moveDirection.normalize();
        }
    }

    /**
     * 移动角色
     */
    private move(dt: number): void {
        // 计算移动增量
        const moveOffset = this.moveDirection.clone().multiplyScalar(this.moveSpeed * dt);
        
        // 更新节点位置
        const currentPos = this.node.position.clone();
        currentPos.add(moveOffset);
        this.node.setPosition(currentPos);

        // 更新朝向(让角色面向移动方向)
        if (this.moveDirection.lengthSqr() > 0) {
            const targetAngle = Math.atan2(this.moveDirection.x, -this.moveDirection.z) * (180 / Math.PI);
            this.node.setRotationFromEuler(0, targetAngle, 0);
        }

        // 播放移动动画
        if (!this.isMoving) {
            this.isMoving = true;
            if (this.roleController) {
                this.roleController.PlayAnimation('move', true);
            }
        }

        // 检查是否需要发送移动请求
        this.checkSendMoveRequest(currentPos);
    }

    /**
     * 检查是否需要发送移动请求
     */
    private checkSendMoveRequest(currentPos: Vec3): void {
        const distance = Vec3.distance(currentPos, this.lastSentPosition);
        
        // 如果移动距离超过阈值,发送移动请求
        if (distance >= this.moveSendThreshold) {
            this.sendMoveRequest(currentPos.x, currentPos.z);
            this.lastSentPosition.set(currentPos);
        }
    }

    /**
     * 发送移动请求到服务器
     */
    private async sendMoveRequest(x: number, z: number): Promise<void> {
        try {
            const netManager = NetManager.getInstance();
            const result = await netManager.callApi<ReqMove, ResMove>('Move', {
                x: x,
                y: z
            });

            if (!result) {
                console.error('[PlayerController] 移动请求失败');
                return;
            }

            // 服务器可能会修正位置,使用服务器返回的位置
            if (result.position) {
                const serverPos = result.position;
                this.node.setPosition(serverPos.x, 0, serverPos.y);
                this.lastSentPosition.set(serverPos.x, 0, serverPos.y);
            }
        } catch (error) {
            console.error('[PlayerController] 发送移动请求异常:', error);
        }
    }

    /**
     * 获取玩家信息
     */
    public getPlayerInfo(): PlayerInfo {
        return this.playerInfo;
    }
}
