import { gameMethod } from "../../common/gameMethod";
import { BattleTeamId, FightType } from "../../data/const/TypeConst";
import GameDataCenter from "../../data/GameDataCenter";
import UEBase from "../../frameWork/compment/UEBase";
import { eg } from "../../frameWork/eg";
import { ActionType, FightBase, fightLogOne, FightStart } from "../../shared/base";
import AssetMgr from "../../utils/AssetMgr";
import { BattleGridConstant } from "./BattleGridConstant";
import UEBattleRole from "./UEBattleRole";

const { ccclass, property } = cc._decorator;

@ccclass
export default class UEBattleView extends UEBase {
    @property(cc.Prefab)
    rolePrefab: cc.Prefab = null;
    @property(cc.Prefab)
    subHpPrefab: cc.Prefab = null;
    @property(cc.Prefab)
    cellPrefab: cc.Prefab = null!;
    @property(cc.Node)
    roleContent: cc.Node = null;
    @property(cc.Node)
    hpLayer: cc.Node = null
    @property(cc.Node)
    cellLayer: cc.Node = null;

    fightStart: FightStart;
    fightLogList: {
        //战斗日志列表
        //回合ID：单回合内战斗日志
        [huihe: string]: fightLogOne[];
    };

    static readonly BundleKey: string = "battle";
    static readonly PrefabUrl: string = "UEBattleView";
    static readonly CLS: string = "UEBattleView";
    type: FightType;
    huihe: number;
    curIndex: number;
    static s_ins: UEBattleView;
    TxtRound: cc.Label;

    static getInstance() {
        return this.s_ins
    }

    Init() {
        UEBattleView.s_ins = this;
        this.TxtRound = this.node.getChildByName("ImgDi").getChildByName("TxtRound").getComponent(cc.Label);
        this.initEvent();
        this.LoadCell();
    }
    initEvent(): void {

    }
    //关闭界面
    onDisable(): void {
        this.node.destroy();
    }
    /** 加载地图数据 */
    private LoadCell() {
        for (let i = 0; i < BattleGridConstant.COL; i++) {
            for (let j = 0; j < BattleGridConstant.ROW; j++) {
                this.CreateCell(i, j);
            }
        }
    }
    /** 创建格子 */
    private CreateCell(i: number, j: number) {
        let cell = cc.instantiate(this.cellPrefab);
        this.cellLayer.addChild(cell);
        cell.width = BattleGridConstant.CELL_WIDTH;
        cell.height = BattleGridConstant.CELL_HEIGHT;
        let pos = this.GetPosByIdx(i, j);
        cell.setPosition(pos);
        cell.name = `${(i + 1) * 10 + (j + 1)}`;
        cell.getChildByName("txtIndex").getComponent(cc.Label).string = `${(i + 1) * 10 + (j + 1)}`;
        return cell;
    }
    /** 根据索引获取实际像素坐标 */
    private GetPosByIdx(i: number, j: number): cc.Vec3 {
        const startX = -(BattleGridConstant.ROW * BattleGridConstant.CELL_WIDTH) / 2;
        const startY = (BattleGridConstant.COL * BattleGridConstant.CELL_HEIGHT) / 2;
        return cc.v3(
            startX + j * BattleGridConstant.CELL_WIDTH + BattleGridConstant.CELL_WIDTH / 2,
            startY - i * BattleGridConstant.CELL_HEIGHT - BattleGridConstant.CELL_HEIGHT / 2
        )
    }
    /** 获取扣血飘字表现层 */
    GetHpLayer() {
        return this.hpLayer;
    }
    /** 获取扣血飘字预制体 */
    GetSubHpPrefab() {
        return this.subHpPrefab;
    }
    //开始战斗
    async onStartFight(fightInfo: FightBase) {
        GameDataCenter.battle.setFightInfo(fightInfo); //设置战斗数据
        eg.poolManager.GetPool("subHPPool").clear();
        this.huihe = 1;
        this.curIndex = 0;
        this.fightStart = GameDataCenter.battle.fightInfo?.fightStart;
        this.fightLogList = GameDataCenter.battle.fightInfo?.log;
        await this.produceRole();
        this.playLog();
    }
    async produceRole() {
        //生产角色
        let fightType: FightType = this.type;
        let teams = this.fightStart?.teams;
        if (gameMethod.isEmpty(teams)) {
            console.error("teams is empty");
            return;
        }
        for (const key in teams) {
            if (Object.prototype.hasOwnProperty.call(teams, key)) {
                let teamInfo = teams[key];
                let roleNode = AssetMgr.instantiate(this.cellLayer, this.rolePrefab);
                let pos = this.cellLayer.getChildByName(teamInfo?.seat?.toString())?.position;
                roleNode.getComponent(UEBattleRole).setRole(pos, teamInfo, fightType);
                roleNode.scale = 0.6;
                roleNode.scaleX = pos.x > 0 ? roleNode.scale * -1 : roleNode.scale * 1;
                GameDataCenter.battle.addRole(key, roleNode.getComponent(UEBattleRole));
            }
        }
    }
    //播放战斗日志
    playLog() {
        this.TxtRound.string = "第" + this.huihe + "回合";
        let curLog = this.fightLogList?.[this.huihe]?.[this.curIndex];
        // console.error("curLog:", curLog)
        let actionType: ActionType = curLog.aType;
        switch (actionType) {
            case ActionType.round:
            case ActionType.buff:
                this.nextLog();
                break;
            case ActionType.atk:
                this.playAtk(curLog);
                break;
            // case ActionType.skill:
            //     this.playAtk(curLog);
            //     break;
            case ActionType.over:
                this.nextLog();
                break;

            default:
                break;
        }
    }
    //播放下一条日志
    nextLog() {
        this.curIndex++;
        if (this.fightLogList?.[this.huihe]?.[this.curIndex] == null) {
            this.huihe++;
            if (this.fightLogList?.[this.huihe] != null) {
                this.curIndex = 0;
                this.playLog();
            } else {
                this.scheduleOnce(() => {
                    console.log("战斗结束");
                }, 1);
            }
        } else {
            this.playLog();
        }
    }

    playAtk(curLog: fightLogOne) {
        let atker = GameDataCenter.battle.battleRoleList[curLog.atker.iid];
        let target0 = curLog.target.length > 0 ? GameDataCenter.battle.battleRoleList[curLog.target[0].iid]
            : Object.values(GameDataCenter.battle.battleRoleList)[0] //没有target 默认取一个防错
        let delay = 0.5;
        let hitPos = this.cellLayer.getChildByName(curLog?.seat?.toString())?.position;
        cc.tween(atker.node)
            .delay(0.15 / GameDataCenter.battle.realBattleSpeed)
            .to(delay / GameDataCenter.battle.realBattleSpeed, { x: hitPos.x, y: hitPos.y })
            .call(() => {
                atker.playAni("atk1", false);
                // GameDataCenter.audio.playEffect(atker.atkAudio);
            })
            .delay((delay + 0.3) / GameDataCenter.battle.realBattleSpeed)
            .call(() => {
                //飘血
                console.log("curLog.target:", curLog.target);
                for (let i = 0; i < curLog.target.length; i++) {
                    let target = curLog.target[i];
                    let trgetNode = GameDataCenter.battle.battleRoleList[target?.iid]
                    let effectList = target?.effect;
                    for (let i = 0; i < effectList?.length; i++) {
                        let effect = effectList[i];
                        console.log("effect:", effect);
                        trgetNode.ShowSubHp(effect);
                    }
                }
            })
            .delay(0.1 / GameDataCenter.battle.realBattleSpeed)
            .call(() => {
                //显示特效以及连击等特殊效果
            })
            .delay(0.1 / GameDataCenter.battle.realBattleSpeed)
            .call(() => {
                atker.playAni("walk", true);
                // GameDataCenter.audio.playEffect(atker.atkAudio);
            })
            .to(delay / GameDataCenter.battle.realBattleSpeed, { x: atker.posX, y: atker.posY })//回到初始位置
            .call(() => {
                atker.playAni("stand", true);
                let atkerEffectList = curLog.atker?.effect;
                for (let i = 0; i < atkerEffectList?.length; i++) {
                    let effect = atkerEffectList[i];
                    console.log("atkerEffect:", effect);
                    atker.ShowSubHp(effect);
                }
                // GameDataCenter.audio.playEffect(atker.atkAudio);
            })
            .delay(0.3 / GameDataCenter.battle.realBattleSpeed)
            .call(() => {
                this.nextLog();
            })
            .start();
    }
}
