import { BEAT_GUILD, CHECK_FRAGMENT, CHECK_TOUCH, DROP_TOP_FRAGMENT, eventTarget, HAMMER, RESET_BOTTLE, RESET_FRAGMENT, SHAKE_FRAGMENT, SHOW_CARD_POPUP, STOP_GUILD_TAP } from "../Events";
import { Global } from "../Global";
import BehindFragment from "./BehindFragment";
import FragmentJarController from "./FragmentJarController";

const { ccclass, property } = cc._decorator;

@ccclass
export default class BreakingJarController extends cc.Component {
    @property([cc.Node])
    private fragmentSpecialNodes: cc.Node[] = [];
    @property(cc.Node)
    private hammerNode: cc.Node = null;
    @property(cc.Node)
    private behindJar: cc.Node = null;
    @property(cc.ParticleSystem)
    private particleFont: cc.ParticleSystem = null;
    @property(cc.ParticleSystem)
    private particleBehind: cc.ParticleSystem = null;
    @property(cc.Node)
    private mask: cc.Node = null;

    private _spine: sp.Skeleton = null;
    private _skins = ["Ga", "Gai_lung", "Gay", "Bua",];
    private _countFragment = 0;

    private _fragmentsPosition: cc.Vec3[] = [];
    private _fontFragments: cc.Node[] = [];
    private _bodyFragments: string[] = [];
    private _isEnd = false;
    private _behindJarChild: BehindFragment[] = [];
    private _behindJarChildPosition: cc.Vec3[] = [];


    onLoad() {
        cc.director.getPhysicsManager().enabled = true;
        // cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_aabbBit |
        //     cc.PhysicsManager.DrawBits.e_jointBit |
        //     cc.PhysicsManager.DrawBits.e_shapeBit;

        this._spine = this.hammerNode.getComponentInChildren(sp.Skeleton);

        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);

        eventTarget.on(CHECK_FRAGMENT, this.checkFragment, this);
        eventTarget.on(HAMMER, this.onHammer, this);
        eventTarget.on(RESET_BOTTLE, this.resetBottle, this);
        eventTarget.on(BEAT_GUILD, this.beatGuild, this);

        this._fontFragments = this.getComponentsInChildren(FragmentJarController).map(item => item.node);
        this._fragmentsPosition = this._fontFragments.map(item => item.position.clone());
        this._behindJarChild = this.behindJar.children.map(item => item.getComponent(BehindFragment));
        this._behindJarChildPosition = this.behindJar.children.map(item => item.position.clone());

        this.particleFont.enabled = false;
        this.particleBehind.enabled = false;
        this.mask.active = false;
    }

    private beatGuild() {
        // this.onHammer(cc.v2(100));
    }

    protected start(): void {
        this.resetHammer();
    }

    private resetBottle() {
        this._countFragment = 0;
        this._bodyFragments = [];
        this._spine.setSkin(this._skins[Global.tool % this._skins.length]);

        this._fontFragments.forEach((node, index) => {
            node.position = this._fragmentsPosition[index];
        })

        this._behindJarChild.forEach((behindFragment, index) => {
            behindFragment.node.position = this._behindJarChildPosition[index];
            behindFragment.reset();
        })

        eventTarget.emit(RESET_FRAGMENT);
        this._isEnd = false;
    }

    private onHammer(newPos: cc.Vec2) {
        cc.Tween.stopAllByTarget(this.hammerNode);
        this._spine.setAnimation(0, "Dap4", false);
        this.hammerNode.active = true;

        cc.tween(this.hammerNode)
            .to(0.5, { position: cc.v3(newPos.x, newPos.y, 0) })
            .call(() => this.shakeNode())
            .delay(0.1)
            .to(0.2, { position: cc.v3(400, -400) })
            .call(() => this.hammerNode.active = false)
            .start();
    }

    private shakeNode() {
        cc.director.getPhysicsManager().enabled = false;
        eventTarget.emit(SHAKE_FRAGMENT);
        cc.tween(this.node)
            .delay(0.15)
            .call(() => cc.director.getPhysicsManager().enabled = true)
            .start();
    }

    private checkFragment(fragmentNode: cc.Node) {
        const fontFragment = this._fontFragments.findIndex(item => item === fragmentNode);
        const behindFragment = this._behindJarChild[fontFragment];
        // behindFragment.onDrop();

        if (this._isEnd) {
            return;
        }

        this._bodyFragments.push(fragmentNode.name);
        this._countFragment++;

        if (this._countFragment == 9) {
            console.log('this._countFragment', this._countFragment)
            this.scheduleOnce(() => eventTarget.emit(SHOW_CARD_POPUP), 1.5);
            this._isEnd = true;
            return;
        }
        
        const isSpecial = this.fragmentSpecialNodes.some(item => item === fragmentNode);
        const isDropTop = this.fragmentSpecialNodes.every(item => item.getComponent(FragmentJarController).isDropped);
        
        if (isSpecial && isDropTop) {
            eventTarget.emit(DROP_TOP_FRAGMENT);
        }
    }

    private onTouchStart(event: cc.Event.EventTouch) {
        eventTarget.emit(STOP_GUILD_TAP);
        const pos = event.getLocation();
        const nodePos = this.node.convertToNodeSpaceAR(pos);

        eventTarget.emit(CHECK_TOUCH, nodePos);
        this._spine.setSkin(this._skins[Global.tool % this._skins.length]);
    }

    private onTouchEnd(event: cc.Event.EventTouch) {

    }

    private resetHammer() {
        this.hammerNode.position = cc.v3(300);
        this.hammerNode.active = false;
    }
}
