import FqLogin from "../../../login/FqLogin";
import CMath from "../../../util/CMath";
import FF from "../FF";
import { GroupType } from "../object/FObject";
import FSprite, { SpriteActionType } from "../object/FSprite";
import FDialogMonster from "./FDialogMonster";
import WOneByone from "./map1/WOneByone";

/**
 * 激活怪物
 * 栅栏事件
 */
const { ccclass, property } = cc._decorator;

@ccclass
export default class FFenceTrigger extends cc.Component {
    /**
     * 伙伴初始化区域
     */
    @property({
        type: cc.Node,
        displayName: '远程初始位置'
    })
    mInitA: cc.Node = null;
    /**
     * 伙伴初始化区域
     */
    @property({
        type: cc.Node,
        displayName: '近战初始位置'
    })
    mInitB: cc.Node = null;
    /**
     * 伙伴初始化区域
     */
    @property({
        type: cc.Node,
        displayName: '摄像机移动的目标位置'
    })
    mCameraPos: cc.Node = null;
    /**
     * 怪物出现动画
     */
    @property({
        type: cc.Prefab,
        displayName: '怪物出现动画'
    })
    mAppear: cc.Prefab = null;
    /**
     * 控制的栅栏
     */
    @property([cc.Node])
    mFenceTrigger: Array<cc.Node> = [];
    /**
     * 需要消灭的怪物1
     */
    @property([FSprite])
    mMonster1: Array<FSprite> = [];
    /**
     * 需要消灭的怪物2
     */
    @property([FSprite])
    mMonster2: Array<FSprite> = [];
    /**
     * 需要消灭的怪物3
     */
    @property([FSprite])
    mMonster3: Array<FSprite> = [];
    /**
     * 需要消灭的怪物4
     */
    @property([FSprite])
    mMonster4: Array<FSprite> = [];
    /**
     * 需要消灭的怪物5
     */
    @property([FSprite])
    mMonster5: Array<FSprite> = [];

    /**
     * 控制的栅栏
     */
    @property({
        type: cc.Node,
        displayName: '结束后开启的栅栏'
    })
    mFenceTrigger2: Array<cc.Node> = [];

    @property(cc.Prefab)
    mMapDialog: cc.Prefab = null;

    @property([cc.String])
    text: Array<string> = [];

    @property({
        displayName: '是否开始就显示boss'
    })
    isBoss = false;

    @property({
        displayName: '倒计时时间'
    })
    countDown = -1;

    public ff: FF;
    private isOver = false;

    private mIndex = 0
    /**
     * 怪物分组
     */
    private groupMonster: Array<Array<FSprite>> = []

    private mMonster: Array<FSprite> = null

    onLoad() {
        this.groupMonster.push(this.mMonster1)
        if (this.mMonster2.length > 0) {
            this.groupMonster.push(this.mMonster2)
        }
        if (this.mMonster3.length > 0) {
            this.groupMonster.push(this.mMonster3)
        }

        if (this.mMonster4.length > 0) {
            this.groupMonster.push(this.mMonster4)
        }
        if (this.mMonster5.length > 0) {
            this.groupMonster.push(this.mMonster5)
        }
    }
    start() {
        for (let i = 0; i < this.groupMonster.length; i++) {
            const element: Array<FSprite> = this.groupMonster[i];
            for (let j = 0; j < element.length; j++) {
                const monster = element[j];
                monster.isActive = false
                if (i > 0) {
                    monster.node.active = false
                }
            }
        }
        this.mMonster = this.groupMonster[0]
    }

    onBeginContact(contact: cc.PhysicsContact, selfCollider: cc.PhysicsCollider, otherCollider: cc.PhysicsCollider) {
        if (this.isOver) {
            return;
        }
        if (otherCollider.node.group == 'A') {//主角踩到机关
            let obj = otherCollider.node.getComponent(FSprite);
            this.ff = obj.ff;
            if (obj == this.ff.mainSprite) {
                this.node.removeComponent(cc.PhysicsBoxCollider);
                this.node.removeComponent(cc.PhysicsBoxCollider);
                this.ff = obj.ff;

                this.ff.regRemoveCallback((f: FSprite) => {
                    this.removeCallback(f);
                });
                this.isOver = true;
                this.startFight();

                FqLogin.commitEvent(this.node.name, '', '')
            }
        }
    }
    /**
     * 开始战斗
     */
    private startFight() {
        this.ff.pauseSprite(true);
        this.moveCamera(this.node, () => {
            this.dialog(0);
        })
    }
    private dialog(index: number) {
        if (index >= this.text.length) {
            this.startFight1();
            return;
        }
        let texts = this.text[index].split('|')
        let mid = parseInt(texts.shift());
        if (mid == -1) {//主角

            let my = this.ff.mainSprite.node;
            this.showDialog(my, texts, () => {
                index++;
                this.dialog(index);
            });
        } else {
            let my = this.mMonster[mid].node;
            this.showDialog(my, texts, () => {
                index++;
                this.dialog(index);
            });
        }

    }
    private showDialog(my: cc.Node, dialogs, fCallback: () => void) {
        this.ff.mBlockInputEvents.active = true;
        let node = cc.instantiate(this.mMapDialog);
        node.group = 'map'
        node.zIndex = 9999;
        node.x = my.x;
        node.y = my.y + my.height;
        node.parent = this.ff.mMap.mSprites;
        let obo = node.getComponent(WOneByone);

        obo.dialogs = dialogs;
        obo.setCallback(() => {
            node.destroy();
            this.ff.setBlockInputCallback(null);

            fCallback();
        });
        this.ff.setBlockInputCallback(() => {
            obo.jump();
        });
        obo._start();
    }

    private startFight1() {
        this.addMark();
        // this.moveTo();
        if (this.isBoss) {
            this.ff.flushHP(this.mMonster[0]);
        }
        if (this.countDown != -1) {
            this.ff.mCountDown.startCountDown(this.countDown);
        }
        cc.tween(this).sequence(
            cc.delayTime(0.6),
            cc.callFunc(() => {
                this.playSkill(1);
                this.playSkill(2);
                this.playSkill(3);
            }),
            cc.delayTime(1.5),
            cc.callFunc(() => {
                this.ff.pauseSprite(false);
                this.ff.mBlockInputEvents.active = false;

                for (let i = 0; i < this.mFenceTrigger.length; i++) {
                    const element = this.mFenceTrigger[i];
                    element.active = true;

                    let nodes = element.children;
                    nodes.forEach(tmp => {
                        let spine = tmp.getComponent(sp.Skeleton);
                        if (spine) {
                            spine.setAnimation(0, 'close', false);
                        }
                    });
                }
                for (let i = 0; i < this.mMonster.length; i++) {
                    const element = this.mMonster[i];
                    element.isActive = true;
                }
            }),
        ).start()
    }
    //添加怪物标记
    private addMark() {
        for (let i = 0; i < this.mMonster.length; i++) {
            const element = this.mMonster[i];
            let node = element.addActiveIcon();
            this.actionMark(node);
        }
    }

    private actionMark(node: cc.Node) {
        node.scale = 0;
        cc.tween(node).sequence(
            cc.delayTime(1),
            cc.scaleTo(0.2, 1.2, 1.2),
            cc.scaleTo(0.2, 0.9, 0.9),
            cc.scaleTo(0.2, 1.1, 1.1),
            cc.scaleTo(0.2, 0.9, 0.9),
            cc.scaleTo(0.2, 1.1, 1.1),
            cc.scaleTo(0.2, 1, 1),
            cc.blink(1, 3),
            cc.fadeOut(1.5),
            // cc.spawn(
            //     cc.blink(2,5),
            //     cc.fadeOut(2)
            // ),
            cc.destroySelf(),
        ).start();
    }

    private moveCamera(node: cc.Node, finishCallback: () => void) {
        if (!this.mCameraPos) {
            finishCallback();
            return;
        }
        let map = this.ff.mMap;
        let camera = map.mCamera;

        let pos = cc.v2();
        let winsize = cc.winSize;
        pos.x = node.x + this.mCameraPos.x - winsize.width / 2;
        pos.y = node.y + this.mCameraPos.y - winsize.height / 2;
        cc.tween(camera.node).sequence(
            cc.moveTo(1, pos),
            cc.callFunc(() => {
                finishCallback();
            })
        ).start()
    }
    /**
     * 移动伙伴
     * @param sprite 
     */
    private moveTo() {
        let ffs = this.ff.getGroupBy(GroupType.A);
        for (let i = 0; i < ffs.length; i++) {
            const element = ffs[i];
            if (element) {
                // element.setRuning(false);
                // element.setDir({x:0,y:0});
                element.playAction(SpriteActionType.run, true)
                let attrData = element.attrData;
                let pos = cc.v2();
                if (attrData.post == 3) {
                    pos.x = this.node.x + this.mInitB.x + CMath.getRandom(-this.mInitB.width, this.mInitB.width);
                    pos.y = this.node.y + this.mInitB.y + CMath.getRandom(-this.mInitB.height, this.mInitB.height);
                } else {
                    pos.x = this.node.x + this.mInitA.x + CMath.getRandom(-this.mInitA.width, this.mInitA.width);
                    pos.y = this.node.y + this.mInitA.y + CMath.getRandom(-this.mInitA.height, this.mInitA.height);
                }

                cc.tween(element.node).sequence(
                    cc.moveTo(0.5, pos),
                    cc.callFunc(() => {
                        element.playAction(SpriteActionType.stand, true);
                    })
                ).start();
            }

        }
    }

    public removeCallback(f: FSprite) {
        for (let i = 0; i < this.mMonster.length; i++) {
            const element = this.mMonster[i];
            if (element == f) {
                this.mMonster.splice(i, 1);
                break;
            }
        }
        if (this.mMonster.length <= 0) {
            this.mIndex++
            if (this.mIndex < this.groupMonster.length) {
                this.mMonster = this.groupMonster[this.mIndex]
                this.playAppear()
            } else {
                for (let i = 0; i < this.mFenceTrigger.length; i++) {
                    const element = this.mFenceTrigger[i];
                    // element.active = false;
                    this.playCancelFence(element);
                }
                this.ff.regRemoveCallback(null);
                //主角减速等待伙伴
                // let t1 = this.ff.mainSprite.SPEED_WALK;
                // let t2 = this.ff.mainSprite.SPEED_RUN;

                // let mainFSprite = this.ff.mainSprite;
                // mainFSprite.SPEED_WALK = 100;
                // mainFSprite.SPEED_RUN = 100;
                this.ff.mainSprite.setPause(true);
                cc.tween(this.node).sequence(
                    cc.delayTime(0.5),
                    cc.callFunc(() => {
                        this.ff.mainSprite.setPause(false);
                    })
                ).start()

                this.checkOpen();
            }



        }
    }
    /**
     * 播放怪物出现
     */
    private playAppear() {
        for (let i = 0; i < this.mMonster.length; i++) {
            const element = this.mMonster[i];
            element.node.active = true
            if (this.mAppear) {
                let node = cc.instantiate(this.mAppear)
                node.parent = element.node
                node.group = element.node.group
                let spine = node.getComponent(sp.Skeleton)
                spine.setCompleteListener(() => {
                    node.destroy()
                    element.isActive = true
                });
                spine.setAnimation(0, 'animation', false);
            } else {
                element.isActive = true
            }

        }

    }
    /**
     * 播放消失动画
     */
    private playCancelFence(node: cc.Node) {
        if (this.countDown != -1) {
            this.ff.mCountDown.stopCountDown();
        }

        let nodes = node.children;
        let count = 0;
        nodes.forEach(element => {
            let spine = element.getComponent(sp.Skeleton);
            if (spine) {
                spine.setCompleteListener(() => {
                    element.active = false;
                    count++;
                    if (count >= nodes.length) {
                        node.active = false;
                    }
                });
                spine.setAnimation(0, 'open', false);
            }
        });
    }
    /**
     * 释放buff技能
     * @param sprite 
     * @param path 
     */
    private playSkill(id) {
        cc.resources.load('prefab/role/skills/skills_' + id, cc.Prefab, (err, prefab: cc.Prefab) => {
            if (err) {
                cc.error(err);
            } else {
                let fss = this.ff.getGroupBy(GroupType.A);
                for (let i = 0; i < fss.length; i++) {
                    const element = fss[i];
                    if (element) {
                        let node = cc.instantiate(prefab);
                        node.parent = element.node;
                        node.zIndex = 9999;
                        let spine = node.getComponent(sp.Skeleton);
                        if (id != 3) {
                            spine.setCompleteListener(() => {
                                node.destroy();
                            });
                        } else {
                            element.hasDun = true;
                            cc.tween(node).sequence(
                                cc.delayTime(10),
                                cc.callFunc(() => {
                                    element.hasDun = false
                                }),
                                cc.destroySelf()
                            ).start();
                        }
                    }
                }
            }
        });
    }


    private checkOpen() {
        //检查其它开关是否打开
        if (!this.mFenceTrigger2.length) return
        this.ff.pauseSprite(true);
        this.moveCamera(this.mFenceTrigger2[0], () => {
            cc.tween(this.node).sequence(
                cc.callFunc(() => {
                    for (let i = 0; i < this.mFenceTrigger2.length; i++) {
                        const element = this.mFenceTrigger2[i];
                        this.showFence(element, "open");
                    }
                }),
                cc.delayTime(1),
                cc.callFunc(() => {
                    for (let i = 0; i < this.mFenceTrigger2.length; i++) {
                        const element = this.mFenceTrigger2[i];
                        element.getComponent(cc.PhysicsBoxCollider).enabled = false;
                    }
                    this.ff.pauseSprite(false);
                })
            ).start();
        })
    }
    private showFence(element, action) {
        let nodes = element.children;
        for (let i = 0; i < nodes.length; i++) {
            const element = nodes[i];
            let spine: sp.Skeleton = element.getComponent(sp.Skeleton);
            if (spine) {
                spine.setAnimation(0, action, false);
            }
        }
    }

}