import {App} from "./App";
import debug from "debug";
import {WebsocketApp} from "./WebsocketApp";
import {Database} from "./database/Database";
import Ingredient from "./database/Ingredient";
import {iTender} from "./iTender";
import {iTenderStatus} from "./iTenderStatus";
import {Utils} from "./Utils";
import Container from "./database/Container";
import {Settings} from "./Settings";

const log = debug("itender:server");

const app = new App();
const wsApp = new WebsocketApp();


(async () => {
    try {
        log("Starting...");
        await Database.connect();
        //await test();
        await app.listen();
        await wsApp.listen();
        Settings.loadSettings();

        iTender.setStatus(iTenderStatus.STARTING);
        await Utils.sleep(2000);

        if (!Settings.setupDone) {
            iTender.setStatus(iTenderStatus.SETUP);
            log("iTender is not set up yet!");
        }


        function checkStart() {
            setTimeout(async () => {
                if (!Settings.setupDone) {
                    checkStart();
                    return;
                }
                Settings.saveSettings();


                await init();
                setInterval(refresh, 1000 * 60 * 10);
                iTender.setStatus(iTenderStatus.READY);
            }, 1000);
        }

        checkStart();

    } catch (e) {
        console.error("---- ERROR ----");
        console.error(e);
        process.exit(-1);
    }
})();

function init(): Promise<void> {
    log("Initializing...");
    return new Promise(async resolve => {
        iTender.setStatus(iTenderStatus.STARTING);

        // Network
        await iTender.checkNetwork();
        if (iTender.internetConnection) {
            await iTender.refreshFromServer();
        }

        // Containers
        //await iTender.refreshContainers();
        await iTender.measureContainers();
        // Drinks
        await iTender.refreshDrinks();
        // Start auto checkup for stuck jobs
        await iTender.autoCheckup();

        resolve();
    });
}

function refresh(): Promise<void> {
    return new Promise(async resolve => {
        // Network
        await iTender.checkNetwork();

        // Below are refreshments of containers / drinks

        // If there is a current job, DO NOT REFRESH!
        if (iTender.currentJob)
            return;

        //await iTender.refreshContainers(); Not needed because there is no change in containers?
        await iTender.measureContainers();
        //await iTender.refreshDrinks(); Not needed because there is no change in drinks?
    });
}

async function test() {
    console.log("Testing fn");

    /*
    let cola = new Ingredient();
    cola.name = "Cola";
    cola.category = Category.SOFTDRINK;
    await cola.save();

    let sprite = new Ingredient();
    sprite.name = "Sprite";
    sprite.category = Category.SOFTDRINK;
    await sprite.save();

    let fanta = new Ingredient();
    fanta.name = "Fanta";
    fanta.category = Category.SOFTDRINK;
    await fanta.save();

    let drink = new Drink();
    drink.name = "Fanta";
    drink.category = Category.ALCOHOL_FREE;
    drink.ingredients = [{type: fanta, amount: 200}];
    await drink.save();

    drink = new Drink();
    drink.name = "Mezzo Mix";
    drink.category = Category.ALCOHOL_FREE;
    drink.ingredients = [{type: fanta, amount: 100}, {type: cola, amount: 100}];
    await drink.save();*/

    let ingredient = await Ingredient.findOne({name: "Fanta"});
    if (!ingredient)
        return;

    /*let drink = new Drink();
    drink.name = "Cola";
    drink.ingredients = [{type: ingredient, amount: 200}];

    await drink.save();*/

    /* let drink = await Drink.findOne({name: "Cola"}).populate("ingredients.type");
     if (!drink) return;

     console.log(drink);*/

    /*let container = new Container();
    container.slot = 2;
    container.volume = 750;
    container.sensorEcho = 28;
    container.sensorTrigger = 29;
    container.content = ingredient;
    container.sensorFilledMax = 2;
    container.sensorFilledMin = 15;*/

    //await container.save();

    /* let container = await Container.findOne({slot: 1});
     if (!container) return;

     console.log(container);*/


    //console.log(drink.ingredients)
    /*let ingredient = new Ingredient();
    ingredient.name = "Cola";
    ingredient.category = Category.ALCOHOL_FREE;

    await ingredient.save();

    let ingredient2 = new Ingredient();
    ingredient2.name = "Fanta";
    ingredient2.category = Category.ALCOHOL_FREE;

    await ingredient2.save();

    let drink = new Drink();
    drink.name = "Mezzo Mix";
    drink.ingredients = [ {type: ingredient2, amount: 2}, { type: ingredient, amount: 10 } ];

    await drink.save();*/


}