/**
 * Filename: index.ts
 * Author: Stevan Bosanac
 * Created Date: 2024-09-17
 *
 * Description:
 * The `BackPanel` class in TypeScript creates a customizable back panel with user and service controls
 * that can be added dynamically.
 *
 * Revision History:
 * 2024-09-17: Initial creation
 *
 */

import { Pane } from 'tweakpane';
import Locator from '../../services/Locator';
import { BackPanelPlugIns } from './backPanelPlugIns/BackPanelPlugIns';
import { getObjFromJSON } from './backPanelPlugIns/utils';
import { PaneExtended } from './interfaces/PaneExtended';

/*
 * The `BackPanel` class in TypeScript creates a customizable back panel with user and service controls
 * that can be added dynamically.
 */
export default class BackPanel
{
    controls: string[];
    backPanelContainer: HTMLDivElement;
    pane: PaneExtended;

    /**
     * The constructor function initializes properties and creates a back panel for a given locator.
     * @param {any} locator - The `locator` parameter in the constructor function is used to specify the
     * location or reference to an element in the DOM (Document Object Model). It can be a selector
     * string, an element object, or any other valid way to locate an element on the web page. This
     * `locator` will be used
     */
    constructor()
    {
        this.controls = [];
        this.createBackPanel();
        this.backPanelContainer.style.display = localStorage.getItem('back_panel_visible') ?? 'none';
    }

    /**
     * The function `createBackPanel` creates a back panel with settings that can be expanded or
     * collapsed by pressing the 'H' key.
     */
    createBackPanel()
    {
        this.backPanelContainer = document.createElement('div');
        this.backPanelContainer.classList.add('back-panel');
        this.backPanelContainer.style.position = 'absolute';
        this.backPanelContainer.style.zIndex = '1000';
        this.backPanelContainer.style.width = '100%';
        this.backPanelContainer.style.height = '0%';
        document.body.appendChild(this.backPanelContainer);

        const mainPanelContainer = document.createElement('div');

        mainPanelContainer.classList.add('main-back-panel');
        mainPanelContainer.style.position = 'absolute';
        mainPanelContainer.style.width = '350px';
        mainPanelContainer.style.right = '50%';
        mainPanelContainer.style.transform = 'translate(50%)';
        mainPanelContainer.style.margin = '5px';
        this.backPanelContainer.appendChild(mainPanelContainer);

        this.pane = new Pane({ title: 'Back Panel', container: mainPanelContainer }) as PaneExtended;

        this.pane.settings = {
            expanded: false,
            users: {
                serverURL: 'dev.popiplay.dev',
                sharedPlayer: '1',
                currency: 'EUR'
            }
        };

        Object.defineProperty(this.pane, 'settings', {
            get()
            {
                return getObjFromJSON(localStorage.getItem('backPanelSettings') || '{}');
            },
            set(settings = {})
            {
                const newSettings = { ...this.settings, ...settings };

                localStorage.setItem('backPanelSettings', JSON.stringify(newSettings));
            }
        });

        this.pane.expanded = !!this.pane.settings.expanded;
        this.pane.on('change', () =>
        {
            if (this.pane.settings.expanded !== this.pane.expanded)
            {
                this.pane.settings = { expanded: this.pane.expanded };
            }
        });

        window.addEventListener('keyup', (e) =>
        {
            switch (e.key)
            {
                case 'h':
                case 'H':
                    this.backPanelContainer.style.display = this.backPanelContainer.style.display === 'none'
                        ? 'block'
                        : 'none';
                    break;
            }
            localStorage.setItem('back_panel_visible', this.backPanelContainer.style.display);
        });
    }

    /** The function `addUserControls` adds user controls using a specified locator. */
    addUserControls()
    {
        this.addControl(Locator.user);
    }

    /**
     * The function `addOtherControls` iterates over services and adds controls that are not already
     * included in the controls list.
     */
    addOtherControls()
    {
        Object.values(Locator.services).forEach((service: any) =>
        {
            if (!this.controls.includes(service.backPanelControlsName))
            {
                this.addControl(service);
            }
        });
    }

    /**
     * The function `addControll` instantiates a control component based on a service and adds its name
     * to a list of controls.
     * @param service - The `service` parameter is an object that contains information about a specific
     * service or feature. It likely includes details such as the name of the service and possibly other
     * configuration settings or data related to that service.
     */
    addControl(service: any)
    {
        const Controll = BackPanelPlugIns.getControll(service.backPanelControlsName);

        if (Controll)
        {
            const controllInstance = new Controll(this.pane);

            controllInstance.initialize();

            this.controls.push(service.backPanelControlsName);
        }
    }
}
