import { _decorator, Button, Color, Component, director, instantiate, Label, Node, Animation, Prefab, ProgressBar, sp, Sprite, SpriteFrame, Toggle, Vec3, RichText } from "cc";
import { areanMgr } from "../../AreanManager";
import { resLoader } from "db://assets/core_tgx/base/utils/ResLoader";
import { ModuleDef } from "db://assets/scripts/ModuleDef";
import { SectType as SectType, heroAttributeType, IBasicAttribute, IAreanPlayer } from "db://assets/module_basic/shared/protocols/public/arean/AreanTypeDef";
import { CommonFun } from "db://assets/module_arean/scripts/CommonFun";
import { iAttribute } from "../../../../module_basic/shared/protocols/public/arean/MsgAreanBattleReportPush";
import { AreanEvent, AreanNetMgr } from "../../AreanNetMgr";
import { MsgAreanAttrUpdatePush } from "../../../../module_basic/shared/protocols/public/arean/MsgAreanAttrUpdatePush";
import { commonFunction } from "../../../../core_tgx/base/utils/commonFunction";

const { ccclass, property } = _decorator;

@ccclass('DetailView')
export class DetailView extends Component {

    @property(Node)
    content_1_1: Node;

    @property(Node)
    heroBg: Node;

    @property(Node)
    content_1_2: Node;

    @property(Node)
    content_1_3: Node;


    @property(Label)
    attr_attack: Label;
    @property(Label)
    attr_attackSpeed: Label;
    @property(Label)
    attr_crit: Label;
    @property(Label)
    attr_spAttack: Label;
    @property(Label)
    attr_skillSpeed: Label;
    @property(Label)
    attr_buffAdd: Label;
    @property(Label)
    attr_defend: Label;
    @property(Label)
    attr_dodge: Label;
    @property(Label)
    attr_anger: Label;
    @property(Label)
    attr_spDefend: Label;
    @property(Label)
    attr_reflect: Label;
    @property(Label)
    attr_healAdd: Label;



    @property(Node)
    hpBar: Node;
    @property(Node)
    mpBar: Node;
    @property(Node)
    shieldBar: Node;

    @property(Node)
    spineNode: Node;


    @property(Prefab)
    attrTxt: Prefab;

    @property(Sprite)
    mainSkillIcon: Sprite;
    @property(Label)
    mainSkillName: Label;
    @property(RichText)
    mainSkillDesc: RichText;

    @property(Sprite)
    jobSkillIcon: Sprite;
    @property(Label)
    jobSkillName: Label;
    @property(RichText)
    jobSkillDesc: RichText;


    @property(Button)
    btnCardList: Button;

    @property(Node)
    equipList: Node;
    @property(Node)
    treasureList: Node;






    curData: IBasicAttribute = null;

    private _curSect: SectType = SectType.体质;

    start() {


        director.on(AreanEvent.AttrUpdate, this.updataAttrPush, this);



        try {
            let node = this.node.getChildByName("ToggleGroup");
            let toggle: Toggle = node.getChildByName(`Toggle${3}`).getComponent(Toggle);
            toggle.node.on('toggle', (target: Toggle) => {
                this.updateSect();
            }, this);
            this._initSectBtn();
        } catch (error) {
            console.warn("An error occurred:", error);
        }

    }


    public updateAttrForReport(data: iAttribute): void {

        let attrId: heroAttributeType = data.type;
        let value: number = data.value;

        switch (attrId) {
            case heroAttributeType.shields: {
                this.curData.shields = value;
                this.shieldBar.getComponent(ProgressBar).progress = value;
                this.shieldBar.getChildByName("value").getComponent(Label).string = `${value}`;
                break;
            }

            case heroAttributeType.hp: {
                this.curData.hp = value;
                this.hpBar.getComponent(ProgressBar).progress = value / this.curData.maxHp;
                this.hpBar.getChildByName("value").getComponent(Label).string = `${value}/${this.curData.maxHp}`;
                break;
            }

            case heroAttributeType.mp: {
                this.curData.mp = value;
                this.mpBar.getComponent(ProgressBar).progress = value / this.curData.maxMp;
                this.mpBar.getChildByName("value").getComponent(Label).string = `${value}/${this.curData.maxMp}`;
                break;
            }

            case heroAttributeType.maxHp: {
                this.curData.maxHp = value;
                this.hpBar.getComponent(ProgressBar).progress = this.curData.hp / value;
                this.hpBar.getChildByName("value").getComponent(Label).string = `${this.curData.hp}/${value}`;
                break;
            }

            case heroAttributeType.maxMp: {
                this.curData.maxMp = value;
                this.mpBar.getComponent(ProgressBar).progress = this.curData.mp / value;
                this.mpBar.getChildByName("value").getComponent(Label).string = `${this.curData.mp}/${value}`;
                break;

            }

            case heroAttributeType.attack: {
                this.curData.attack = value;
                this.attr_attack.string = value + "";
                break;
            }

            case heroAttributeType.spAttack: {
                this.curData.spAttack = value;
                this.attr_spAttack.string = value + "";
                break;

            }

            case heroAttributeType.skillSpeed: {
                this.curData.skillSpeed = value;
                this.attr_skillSpeed.string = value + "";
                break;
            }

            case heroAttributeType.buffAdd: {
                this.curData.buffAdd = value;
                this.attr_buffAdd.string = value + "";
                break;
            }

            case heroAttributeType.attackSpeed: {
                this.curData.attackSpeed = value;
                this.attr_attackSpeed.string = value + "";
                break;
            }

            case heroAttributeType.dodge: {
                this.curData.dodge = value;
                this.attr_dodge.string = value + "";
                break;
            }

            case heroAttributeType.anger: {
                this.curData.anger = value;
                this.attr_anger.string = value + "";
                break;
            }

            case heroAttributeType.reflect: {
                this.curData.reflect = value;
                this.attr_reflect.string = value + "";
                break;
            }

            case heroAttributeType.critical: {
                this.curData.critical = value;
                this.attr_crit.string = value + "";
                break;
            }


            case heroAttributeType.defend: {
                this.curData.defend = value;
                this.attr_defend.string = value + "";
                break;
            }

            case heroAttributeType.spDefend: {
                this.curData.spDefend = value;
                this.attr_spDefend.string = value + "";
                break;

            }

            case heroAttributeType.healAdd: {
                this.curData.healAdd = value;
                this.attr_healAdd.string = value + "";
                break;

            }


            default:
                break;

        }
        this.updateAddAttr();
    }

    updataAttrPush(attr: IBasicAttribute) {

        this.curData = AreanNetMgr.inst.playerMap[areanMgr.BattleView.getLocalPlayerData().playerId].attr;
        this.updateAttr(attr);
        this.updateAddAttr();

    }


    init(id: number) {
        console.log("init id", id);
        let heroData = areanMgr.cfgMgr.HeroDatas.getData(id);
        let skin = areanMgr.cfgMgr.SkinData.getData(heroData.skinRes[0]).icon;
        let imagePath = 'res/Spine/' + skin;
        let spAsset: sp.SkeletonData = resLoader.get(imagePath, sp.SkeletonData, ModuleDef.Arean);
        let ske = this.spineNode.getComponent(sp.Skeleton);
        ske.skeletonData = spAsset;
        //ske.setAnimation(0, "idle", true);

        let skillID = heroData.mainSkill[0];
        let skillData = areanMgr.cfgMgr.SkillPerformanceDatas.getData(skillID);
        this.mainSkillDesc.string = CommonFun.getInstance().HighlightNumbers(skillData.effectDescribe);
        this.mainSkillName.string = skillData.skillname;
        this.mainSkillIcon.spriteFrame = resLoader.getSpriteFrame("res/Image/icon/" + skillData.icon, ModuleDef.Arean);

        this.updataAttrPush(areanMgr.BattleView.getLocalPlayerData().attr);
    }



    updateCardNum() {
        let cardData = AreanNetMgr.inst.playerMap[areanMgr.BattleView.getLocalPlayerId()].cardList
        for (let i = 1; i <= 3; i++) {
            let countNode = this.btnCardList.node.getChildByPath("cardNode_" + i + "/count");
            countNode.getComponent(Label).string = CommonFun.getInstance().CalCardCount(i, cardData).toString();

        }
    }


    // 属性面板
    async updateAttr(attr: IBasicAttribute) {

        if (attr) {
            let attrData = AreanNetMgr.inst.playerMap[areanMgr.BattleView.getLocalPlayerData().playerId].attr;

            // // 创建一个新的字典来存储差值
            // let data: { [key: string]: number } = {};

            // // 遍历data字典
            // for (let key in attrData) {
            //     if (attrData.hasOwnProperty(key) && changeAdd.hasOwnProperty(key)) {
            //         // 计算差值并存储到新的字典中
            //         data[key] = attrData[key] - changeAdd[key];
            //     }
            // }

            this.attr_attack.string = attrData.attack + "";
            this.attr_attackSpeed.string = attrData.attackSpeed + "";
            this.attr_crit.string = attrData.critical + "";
            this.attr_spAttack.string = attrData.spAttack + "";
            this.attr_skillSpeed.string = attrData.skillSpeed + "";
            this.attr_buffAdd.string = attrData.buffAdd + "";
            this.attr_defend.string = attrData.defend + "";
            this.attr_dodge.string = attrData.dodge + "";
            this.attr_anger.string = attrData.anger + "";
            this.attr_spDefend.string = attrData.spDefend + "";
            this.attr_reflect.string = attrData.reflect + "";
            this.attr_healAdd.string = attrData.healAdd + "";

            this.shieldBar.getComponent(ProgressBar).progress = attrData.shields;
            this.hpBar.getComponent(ProgressBar).progress = attrData.hp / attrData.maxHp;
            this.mpBar.getComponent(ProgressBar).progress = attrData.mp / attrData.maxMp;
            this.shieldBar.getChildByName("value").getComponent(Label).string = `${attrData.shields}`;
            this.hpBar.getChildByName("value").getComponent(Label).string = `${attrData.hp}/${attrData.maxHp}`;
            this.mpBar.getChildByName("value").getComponent(Label).string = `${attrData.mp}/${attrData.maxMp}`;

            console.log(attr);
            for (let a in attr) {

                if (attr[a] != 0) {
                    this.AddBuff(heroAttributeType[a], attr[a], this.spineNode);
                    this.AddBuff(heroAttributeType[a], attr[a], areanMgr.BattleView.headIcon);
                    await new Promise(resolve => setTimeout(resolve, 200));
                }


            }
        }


    }


    // 属性面板
    updateAddAttr() {


        let data = this.curData;
        this.attr_attack.node.parent.getChildByName("valueAdd").getComponent(Label).string = "+" + data.attack;
        this.attr_attack.node.parent.getChildByName("valueAdd").active = false;
        this.attr_attackSpeed.node.parent.getChildByName("valueAdd").getComponent(Label).string = "(" + data.attackSpeed + "%)";
        this.attr_attackSpeed.node.parent.getChildByName("valueAdd").active = data.attackSpeed > 0;
        this.attr_crit.node.parent.getChildByName("valueAdd").getComponent(Label).string = "(" + data.critical + "%)";
        this.attr_crit.node.parent.getChildByName("valueAdd").active = data.critical > 0;
        this.attr_spAttack.node.parent.getChildByName("valueAdd").getComponent(Label).string = "+" + data.spAttack;
        this.attr_spAttack.node.parent.getChildByName("valueAdd").active = false;
        this.attr_skillSpeed.node.parent.getChildByName("valueAdd").getComponent(Label).string = "(" + data.skillSpeed + "%)";
        this.attr_skillSpeed.node.parent.getChildByName("valueAdd").active = data.skillSpeed > 0;
        this.attr_buffAdd.node.parent.getChildByName("valueAdd").getComponent(Label).string = "(" + data.buffAdd + "%)";
        this.attr_buffAdd.node.parent.getChildByName("valueAdd").active = data.buffAdd > 0;
        this.attr_defend.node.parent.getChildByName("valueAdd").getComponent(Label).string = "(" + data.defend + "%)";
        this.attr_defend.node.parent.getChildByName("valueAdd").active = false;
        this.attr_dodge.node.parent.getChildByName("valueAdd").getComponent(Label).string = "(" + data.dodge + "%)";
        this.attr_dodge.node.parent.getChildByName("valueAdd").active = data.dodge > 0;
        this.attr_anger.node.parent.getChildByName("valueAdd").getComponent(Label).string = "+" + data.anger;
        this.attr_anger.node.parent.getChildByName("valueAdd").active = false;
        this.attr_spDefend.node.parent.getChildByName("valueAdd").getComponent(Label).string = "(" + data.spDefend + "%)";
        this.attr_spDefend.node.parent.getChildByName("valueAdd").active = false;
        this.attr_reflect.node.parent.getChildByName("valueAdd").getComponent(Label).string = "(" + data.reflect * 3 + "%)";
        this.attr_reflect.node.parent.getChildByName("valueAdd").active = data.reflect > 0;
        this.attr_healAdd.node.parent.getChildByName("valueAdd").getComponent(Label).string = "+" + data.healAdd;
        this.attr_healAdd.node.parent.getChildByName("valueAdd").active = false;


    }


    AddBuff(attr: heroAttributeType, value: number, spine: Node) {

        if (this.attrTxt) {
            let damageNode = instantiate(this.attrTxt);
            spine.addChild(damageNode);
            damageNode.setPosition(new Vec3(0, 40, 0));
            damageNode.setScale(spine.getScale());
            let duffData = areanMgr.cfgMgr.BuffDatas.getData(attr);
            let text = duffData.name;

            if (value > 0) {
                damageNode.getComponent(Animation)?.play("buff");
                damageNode.getChildByName("buff")!.getComponent(Label)!.string = text + "+" + value;

            }
            else if (value < 0) {
                damageNode.getComponent(Animation)?.play("debuff");
                damageNode.getChildByName("debuff")!.getComponent(Label)!.string = text + "-" + Math.abs(value);

            }
            setTimeout(() => {

                damageNode.removeFromParent();
            }
                , 2000);

        }
    }



    /***************************************************************** 技能部分 ***********************************************/
    // 更新技能内容
    updateJobDetail(careerId: number): void {


        let careerData = areanMgr.cfgMgr.JobDatas.getData(careerId);
        if (careerData)
            this.jobSkillName.string = careerData.occupationName;
        this.jobSkillDesc.string = careerData.occupationDescribe;
        this.jobSkillIcon.spriteFrame = resLoader.getSpriteFrame(`res/Image/Job/${careerData.occupationIcon}`, ModuleDef.Arean)

    }

    /*********************** 羁绊*************************************/
    private _initSectBtn(): void {
        for (let i: number = 1; i <= 12; i++) {
            let toggle: Toggle = this.content_1_3.getChildByPath("ScrollView/ToggleGroup").getChildByName(`Toggle${i}`).getComponent(Toggle);
            let attr: { tag: SectType } = {
                tag: i
            }
            toggle.node.attr(attr);
            toggle.node.on('toggle', (target: Toggle) => {
                //@ts-ignore
                this._curSect = target.node.tag;
                this.updateSect();
            }, this);
        }
    }

    public updateSect(): void {
        const playerId = areanMgr.BattleView.getLocalPlayerId();
        const sectList = AreanNetMgr.inst.playerMap[playerId].sect;
        const count = CommonFun.getInstance().getSectCount(this._curSect, sectList);
        const curData = CommonFun.getInstance().getSectData(this._curSect);
        const node = this.content_1_3.getChildByName("descLayout");
        const targetCounts = [5, 10, 20]; // 定义目标数量常量

        for (let i = 0; i < curData.length; i++) {
            const _node = node.getChildByName(`desc-00${i + 1}`);
            const lab_1 = _node.getChildByName("Label-003").getComponent(Label);
            const lab_2 = _node.getChildByName("Label-001").getComponent(Label);
            lab_1.string = `${count}/${targetCounts[i]}`;
            lab_2.string = curData[i].desc;
        }

        // 设置未达到目标数量的文本颜色为灰色

        for (let i = 1; i <= 3; i++) {
            const _node = node.getChildByName(`desc-00${i}`);
            const lab_1 = _node.getChildByName("Label-003").getComponent(Label);
            const lab_2 = _node.getChildByName("Label-001").getComponent(Label);
            if (count < targetCounts[i - 1]) {
                lab_1.color = new Color(150, 150, 150, 255);
                lab_2.color = new Color(150, 150, 150, 255);
            } else {
                lab_1.color = new Color(255, 255, 255, 255);
                lab_2.color = new Color(255, 255, 255, 255);
                break;
            }
        }
    }

    updateEquipAndTreasure(data: IAreanPlayer) {
        // 装备
        let equipNode = this.equipList;
        let equipData = data.equipList;
        for (let i = 0; i < 4; i++) {
            let node = equipNode.getChildByName(`item_${i + 1}`);
            let equipId = equipData[i];
            if (equipId) {
                let equipLocalData = areanMgr.cfgMgr.EquipmentData.getData(equipId);
                let sp: SpriteFrame = resLoader.getSpriteFrame(`res/Image/Equip/${equipLocalData.icon}`, ModuleDef.Arean);
                if (sp) node.getComponent(Sprite).spriteFrame = sp;
                let count = node.getChildByName("count");
                count.getComponent(Label).string = "";
            }
        }

        // 圣物
        let relicNode = this.treasureList;
        let relicData = data.treasureList;
        for (let i = 0; i < 2; i++) {
            let node = relicNode.getChildByName(`item_${i + 1}`);
            let d = relicData[i];
            if (d) {
                let localData = areanMgr.cfgMgr.TreasureDatas.getData(d.id);
                let sp: SpriteFrame = resLoader.getSpriteFrame(`res/Image/Treasure/${localData.icon}`, ModuleDef.Arean);
                if (sp) node.getComponent(Sprite).spriteFrame = sp;
                let count = node.getChildByName("count");
                count.getComponent(Label).string = "";
            }
        }

    }


    showCardList() {
        const path = 'res/Prefebs/cardList';
        let sp: Prefab = resLoader.get(path, Prefab, ModuleDef.Arean);
        let node = instantiate(sp);
        areanMgr.BattleView.node.addChild(node);

        let list = node.getChildByPath("ScrollView/view/content");
        let item = list.children[0];
        let cardList = AreanNetMgr.inst.playerMap[areanMgr.BattleView.getLocalPlayerId()].cardList;

        const sortedCardList = cardList
            .filter(card => {
                const data = areanMgr.cfgMgr.CardDatas.getData(card.id);
                return data.show !== 1;
            })
            .sort((a, b) => {
                let dataA = areanMgr.cfgMgr.CardDatas.getData(a.id);
                let dataB = areanMgr.cfgMgr.CardDatas.getData(b.id);
                return dataB.cardRare - dataA.cardRare;
            });

        let cardMap = {}; // 用于跟踪已经实例化的卡牌

        for (let i = 0; i < sortedCardList.length; i++) {

            let cardId = sortedCardList[i];
            let data = areanMgr.cfgMgr.CardDatas.getData(cardId.id);
            if (data) {

                if (cardMap[cardId.id]) {
                    // 如果已经实例化了该卡牌,更新 count 组件
                    let countLabel = cardMap[cardId.id].getChildByName("count").getComponent(Label);
                    countLabel.string = parseInt(countLabel.string) + 1;
                } else {

                    // 如果没有实例化该卡牌,实例化一个新的卡牌
                    let cardItem = instantiate(item);
                    list.addChild(cardItem);


                    let sp: SpriteFrame = resLoader.getSpriteFrame("res/Image/cardRare/rare" + data.cardRare, ModuleDef.Arean);
                    if (sp) cardItem.getChildByName("rareBg").getComponent(Sprite).spriteFrame = sp;
                    sp = resLoader.getSpriteFrame("res/Image/skill/" + data.icon, ModuleDef.Arean);
                    if (sp) cardItem.getChildByPath("cardBg/mask/cardIcon").getComponent(Sprite).spriteFrame = sp;
                    cardItem.getChildByName("name").getComponent(Label).string = data.mainName;
                    cardItem.getChildByName("cardDesc").getComponent(RichText).string = CommonFun.getInstance().HighlightNumbers(data.skillDescribe);



                    cardItem.getChildByPath("types/type2").active = data.Sect.length == 2;
                    for (let i = 0; i < data.Sect.length; i++) {
                        let sp: SpriteFrame = resLoader.getSpriteFrame("res/Image/sect/sect" + data.Sect[i], ModuleDef.Arean);
                        if (sp) cardItem.getChildByPath("types").children[i].getChildByName("icon").getComponent(Sprite).spriteFrame = sp;
                    }

                    cardMap[cardId.id] = cardItem; // 将新实例化的卡牌添加到 cardMap 中
                }
            }

        }
        list.removeChild(item);


        node.getChildByName("btnClose").on("click", () => {
            node.removeFromParent();
        })
    }

    showEquipAndTreasureList() {
        const path = 'res/Prefebs/equipAndTreasureList';
        let sp: Prefab = resLoader.get(path, Prefab, ModuleDef.Arean);
        let node = instantiate(sp);
        areanMgr.BattleView.node.addChild(node);

        let list = node.getChildByPath("ScrollView/view/content");
        let item = list.children[0];
        let equipList = AreanNetMgr.inst.playerMap[areanMgr.BattleView.getLocalPlayerId()].equipList;

        for (let i = 0; i < equipList.length; i++) {

            let equipmentId = equipList[i];
            let data = areanMgr.cfgMgr.EquipmentData.getData(equipmentId);
            if (data) {
                let equipItem = instantiate(item);
                list.addChild(equipItem);
                let sp: SpriteFrame = resLoader.getSpriteFrame("res/Image/Equip/" + data.icon, ModuleDef.Arean);
                if (sp) equipItem.getChildByName("cardIcon").getComponent(Sprite).spriteFrame = sp;
                equipItem.getChildByName("name").getComponent(Label).string = data.name;
                equipItem.getChildByName("cardDesc").getComponent(RichText).string = CommonFun.getInstance().HighlightNumbers(data.describe);
            }
        }

        let treasureList = AreanNetMgr.inst.playerMap[areanMgr.BattleView.getLocalPlayerId()].treasureList;
        for (let i = 0; i < treasureList.length; i++) {

            let d = treasureList[i];
            let data = areanMgr.cfgMgr.TreasureDatas.getData(d.id);
            if (data) {
                let treasureItem = instantiate(item);
                list.addChild(treasureItem);
                let sp: SpriteFrame = resLoader.getSpriteFrame("res/Image/Treasure/" + data.icon, ModuleDef.Arean);
                if (sp) treasureItem.getChildByName("cardIcon").getComponent(Sprite).spriteFrame = sp;
                treasureItem.getChildByName("name").getComponent(Label).string = data.name;
                treasureItem.getChildByName("cardDesc").getComponent(RichText).string = CommonFun.getInstance().HighlightNumbers(data.describe);
            }

        }
        list.removeChild(item);


        node.getChildByName("btnClose").on("click", () => {
            node.removeFromParent();
        })


    }



}