var mqttData = {};

const solarMQTT = {
    getMQTT: function () {
        const id = Math.random().toString(36).substring(7);
        const topic = "#";
        const connection = "wss://mqtt.nas.el-wa.org:443"
        mqttsolarTreeDone = false;
        // const connection = "ws://username:password@37.97.203.138:8083" // Works
        // const connection = "wss://public:public@public.cloud.shiftr.io" // Works
        const client = mqtt.connect(connection, {
            rejectUnauthorized: false,
        });

        client.on("message", messageReceived);
        client.on("connect", function () {
            client.subscribe("solarManager/#");
            client.subscribe("wattpilot/properties/lmo/state");
            client.subscribe("wattpilot/properties/ftt/state");
            client.subscribe("wattpilot/properties/fte/state");
            client.subscribe("wattpilot/properties/amp/state");
            client.subscribe("wattpilot/properties/car/state");
            client.subscribe("go-eCharger/270003/amp");
            client.subscribe("go-eCharger/270003/ate");
            client.subscribe("go-eCharger/270003/lmo");
            client.subscribe("go-eCharger/270003/att");
            client.subscribe("go-eCharger/270003/car");
            client.subscribe("weatherStation/#");
        });
        client.on("error", function (error) {
            //alert("MQTT Error: " + error);
        });
        client.on('end', function () {
            setTimeout(getMQTT, 5000);
            alert("MQTT Disconnected, try to reconnect in 5 secs.");
        })

        function getNestedProp(obj, path) {
            return path.split('/').reduce((acc, key) => acc && acc[key], obj);
        }
        function setNestedProp(obj, path, value) {
            var schema = obj;  // a moving reference to internal objects within obj
            var pList = path.split('/');
            var len = pList.length;
            for (var i = 0; i < len - 1; i++) {
            var elem = pList[i];
            if (!schema[elem]) schema[elem] = {}
            schema = schema[elem];
            }

            schema[pList[len - 1]] = value;
        }

        function messageReceived(topic, message) {
            setNestedProp(mqttData, topic, message);
            if (topic == "solarManager/P_Load") {
            setTimeout(function () { solarSVG.updateValuesMQTT(mqttData) }, 200); //give the object tree some time to build up and receive all values
            }
        }
    }
}

const solarSVG = {
    updateCnt: 99,
    updateValuesMQTT: function (mqttData) {
        if (this.updateCnt > 10) {
            this.updateCnt = 0;
            var obj = document.querySelector("object");
            var htmlNode = obj.contentDocument;
            htmlNode.getElementById("PufferOtxt").innerHTML = mqttData["solarManager"]["t_buffT"] + " °C";
            htmlNode.getElementById("PufferMtxt").innerHTML = mqttData["solarManager"]["t_buffM"] + " °C";
            htmlNode.getElementById("PufferUtxt").innerHTML = mqttData["solarManager"]["t_buffB"] + " °C";
            htmlNode.getElementById("heaterVL").innerHTML = mqttData["solarManager"]["t_heatVL"] + " °C";
            htmlNode.getElementById("heaterRL").innerHTML = mqttData["solarManager"]["t_heatRL"] + " °C";
            htmlNode.getElementById("thermeVLfb").innerHTML = mqttData["solarManager"]["t_gasVLu"] + " °C";
            htmlNode.getElementById("thermeVLww").innerHTML = mqttData["solarManager"]["t_gasVLo"] + " °C";
            htmlNode.getElementById("thermeRL").innerHTML = mqttData["solarManager"]["t_gasRL"] + " °C";
            htmlNode.getElementById("fbVL").innerHTML = mqttData["solarManager"]["t_fbVL"] + " °C";
            htmlNode.getElementById("fbRL").innerHTML = mqttData["solarManager"]["t_fbRL"] + " °C";
            htmlNode.getElementById("triac").innerHTML = mqttData["solarManager"]["t_triac"] + " °C";
        }
        this.updateCnt++;
    }

}

var chartSettings = {
    type: 'line',
    options: {
      animation: true,
      plugins: {
        annotation: {
          common: { type: 'box', drawTime: 'beforeDatasetsDraw', yScaleID: 'y-axis-0', backgroundColor: 'rgba(255, 255, 255, 0.05)', init: true },
          annotations: []
        },
        tooltip: {
          position: 'nearest',
          pointStyle: "circle",
          boxWidth: 4,
          usePointStyle: true,
          callbacks: {
            label: function (context) {
              let label = context.dataset.label || '';
              if (label) {
                label += ': ';
              }
              if (context.dataset.yAxisID == "y1") {
                label += Math.round(context.parsed.y * 10) / 10 + " " + "L/min";
              } else {
                if (context.parsed.y !== null) {
                  ret = scale(Math.round(context.parsed.y), false);
                  label += ret[0] + " " + ret[1] + "°C";
                }
              }
              return label;
            },
          },
        },
        legend: {
          position: "bottom",
          labels: {
            pointStyleWidth: 10,
            usePointStyle: true,
            pointStyle: "line",
          }
        },
      },
      responsive: true,
      maintainAspectRatio: false,
      interaction: {
        intersect: false,
        mode: 'index',
      },
      scales: {
        x: {
          adapters: {
            date: {
              locale: "DE-de"
            }
          },
          ticks: {

          },
          type: 'timestack',
        },
        y: {
          stacked: false,
          display: true,
          position: 'left',
          ticks: {
            callback: value => `${value} °C`,
          },
          title: {
            display: true,
            text: "Temperatur"
          }
        },
        y1: {
          stacked: false,
          display: true,
          position: 'right',
          ticks: {
            callback: value => `${value} L/min`,
          },
          title: {
            display: true,
            text: "Wasserverbrauch"
          },
          data:{}
        }
      }
    }
  };

  var chartData = {};
  const heatChart = new Chart(
    document.querySelector('#heat-chart'),
    Object.assign({}, chartSettings)
  );
  const waterChart = new Chart(
    document.querySelector('#water-chart'),
    Object.assign({}, chartSettings)
  );

  document.addEventListener('readystatechange', function () {
    if (event.target.readyState === "complete") {
      solarMQTT.getMQTT();
      getData(heatChart, 'ajax/getHeaterData.php');
      getData(waterChart, 'ajax/getWaterData.php');
    }
  });

  String.prototype.toHHMM = function () {
    var sec_num = parseInt(this, 10); // don't forget the second param
    var hours = Math.floor(sec_num / 3600);
    var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
    var seconds = sec_num - (hours * 3600) - (minutes * 60);

    if (hours < 10) { hours = "0" + hours; }
    if (minutes < 10) { minutes = "0" + minutes; }
    return hours + ':' + minutes;
  }

  async function getData(chart, url, sunrise=true) {
    try {
      console.log("fetching");
      const response = await fetch(url);
      if (!response.ok) {
        console.log("err");
        throw new Error(`Response status: ${response.status}`);
      }
      chart.data = await response.json();
      if(sunrise){
        const response2 = await fetch("ajax/getSunrise.php?FROM=-24&TO=0");
        if (!response2.ok) {
          console.log("err");
          throw new Error(`Response status: ${response2.status}`);
        }
        chart.options.plugins.annotation.annotations = await response2.json();
      }
      chart.update();
    } catch (error) {
      console.log(error.message);
    }
    setTimeout(function () { getData(chart, url, sunrise) }, 5 * 60 * 1000); //renew data every 5 min.
  }

  function powerToString(power) {
    if (Math.abs(power) > 999) {
      power = power / 1000
      return power.toPrecision(3) + " kW"
    } else {
      return Math.round(power) + " W"
    }

  }