"use strict";
import { showAlert } from './alerts.js';
import Luci from './luci.js';
import Scenari from './scenari.js';

class Antifurto {
    /**
     * the div where everything related to the AntiFurto is stored
     */
    static antifurtoContainer = document.getElementById('antifurtoContainer')!;
    /**
     * the progress bar used to show the user how much is left until the alarm is triggered
     */
    static progressBar = document.getElementById('antifurto-progress')!;
    /**
     * describes the current status of the progress bar
     */
    static currentPercentage: number = parseInt(Antifurto.progressBar!.style.width);
    /**
     * shows if the antitheft is on or off
     */
    static status: Boolean = false;
    /**
     * contains the user's preferences regarding when to trigger the alarm
     */
    static soglia: undefined | number = undefined;
    /**
     * shows if the alarm is on or off
     */
    static alarmStatus: Boolean = false;

    constructor() {
        Antifurto.init();
        Antifurto.timer();
        Antifurto.setupModalListener();
    }

    static init(): void {
        Antifurto.fillTable();

        const antifurtoBtn = document.getElementById('mainButtonContainer')!.children[2];
        antifurtoBtn.addEventListener('click', () => {
            Antifurto.toggleContainer(true);
            Luci.toggleContainer(false);
            Scenari.toggleContainer(false);
        }, false);

        Antifurto.antifurtoBtnListener();
        const bell = document.getElementById('antifurto-bell')!;
        bell.addEventListener('click', () => {
            Antifurto.activateAlarm(false);
            // TODO ask if they want to turn off the antitheft
        }, false);
    }
    /**
     * listener for the form in the modal used to retrieve the soglia value from the user
     */
    static setupModalListener(): void {
        const modalForm: HTMLFormElement = document.getElementById('setup-antifurto-form')! as HTMLFormElement;
        const sogliaInput: HTMLInputElement = document.getElementById('sogliaAntifurto')! as HTMLInputElement;
        const closeModal: HTMLButtonElement = modalForm.querySelector('.btn.btn-danger')!;
        modalForm.addEventListener('submit', event => {
            event.preventDefault();
            // get the value from the input
            const inputVal = sogliaInput!.value.trim();
            if (inputVal == null || inputVal === '') {
                alert('Inserisci un valore valido');
                return;
            }
            const soglia = parseInt(inputVal);
            if (isNaN(soglia) || soglia < 0 || soglia > 100) {
                alert('Inserisci un valore valido');
                return;
            }
            // close modal
            closeModal.click();
            // empty the modal
            modalForm.reset();
            // setup soglia and progress bar
            Antifurto.setupSoglia(soglia);
        }, false);
    }
    /**
     * sets up the progress bar to better accomodate the user's preferences
     * @param {number} soglia the integer value from which the alarm will be triggered
     */
    static setupSoglia(soglia: number): void {
        Antifurto.soglia = soglia;
        Antifurto.progressBar.setAttribute('aria-valuemax', Antifurto.maxProgressBar().toString());//the progress bar goes a little bit more than the soglia
        Antifurto.resetProgressBar();
    }
    /**
     * edits and shows the modal to toggle the antitheft
     */
    static antifurtoBtnListener(): void {
        const antifurtoBtn = document.getElementById('antifurto-stato-antifurto')! as HTMLButtonElement;
        const modal = document.getElementById('toggle-antifurto-modal')!;
        const modalBody = modal.querySelector('.modal-body')!;
        const modalLauncher = document.getElementById('antifurto-modal-launcher')!;
        const okBtn: HTMLButtonElement = modal.querySelector('#toggle-antifurto-btn')!;

        antifurtoBtn.addEventListener('click', () => {
            const children = modalBody.children as HTMLCollectionOf<HTMLParagraphElement>;
            // p, p
            /*
            <p>Stai per abilitare l'antifurto.</p>
            <p>Vuoi continuare?</p>
            */
            if (antifurtoBtn.innerText === 'ON') {
                // the antitheft is on
                children[0].innerText = "Stai per disabilitare l'antifurto.";
                okBtn.innerText = 'Disattiva';
            } else {
                if (Antifurto.soglia === undefined) {
                    showAlert('Soglia', "Non hai ancora impostato la soglia di sicurezza. Impostala prima di attivare l'antifurto", false);
                    return;
                }
                // the antitheft is off
                children[0].innerText = "Stai per abilitare l'antifurto.";
                okBtn.innerText = 'Attiva';
            }
            // launch the modal
            modalLauncher.click();
        }, false);

        const closeModal: HTMLButtonElement = modal.querySelector('.btn.btn-danger')!;
        okBtn.addEventListener('click', () => {
            // close the modal
            closeModal.click();
            // toggle the antitheft
            const activating = antifurtoBtn.innerText === 'OFF';
            Antifurto.activate(activating);
        }, false);
    }
    /**
     * function to activate or deactivate the antitheft and syncronize the button in the scenari
     * @param {Boolean} activating whether to activate or deactivate the antitheft
     * @param {Boolean} fromScenari usually false or undefined; true only if the function is called from the scenari
     */
    static activate(activating: Boolean, fromScenari: Boolean = false): void {
        if (fromScenari !== true)
            Scenari.correctlySetAntifurto(activating, true);

        // TODO server set the status of the antitheft
        const antifurtoBtn = document.getElementById('antifurto-stato-antifurto')!;

        if (activating) {
            if (antifurtoBtn.innerText === 'ON')
                return;
            antifurtoBtn.innerText = 'ON';
            antifurtoBtn.classList.remove('btn-danger');
            antifurtoBtn.classList.add('btn-success');
        } else {
            if (antifurtoBtn.innerText === 'OFF')
                return;
            antifurtoBtn.innerText = 'OFF';
            antifurtoBtn.classList.remove('btn-success');
            antifurtoBtn.classList.add('btn-danger');
            Antifurto.activateAlarm(false);
        }
        Antifurto.status = activating;
    }
    /**
     * toggles the bell if the alarm is on
     * @param {Boolean} activating if true, the bell will turn on
     */
    static activateAlarm(activating: Boolean): void {
        // if the antitheft is off, the bell shouldn't turn on
        // if the alarmStatus is already set, nothing else should be done
        if (Antifurto.status === false || Antifurto.alarmStatus === activating)
            return;

        Antifurto.alarmStatus = activating;
        const bell = document.getElementById('antifurto-bell')!;
        if (activating) {
            bell.classList.add('fa-shake');
        } else {
            bell.classList.remove('fa-shake');
            // empty the progress bar
            Antifurto.resetProgressBar();
        }
    }
    /**
     * inputs a delta and takes care of updating the progress bar and the server
     * @param {number} percentage the percentage to add to the progress bar (+/-)
     */
    static changeProgressBar(percentage: number): void {
        // if the antitheft is turned off, the progress bar shouldn't change
        if (!Antifurto.status) {
            showAlert('Antifurto', "L'antifurto รจ spento", false);
            return;
        }
        if (Antifurto.soglia === undefined) {
            showAlert('Soglia', "Non hai ancora impostato la soglia di sicurezza. Impostala prima di attivare l'antifurto", false);
            return;
        }
        const oldPercentage = Antifurto.currentPercentage;
        var newPercentage = oldPercentage + percentage;
        newPercentage = Math.floor(newPercentage);
        const maxProgressAvailable = Antifurto.maxProgressBar();
        if (newPercentage > maxProgressAvailable)
            newPercentage = maxProgressAvailable;
        if (newPercentage < 0)
            newPercentage = 0;
        // TODO server send the new percentage
        Antifurto.progressBar.style.width = newPercentage + '%';
        Antifurto.progressBar.setAttribute('aria-valuenow', newPercentage.toString());
        Antifurto.progressBar.innerHTML = newPercentage + '%';
        Antifurto.currentPercentage = newPercentage;
        // check if the soglia is reached
        Antifurto.activateAlarm(newPercentage >= Antifurto.soglia);
        const quarterSoglia = Antifurto.soglia / 4;
        // change colors of the progress bar
        if (newPercentage <= quarterSoglia) {
            if (Antifurto.progressBar.classList.contains('bg-info'))
                return;
            Antifurto.progressBar.classList.add('bg-info');
            Antifurto.progressBar.classList.remove('bg-success');
            Antifurto.progressBar.classList.remove('bg-warning');
            Antifurto.progressBar.classList.remove('bg-danger');
        } else if (newPercentage <= 2 * quarterSoglia) {
            if (Antifurto.progressBar.classList.contains('bg-success'))
                return;
            Antifurto.progressBar.classList.remove('bg-info');
            Antifurto.progressBar.classList.add('bg-success');
            Antifurto.progressBar.classList.remove('bg-warning');
            Antifurto.progressBar.classList.remove('bg-danger');
        } else if (newPercentage <= 3 * quarterSoglia) {
            if (Antifurto.progressBar.classList.contains('bg-warning'))
                return;
            Antifurto.progressBar.classList.remove('bg-info');
            Antifurto.progressBar.classList.remove('bg-success');
            Antifurto.progressBar.classList.add('bg-warning');
            Antifurto.progressBar.classList.remove('bg-danger');
        } else {
            if (Antifurto.progressBar.classList.contains('bg-danger'))
                return;
            Antifurto.progressBar.classList.remove('bg-info');
            Antifurto.progressBar.classList.remove('bg-success');
            Antifurto.progressBar.classList.remove('bg-warning');
            Antifurto.progressBar.classList.add('bg-danger');
        }
    }
    /**
     * every minute, the progress bar recevies a delta of -5%
     */
    static timer(): void {
        setInterval(() => {
            Antifurto.changeProgressBar(-5);
        }, 60000);
        //FIXME test to remove the following lines
        const github = document.getElementById('boost-progressbar')!;
        github.addEventListener('click', () => {
            Antifurto.changeProgressBar(3);
            if (!Antifurto.status)
                alert("attiva l'antifurto");
        }, false);
    }
    /**
     * resets the progress bar to 0
     */
    static resetProgressBar(): void {
        Antifurto.changeProgressBar(-Antifurto.currentPercentage);
    }
    /**
     * get all user's data from the server and show them in the table
     */
    static fillTable(): void {
        // TODO server get all sensors for the antitheft
        const sensori = [];
        // TODO server get antitheft status
        // Antifurto.status = true/false;
    }
    /**
     * toggle the visibility of the antifurto container
     * @param {Boolean} visible whether the container should be visible or not
     */
    static toggleContainer(visible: Boolean): void {
        if (visible) {
            Antifurto.antifurtoContainer.classList.remove('invisible');
        } else {
            Antifurto.antifurtoContainer.classList.add('invisible');
        }
    }
    /**
     * @returns the maximum value of the progress bar
     */
    static maxProgressBar(): number {
        if(Antifurto.soglia == null)
            return 100;
        return Antifurto.soglia + (Antifurto.soglia * 0.2);
    }
}

export default Antifurto;