const Phaser = require('phaser');
const { throttle } = require('lodash');

const { TEXT, POSITIONS: { COMBAT } } = require('./constants');
const CombatLog = require('./combat.log');
const CombatCryps = require('./combat.cryps');
const CombatSkills = require('./combat.skills');
const CombatHitBox = require('./combat.hitbox');

const renderResolutions = require('./combat.render.resolutions');


class Combat extends Phaser.Scene {
    constructor() {
        super({ key: 'Combat' });
    }

    preload() {
        this.load.image('proj', 'https://labs.phaser.io/assets/sprites/bullet.png');
        this.load.image('blue', 'https://labs.phaser.io/assets/particles/blue.png');
        this.load.image('green', 'https://labs.phaser.io/assets/particles/green.png');
        this.load.image('red', 'https://labs.phaser.io/assets/particles/red.png');
        this.load.image('white', 'https://labs.phaser.io/assets/particles/white.png');
        this.load.image('yellow', 'https://labs.phaser.io/assets/particles/yellow.png');
    }

    create() {
        console.log('creating game');
        this.registry.events.off('changedata', this.updateData);
        this.registry.events.on('changedata', this.updateData, this);
        this.addLeaveGame();

        this.registry.set('gamePhase', false);
        this.registry.set('inGame', true);
        this.registry.set('gameAnimating', false);
        this.account = this.registry.get('account');
        this.fetchGame = throttle(() => {
            const game = this.registry.get('game');
            if (game) {
                const ws = this.registry.get('ws');
                return ws.sendGameState(game.id);
            }
            return false;
        }, 500);

        return true;
    }

    startGame(game) {
        this.scene.manager.add('CombatCryps', CombatCryps, true, game);
        this.scene.manager.add('CombatLog', CombatLog, true, game);
        this.renderedResolves = game.resolved.length; // In case you rejoin mid way
        this.scene.manager.add('CombatSkills', CombatSkills, true, game.phase);
        this.scene.manager.add('CombatHitBox', CombatHitBox, true, game.phase);
        this.registry.set('gamePhase', game.phase);
        this.phase = game.phase;
        return true;
    }

    update() {
        this.fetchGame();
        return true;
    }

    updateData(parent, key, data) {
        if (key === 'game') {
            if (!data) return false;
            const startGame = this.registry.get('gamePhase') === false;
            if (startGame) { this.startGame(data); return true; }
            this.checkAnimation(data);
            // Game over?
            // if (data.phase === 'Finish') {
            //     this.time.delayedCall(10000, () => {
            //         this.endGame();
            //     });
            // }
        }
        return true;
    }

    checkAnimation(game) {
        // Check cryps are loaded and whether game is animating
        const cantAnimate = this.registry.get('gamePhase') === 'animating';
        if (cantAnimate) return false;
        if (game.resolved.length !== this.renderedResolves) {
            const newResolutions = game.resolved.slice(this.renderedResolves);
            renderResolutions(this, game, newResolutions);
            this.renderedResolves = game.resolved.length;
            return true;
        }
        if (this.phase !== game.phase) {
            this.phase = game.phase;
            this.registry.set('gamePhase', game.phase);
        }
        if (this.registry.get('gameLog') !== game.log.length) {
            this.registry.set('gameLog', game.log.length);
        }
        return true;
    }

    addLeaveGame() {
        const leaveGame = () => this.cleanUp();
        this.input.keyboard.on('keydown_BACKSPACE', leaveGame, 0, this);
        const LEAVE_HEIGHT = COMBAT.height() / 6;
        const LEAVE_WIDTH = COMBAT.width() / 5;
        const LEAVE_X = COMBAT.width() * 0.8;
        const LEAVE_Y = COMBAT.height() * 0.9;

        const menu = this.add
            .rectangle(LEAVE_X, LEAVE_Y, LEAVE_WIDTH, LEAVE_HEIGHT, 0x440000)
            .setInteractive()
            .setOrigin(0)
            .on('pointerdown', leaveGame);

        this.add
            .text(menu.getCenter().x, menu.getCenter().y, 'Menu', TEXT.HEADER)
            .setOrigin(0.5, 0.5);
    }

    cleanUp() {
        this.registry.events.off('changedata', this.updateData, this);
        this.registry.events.off('setdata', this.updateData, this);

        this.registry.set('inGame', null);
        this.registry.set('menu', true);
        this.registry.set('game', null);

        const ACTIVE_SCENES = ['CombatLog', 'CombatCryps', 'CombatSkills', 'CombatHitBox'];
        ACTIVE_SCENES.forEach((sKey) => {
            if (this.scene.get(sKey)) this.scene.get(sKey).cleanUp();
        });
        this.scene.remove();

        return true;
    }
}

module.exports = Combat;
