import { ActionFormData, ModalFormData } from '@minecraft/server-ui';
import { MenuFormBuilder } from '../MenuFormBuilder';
import { StructureVerifier } from '../Verifier/StructureVerifier';
import { InstanceStatistics } from './InstanceStatistics';
import {EntityComponentTypes, TicksPerSecond, world} from '@minecraft/server';
import { RENDER_MODE_LABELS, RENDER_MODE_ORDER } from '../Enums/RenderMode';
import { RefreshRate } from '../Verifier/RefreshRate';

export class InstanceFormBuilder {
    static structureVerifier;

    static buildInstance(instance, options) {
        const location = instance.getLocation();
        const form = new ActionFormData()
            .title(MenuFormBuilder.menuTitle)
        const body = { rawtext: [
            { translate: 'construct.instance.menu.body', with: [instance.getName(), instance.getStructureId()] }
        ]};
        if (instance.hasLocation())
                body.rawtext.push(...[
                    { text: '\n' },
                    { translate: 'construct.instance.menu.location', with: { rawtext: [
                        { text:String(location.location.x) },
                        { text:String(location.location.y) },
                        { text:String(location.location.z) },
                        { translate:world.getDimension(location.dimensionId).localizationKey }
                    ]} }
                ]);
        form.body(body);
        options.forEach(option => {
            form.button({ translate: option });
        });
        return form;
    }

    static buildRenameInstance(currentName) {
        return new ModalFormData()
            .title(MenuFormBuilder.menuTitle)
            .textField({ translate: 'construct.instance.menu.rename' }, currentName)
            .submitButton({ translate: 'construct.menu.instance.button.rename' });
    }

    static async buildStatistics(instance) {
        const buildStatisticsForm = new ActionFormData()
            .title(MenuFormBuilder.menuTitle)
        if (this.structureVerifier)
            throw new Error('StructureVerifier is already running.');
        this.structureVerifier = StructureVerifier.standalone(instance, { particleLifetime: 1*TicksPerSecond });
        const verification = await this.structureVerifier.verifyStructure(true);
        const statistics = new InstanceStatistics(instance, verification);
        const statsMessage = statistics.getMessage();
        this.structureVerifier = void 0;
        buildStatisticsForm.body(statsMessage);
        return { form: buildStatisticsForm, stats: statsMessage };
    }

    static buildSettings(instance) {
        return new ModalFormData()
            .title(MenuFormBuilder.menuTitle)
            .toggle({ translate: 'construct.instance.option.validation' }, { defaultValue: instance.options.verifier.isEnabled, tooltip: { translate: 'construct.instance.option.validation.description' }})
            .slider({ translate: 'construct.instance.option.layer'}, 0, instance.getMaxLayer(), { defaultValue: instance.getLayer(), valueStep: 1, tooltip: { translate: 'construct.instance.option.layer.description' }})
            .dropdown(
                { translate: 'construct.instance.option.rendermode' },
                RENDER_MODE_ORDER.map(mode => ({ translate: RENDER_MODE_LABELS[mode] })),
                {
                    defaultValueIndex: Math.max(RENDER_MODE_ORDER.indexOf(instance.options.renderMode), 0),
                    tooltip: { translate: 'construct.instance.option.rendermode.description' }
                }
            )
            .slider(
                { translate: 'construct.instance.option.refreshrate' },
                RefreshRate.MIN_SECONDS,
                RefreshRate.MAX_SECONDS,
                {
                    defaultValue: instance.options.verifier.refreshSeconds,
                    valueStep: RefreshRate.SECONDS_STEP,
                    tooltip: { translate: 'construct.instance.option.refreshrate.description' }
                }
            )
            .submitButton({ translate: 'construct.menu.submit' });
    }

    static buildMaterialList(instance, onlyMissing = false, player = false) {
        const materials = instance.getActiveMaterials();
        const form = new ActionFormData()
            .title(MenuFormBuilder.menuTitle)
        const bodyText = { rawtext: [] };
        let buttonText = void 0;
        if (onlyMissing) {
            const inventoryContainer = player?.getComponent(EntityComponentTypes.Inventory)?.container;
            if (!inventoryContainer) {
                form.body({ translate: 'construct.instance.materials.noinventory' });
                return form;
            }
            bodyText.rawtext.push({ translate: 'construct.instance.materials.missing.header' });
            if (instance.hasLayerSelected())
                bodyText.rawtext.push({ translate: 'construct.instance.materials.layer', with: [String(instance.getLayer())] });
            bodyText.rawtext.push({ text: `§f\n\n` });
            bodyText.rawtext.push(materials.formatString(materials.getMaterialsDifference(inventoryContainer)));
            buttonText = "construct.instance.materials.all.button";
        } else {
            bodyText.rawtext.push({ translate: `construct.instance.materials.all.header` });
            if (instance.hasLayerSelected())
                bodyText.rawtext.push({ translate: 'construct.instance.materials.layer', with: [String(instance.getLayer())] });
            bodyText.rawtext.push({ text: `§f\n\n` });
            bodyText.rawtext.push(materials.formatString());
            buttonText = "construct.instance.materials.missing.button";
        }
        form.body(bodyText);
        form.button({ translate: buttonText });
        return form;
    }
}