import { Node, Vec3, instantiate, Prefab } from 'cc';
import { NetManager } from '../../Framework/Net/NetManager';
import { ResMgr } from '../../Framework/ResMgr/ResMgr';
import { MsgPlayerJoin } from '../../Shared/protocols/MsgPlayerJoin';
import { MsgPlayerMove } from '../../Shared/protocols/MsgPlayerMove';
import { PlayerInfo } from '../../Shared/protocols/PtlLogin';
import { PlayerController } from './PlayerController';
import { RemotePlayer } from './RemotePlayer';

/**
 * World 世界管理器
 * 负责管理游戏世界中的所有玩家
 * 包括本地玩家和远程玩家的创建、更新和销毁
 */
export class World {
    private static instance: World = null;

    /** 世界根节点 */
    private worldRoot: Node = null;

    /** 本地玩家信息 */
    private localPlayer: PlayerInfo = null;

    /** 本地玩家控制器 */
    private localPlayerController: PlayerController = null;

    /** 本地玩家节点 */
    private localPlayerNode: Node = null;

    /** 远程玩家列表 Map<playerId, RemotePlayer> */
    private remotePlayers: Map<string, RemotePlayer> = new Map();

    /** 玩家模型预制体 */
    private playerPrefab: Prefab = null;

    private constructor() {}

    public static getInstance(): World {
        if (!World.instance) {
            World.instance = new World();
        }
        return World.instance;
    }

    /**
     * 初始化世界
     * @param worldRoot 世界根节点
     * @param localPlayer 本地玩家信息
     */
    public async init(worldRoot: Node, localPlayer: PlayerInfo): Promise<void> {
        this.worldRoot = worldRoot;
        this.localPlayer = localPlayer;

        // 加载玩家模型预制体
        await this.loadPlayerPrefab();

        // 注册网络消息监听
        this.registerNetworkListeners();

        // 创建本地玩家
        await this.createLocalPlayer();

        console.log('[World] 世界初始化完成');
    }

    /**
     * 加载玩家模型预制体
     */
    private async loadPlayerPrefab(): Promise<void> {
        try {
            this.playerPrefab = await ResMgr.getInstance().load('resources', 'res://Actor/M1/M1', Prefab);
            console.log('[World] 玩家模型预制体加载成功');
        } catch (error) {
            console.error('[World] 加载玩家模型预制体失败:', error);
        }
    }

    /**
     * 注册网络消息监听
     */
    private registerNetworkListeners(): void {
        const netManager = NetManager.getInstance();

        // 监听玩家加入消息
        netManager.listenMsg('PlayerJoin', (msg: MsgPlayerJoin) => {
            this.onPlayerJoin(msg);
        });

        // 监听玩家移动消息
        netManager.listenMsg('PlayerMove', (msg: MsgPlayerMove) => {
            this.onPlayerMove(msg);
        });

        console.log('[World] 网络消息监听注册完成');
    }

    /**
     * 创建本地玩家
     */
    private async createLocalPlayer(): Promise<void> {
        if (!this.playerPrefab) {
            console.error('[World] 玩家模型预制体未加载');
            return;
        }

        // 实例化玩家节点
        this.localPlayerNode = instantiate(this.playerPrefab);
        this.localPlayerNode.name = `Player_${this.localPlayer.id}_Local`;
        this.localPlayerNode.setPosition(this.localPlayer.position.x, 0, this.localPlayer.position.y);
        this.worldRoot.addChild(this.localPlayerNode);

        // 创建本地玩家控制器
        this.localPlayerController = this.localPlayerNode.addComponent(PlayerController);
        this.localPlayerController.init(this.localPlayer);

        console.log('[World] 本地玩家创建完成:', this.localPlayer.name);
    }

    /**
     * 处理玩家加入消息
     */
    private onPlayerJoin(msg: MsgPlayerJoin): void {
        console.log('[World] 玩家加入:', msg.playerName);

        // 如果是本地玩家,不处理
        if (msg.playerId === this.localPlayer.id) {
            return;
        }

        // 创建远程玩家
        this.createRemotePlayer(msg);
    }

    /**
     * 创建远程玩家
     */
    private async createRemotePlayer(msg: MsgPlayerJoin): Promise<void> {
        if (!this.playerPrefab) {
            console.error('[World] 玩家模型预制体未加载');
            return;
        }

        // 检查是否已存在
        if (this.remotePlayers.has(msg.playerId)) {
            console.warn('[World] 远程玩家已存在:', msg.playerId);
            return;
        }

        // 实例化玩家节点
        const playerNode = instantiate(this.playerPrefab);
        playerNode.name = `Player_${msg.playerId}_Remote`;
        playerNode.setPosition(msg.position.x, 0, msg.position.y);
        this.worldRoot.addChild(playerNode);

        // 创建远程玩家控制器
        const remotePlayer = new RemotePlayer();
        remotePlayer.init(playerNode, msg.playerId, msg.playerName, msg.position);

        this.remotePlayers.set(msg.playerId, remotePlayer);

        console.log('[World] 远程玩家创建完成:', msg.playerName);
    }

    /**
     * 处理玩家移动消息
     */
    private onPlayerMove(msg: MsgPlayerMove): void {
        // 如果是本地玩家,不处理
        if (msg.playerId === this.localPlayer.id) {
            return;
        }

        // 更新远程玩家位置
        const remotePlayer = this.remotePlayers.get(msg.playerId);
        if (remotePlayer) {
            remotePlayer.updatePosition(msg.position);
        }
    }

    /**
     * 获取本地玩家控制器
     */
    public getLocalPlayerController(): PlayerController {
        return this.localPlayerController;
    }

    /**
     * 销毁世界
     */
    public destroy(): void {
        // 注意: TSRPC 的 listenMsg 不提供取消监听的方法
        // 在实际使用中,监听会在连接断开时自动清除

        // 销毁本地玩家
        if (this.localPlayerNode) {
            this.localPlayerNode.destroy();
            this.localPlayerNode = null;
        }
        this.localPlayerController = null;

        // 销毁所有远程玩家
        this.remotePlayers.forEach((remotePlayer) => {
            remotePlayer.destroy();
        });
        this.remotePlayers.clear();

        // 释放资源
        if (this.playerPrefab) {
            ResMgr.getInstance().release('resources', 'res://Actor/M1/M1');
            this.playerPrefab = null;
        }

        this.worldRoot = null;
        this.localPlayer = null;

        console.log('[World] 世界已销毁');
    }

    /**
     * 清理单例
     */
    public static clear(): void {
        if (World.instance) {
            World.instance.destroy();
            World.instance = null;
        }
    }
}
