//Inner state
var lastBrew = new Date(0);
var brewing = false;
var backoff = 2000;

//MQTT client config
var username = "coffee-user-"+ Math.random();
// eslint-disable-next-line no-undef
var client = new Paho.MQTT.Client("sika.sahkoinsinoorikilta.fi", 9001, username);
client.onMessageArrived = function (message) {
    // eslint-disable-next-line no-console
    console.log("Topic: "+message.destinationName+" msg: "+message.payloadString);
    var ev = new CustomEvent(message.destinationName, {'detail': message.payloadString});
    window.dispatchEvent(ev);
}

function reconnect(responseObject){
    if (responseObject.errorCode !== 0) {
        console.log("connection lost! Reason: "+responseObject.errorMessage); // eslint-disable-line no-console
        setTimeout(function(){
            client.connect({onSuccess:onConnect, useSSL:true, onFailure: reconnect});
        }, backoff);
    }
}

function onConnect() {
      console.log("MQTT connected"); // eslint-disable-line no-console
      //set and reset reconnector
      client.onConnectionLost = reconnect
      // subscribe to topics
      client.subscribe("sik/kiltahuone/kahvivaaka/cups");
      client.subscribe("sik/kiltahuone/kahvivaaka/brewing");
      client.subscribe("sik/kiltahuone/kahvivaaka/brewtime");
  }

// data update and parse functions
function parseCups(ev){
    var cups = parseFloat(ev.detail).toFixed(1)

    function makeEvent(cups) {
        return (String(cups) !== '-1.0')
            ? new CustomEvent("cupsChanged", {'detail': cups})
            : new CustomEvent("cupsError", {'detail': 'Error: unable to fetch cups :('});
    }
    
    window.dispatchEvent(makeEvent(cups));
}
function updateCups(ev){
    $("#text").text(ev.detail);
}
function showCupsError(ev) {
    $('#text').text(ev.detail);
    $('#text').css({
        'font-size': '7vh',
        'left': '0',
        'top': '40%',
        'width': '100%',
        'text-align': 'center',
        'color': 'red',
    });
    $('#lower').css({'background-image': 'none'});
}
function updateScale(ev){
     $("#scale2").css({width: Math.min(ev.detail/9*100,100) + '%'});
}

function tick(){
    var ev = new CustomEvent("tick", {'detail': new Date()});
    window.dispatchEvent(ev);
}

function updateTime(ev){
  var now = ev.detail;
  $("#time").html(formatTime(now.getHours(),now.getMinutes(),now.getSeconds()));
}

function coffeeLowEffect(ev){
    ev.detail <= 2 ? $("#text").addClass("hurry") : $("#text").removeClass("hurry");
}
function coffeeReadyEffect(){
    $("body").addClass("coffeeready");
    // autoclear animation class in 10s
    setTimeout(function(){$("body").removeClass("coffeeready");}, 10000);
}
function hotEffect(ev){
  var opa = Math.max(100 - ev.detail / 90000,0);
  $("#upper").css({opacity: opa/100});
}
function brewAnimStart(){
    $(".text").addClass("brewing");
    $(".layerone").hide();
    $(".layertwo").show();
}
function brewAnimEnd(){
    $(".text").removeClass("brewing");
    $(".layertwo").hide();
    $(".layerone").show();
}
function brewNotifier(ev){
    var new_brewing = parseInt(ev.detail);
    if (new_brewing == 1 && brewing == 0){
        window.dispatchEvent(new Event("brewStart"));
    } else if (new_brewing == 0 && brewing == 1){
        window.dispatchEvent(new Event("brewEnd"));
    }
    brewing = new_brewing;
}
function brewTimeParser(ev){
    lastBrew = new Date(parseInt(ev.detail)*1000.0);
}
function updateBrewDiff(){
    var now = new Date();
    var timeDiff = Math.max(now.getTime() - lastBrew.getTime(), 0);
    var eve = new CustomEvent("dtUpdate", {'detail': timeDiff});
    window.dispatchEvent(eve);
}
function updateBrewTime(ev){
  var timeDiff = ev.detail;
  var timeStr;
  if (timeDiff < 3600000){
    timeStr = Math.round(timeDiff / 60000) + ' min'
  } else if (timeDiff < 10000* 3600 * 1000){ // 1000h
    timeStr = '~' + Math.round(timeDiff / 3600000 * 2) / 2 + ' h';
  } else {
    timeStr = "???"
  }
  $("#brewtime").html(timeStr);
}

// Helpers

function nToS(num){
    return num < 10 ? "0" + num : "" + num;
}

function formatTime(hours, minutes, seconds){
  return nToS(hours)+":"+nToS(minutes)+":"+nToS(seconds)
}

function resize(){
  var w = $("#container").width();
  var h = $("#container").height();
  var s = w > h ? h : w;
  var font = s * 0.8 * 0.38/Math.sqrt(3);
  $(".text").css({ top: s*0.16-font/2 + 'px',
                   fontSize: font + 'px',
                   marginLeft: -font*3*3/10 + 'px'});
}

// Init everything

$(document).ready(function(){
 client.connect({onSuccess:onConnect, useSSL:true, onFailure:reconnect});

 //connect MQTT event listeners
 window.addEventListener("sik/kiltahuone/kahvivaaka/cups", parseCups);
 window.addEventListener("sik/kiltahuone/kahvivaaka/brewing", brewNotifier);
 window.addEventListener("sik/kiltahuone/kahvivaaka/brewtime", brewTimeParser);

 //connect other event listeners
 window.addEventListener("cupsChanged", updateCups);
 window.addEventListener("cupsChanged", coffeeLowEffect);
 window.addEventListener("cupsChanged", updateScale);
 window.addEventListener("cupsChanged", resize);

 window.addEventListener("cupsError", showCupsError);
 window.addEventListener("cupsError", coffeeLowEffect);
 window.addEventListener("cupsError", updateScale);

 window.addEventListener("brewStart", brewAnimStart);
 window.addEventListener("brewEnd", brewAnimEnd);
 window.addEventListener("brewEnd", coffeeReadyEffect);
 window.addEventListener("tick", updateTime);
 window.addEventListener("tick", updateBrewDiff);
 window.addEventListener("dtUpdate", updateBrewTime);
 window.addEventListener("dtUpdate", hotEffect);

 //start time based events
 setInterval(tick, 100);
 tick();

});
$(window).resize(resize);
