"use strict";

import Luci from "../luci.js";
import ApiMqttIn from "./api-mqtt-in.js";
import ApiMqttOut from "./api-mqtt-out.js";

class Api {

    static baseURL = "/api/";
    // /api/luci/
    static callbackGetLuci = null;
    /**
     * gets the luci of the user from the server
     * @returns {*} all the lights of the user
     */
    static getLuci = callback => {
        /*const url = Api.baseURL + "luci/";
        const response = await fetch(url);
        const data = await response.json();
        if (response.ok)
            return data;
        else
            throw data;*/
        Api.callbackGetLuci = callback;
        ApiMqttOut.getStatusLuci();
    };
    static sendLuciWeb = luci => {
        if( Api.callbackGetLuci == null)
            return;
        Api.callbackGetLuci(luci);
        Api.callbackGetLuci = null;
    }
    /**
     * adds a new luce to the server
     * @param {luceTemplate} luce the luce to add to the server
     * @returns {*} null if the light was added
     */
    static makeNewLuci = async luce => {
        if (luce == null)
            throw new Error("luce must be defined");
        const url = Api.baseURL + "luci/";
        const response = await fetch(url, {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(luce)
        });
        if (response.ok)
            return null;
        else
            throw await response.json();
    };
    static callbackLuciStato = null;
    static toggleForLuciStato = null;
    // /api/luci/stato/
    /**
     * changes the status of a luce on the server
     * @param {luceTemplate} luce the luce to change the status of
     * @returns {*} null if the light's status was changed
     */
    static setLuciStato = (luce,toggle,callback) => {
        /*if (luce == null)
            throw new Error("luce must be defined");
        const url = Api.baseURL + "luci/stato/";
        const response = await fetch(url, {
            method: "PUT",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(luce)
        });
        if (response.ok)
            return null;
        else
            throw await response.json();*/
        Api.callbackLuciStato = callback;
        Api.toggleForLuciStato = toggle;
        ApiMqttOut.setLuciStato(luce);
    }
    static sendLuciStatoWeb = () => {
        // ApiMqttIn.statoLuce(luci);
        Api.callbackLuciStato(Api.toggleForLuciStato);
        // Api.callbackLuciStato = null;
        Api.toggleForLuciStato = null;
    }
    // /api/scenari/
    /**
     * gets the scenari of the user from the server
     * @returns {*} all the scenarios of the user
     */
    static getScenari = async () => {
        const url = Api.baseURL + "scenari/";
        const response = await fetch(url);
        const data = await response.json();
        if (response.ok)
            return data;
        else
            throw data;
    };
    // /api/scenari/attiva/
    /**
     * activates or deactivates a scenario on the server
     * @param {scenarioTemplate} scenario the scenario to activate or deactivate
     * @returns {*} null if the scenario was activated or deactivated
     */
    static setScenarioStatus = async scenario => {
        if (scenario == null)
            throw new Error("scenario must be defined");
        const url = Api.baseURL + "scenari/attiva/";
        const response = await fetch(url, {
            method: "PUT",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(scenario)
        });
        if (response.ok)
            return null;
        else
            throw await response.json();
    };
    // /api/scenari/registra/
    /**
     * starts/stop the recording of a scenario
     * @param {Boolean} recording true to start the recording, false to stop it
     * @returns {*} null if the recording was started or stopped
     */
    static recordScenario = async recording => {
        if (recording == null || typeof recording.registra != "boolean")
            throw new Error("recording must be a set boolean");
        const url = Api.baseURL + "scenari/registra/";
        const response = await fetch(url, {
            method: "PUT",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(recording)
        });
        if (response.ok)
            return null;
        else
            throw await response.json();
    }
    // /api/scenari/salva/
    /**
     * tells the server to save the currently recorded scenario
     * @returns {*} the scenario if it was saved
     */
    static saveScenario = async nome => {
        if(nome == null)
            throw new Error("nome must be defined");
        const url = Api.baseURL + "scenari/salva/";
        const response = await fetch(url,{
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({salva:true,nome})
        });
        if (response.ok)
            return null;
        else
            throw await response.json();;
    };
    // /api/antifurto/
    /**
     * gets everything about the antifurto (stato, allarme, attenzione (valore progress bar), soglia, sensori)
     * @returns {*} the antifurto's values
     */
    static getAntifurto = async () => {
        
        // const url = Api.baseURL + "antifurto/";
        // const response = await fetch(url);
        // const data = await response.json();
        // if (response.ok)
        //     return data;
        // else
        //     throw data;
    };
    // /api/antifurto/stato/
    /**
     * gets the status of the antifurto
     * @returns {*} the antifurto's status
     */
    /*static getAntifurtoStatus = async () => {
        const url = Api.baseURL + "antifurto/stato/";
        const response = await fetch(url);
        const data = await response.json();
        if (response.ok)
            return data;
        else
            throw data;
    };*/
    /**
     * sets the status of the antifurto
     * @param {Boolean} status the new status of the antifurto
     * @returns {*} null if the status was changed
     */
    static setAntifurtoStatus = async status => {
        if (status == null || typeof status.stato !== 'boolean')
            throw new Error('status must be a set boolean');
        const url = `${Api.baseURL}antifurto/stato/`;
        const response = await fetch(url, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(status)
        });
        if (response.ok)
            return null;
        else
            throw await response.json();;
    };
    // /api/antifurto/allarme/
    /**
     * gets the status of the antifurto's alarm
     * @returns {*} the antifurto's alarm status
     */
    /*static getAntifurtoAllarme = async () => {
        const url = Api.baseURL + "antifurto/allarme/";
        const response = await fetch(url);
        const data = await response.json();
        if (response.ok)
            return data;
        else
            throw data;
    };*/
    /**
     * sets the status of the antifurto's alarm
     * @param {Boolean} allarme the new status of the antifurto's alarm
     * @returns {*} null if the status was changed
     */
    static setAntifurtoAllarme = async allarme => {
        if (allarme == null || typeof allarme.stato !== 'boolean')
            throw new Error("allarme must be a set boolean");
        const url = Api.baseURL + "antifurto/allarme/";
        const response = await fetch(url, {
            method: "PUT",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(allarme)
        });
        if (response.ok)
            return null;
        else
            throw await response.json();
    };
    // /api/antifurto/attenzione/
    /**
     * sets the status for the progress bar of the antifurto's alarm
     * @param {Number} attenzione the new value of the antifurto's attention
     * @returns {*} null if the value was changed 
     */
    static setAntifurtoAttenzione = async attenzione => {
        if (attenzione == null || isNaN(parseInt(attenzione)))
            throw new Error("attenzione must be a set integer");
        const val = parseInt(attenzione);
        if (val < 0 || val > 100)
            throw new Error("attenzione must be between 0 and 100");
        const url = Api.baseURL + "antifurto/attenzione/";
        const response = await fetch(url, {
            method: "PUT",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({attenzione:val})
        });
        if (response.ok)
            return null;
        else
            throw await response.json();
    };
    // /api/antifurto/soglia/
    /**
     * sets the value of the antifurto's threshold
     * @param {Number} soglia the user's value of the antifurto's threshold
     * @returns {*} null if the value was changed
     */
    static setAntifurtoSoglia = async soglia => {
        if (soglia == null || isNaN(parseInt(soglia)))
            throw new Error("soglia must be a set integer");
        const val = parseInt(soglia);
        if (val < 0 || val > 100)
            throw new Error("soglia must be between 0 and 100");
        const url = Api.baseURL + "antifurto/soglia/";
        const response = await fetch(url, {
            method: "PUT",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({soglia:val})
        });
        if (response.ok)
            return null;
        else
            throw await response.json();
    };
}

export default Api;