const Phaser = require('phaser');

const { TEXT, COLOURS, POSITIONS: { CRYP_LIST } } = require('./constants');
const genAvatar = require('./avatar');
const Item = require('./elements/item');

const BOX_WIDTH = Math.floor(CRYP_LIST.width());
const BOX_HEIGHT = Math.floor(CRYP_LIST.height() / 3.34);

const TEXT_MARGIN = 24;

const KEY_MAP = [
    'keydown-ONE',
    'keydown-TWO',
    'keydown-THREE',
];

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

    create() {
        this.registry.events.on('changedata', this.updateData, this);
        this.registry.events.on('setdata', this.updateData, this);
        const player = this.registry.get('player');
        if (player) this.drawCryps(player.cryps);
    }

    updateData(parent, key, data) {
        if (key === 'player') {
            this.drawCryps(data.cryps);
        }
    }

    drawCryps(cryps) {
        if (!cryps) return true;
        if (this.crypGroup) this.crypGroup.destroy(true);
        this.crypGroup = this.add.group();
        const addCryp = (cryp, i) => {
            const ROW_X = CRYP_LIST.x();
            const ROW_Y = CRYP_LIST.y() + BOX_HEIGHT * i * 1.1;


            const ACTIVE_FILL = 0.2;

            const FILL = Object.values(COLOURS)[i];
            // Selection of cryps
            const selectFn = () => {
                this.registry.set('crypStats', cryp);
            };

            // Cryp interaction box for adding items
            const crypInteract = this.add
                .rectangle(ROW_X, ROW_Y, BOX_WIDTH, BOX_HEIGHT, FILL, ACTIVE_FILL)
                .setInteractive()
                .setOrigin(0)
                .on('pointerdown', selectFn);
            crypInteract.itemSelect = () => {
                crypInteract.setFillStyle(COLOURS.SELECT);
            };
            crypInteract.itemDeselect = () => {
                crypInteract.setFillStyle(FILL, ACTIVE_FILL);
            };
            crypInteract.cryp = cryp;

            // Cryp Avatar
            const { name } = cryp;
            const crypImage = this.add.image(
                crypInteract.getCenter().x - crypInteract.width / 4,
                crypInteract.getCenter().y,
                'aztec',
                genAvatar(name)
            );

            // Add text info
            const yCrypTextAlgin = Math.floor(crypInteract.y + TEXT_MARGIN / 2);
            const xCrypNameAlign = Math.floor(crypInteract.x + crypInteract.width * 1 / 10);
            const crypInfoText = this.add.text(xCrypNameAlign, yCrypTextAlgin, name, TEXT.HEADER);
            const colourText = (c, j) => {
                // Placeholder for when gems are implemented
                const gemText = this.add.text(crypInteract.x + crypInteract.width * (j + 3) / 6, yCrypTextAlgin, `${c[0]} - ${c[1]}`, TEXT.HEADER);
                this.crypGroup.add(gemText);
            };

            const { red, green, blue } = cryp.colours;
            const CRYP_COLOURS = [
                ['R', red],
                ['G', green],
                ['B', blue],
            ];
            CRYP_COLOURS.forEach(colourText);

            this.crypGroup.addMultiple([crypInteract, crypImage, crypInfoText]);

            const crypSkill = (stat, j) => {
                const SKILL_WIDTH = Math.floor(BOX_WIDTH / 2);
                const SKILL_HEIGHT = Math.floor(BOX_HEIGHT / 8);
                const SKILL_X = crypInteract.getCenter().x + crypInteract.width / 4;
                const SKILL_Y = crypInteract.y + SKILL_HEIGHT * 1.15 * (j + 1.6);
                const itemObj = new Item(this, stat.skill, j, SKILL_X, SKILL_Y, SKILL_WIDTH, SKILL_HEIGHT);
                this.add.existing(itemObj);
                itemObj.setInteractive();
                const itemInfo = { item: stat.skill, cryp };
                itemObj.on('pointerdown', () => this.registry.set('itemInfo', itemInfo));
                this.crypGroup.add(itemObj);
            };
            cryp.skills.forEach(crypSkill);

            const crypSpec = (spec, j) => {
                const SKILL_WIDTH = Math.floor(BOX_WIDTH * 0.15);
                const SKILL_HEIGHT = Math.floor(BOX_HEIGHT * 0.2);
                const SKILL_X = Math.floor(crypInteract.x + BOX_WIDTH * (0.6 + j) * 0.175);
                const SKILL_Y = Math.floor(crypInteract.y + BOX_HEIGHT * 0.875);
                const itemObj = new Item(this, spec, j, SKILL_X, SKILL_Y, SKILL_WIDTH, SKILL_HEIGHT);
                itemObj.setInteractive();
                const itemInfo = { item: spec, cryp };
                itemObj.on('pointerdown', () => this.registry.set('itemInfo', itemInfo));
                this.add.existing(itemObj);
                this.crypGroup.add(itemObj);
            };
            cryp.specs.forEach(crypSpec);
        };
        cryps.forEach(addCryp);

        return true;
    }

    cleanUp() {
        KEY_MAP.forEach(k => this.input.keyboard.removeListener(k));
        this.registry.events.off('changedata', this.updateData, this);
        this.registry.events.off('setdata', this.updateData, this);
        this.scene.remove();
    }
}

module.exports = MenuCrypList;
