from PyQt5.QtCore import Qt, pyqtSlot
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QDockWidget, QTreeWidget, QTreeWidgetItem

# TODO: merge get_top_item() and get_nested_item() to a recursive generator

item_icons = {
    "Time": "time.png",
}

item_units = {
    # ENERGY units
    "Voltage": "V",
    "Current": "A",
    "Power": "W",
    "ApparentPower": "VA",
    "ReactivePower": "VAR",
    "Frequency": "Hz",
    "Total": "kWh",
    "Yesterday": "kWh",
    "Today": "kWh",
}

class TelemetryWidget(QDockWidget):
    def __init__(self, device, *args, **kwargs):
        super(TelemetryWidget, self).__init__(*args, **kwargs)
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.setWindowTitle(device.name)

        self.tree_items = {}

        self.tree = QTreeWidget()
        self.setWidget(self.tree)
        self.tree.setColumnCount(2)
        self.tree.setHeaderHidden(True)

        device.update_telemetry.connect(self.update_telemetry)

        self.device = device

    def get_top_item(self, name):
        item = self.tree_items.get(name)
        if not item:
            item = QTreeWidgetItem()
            item.setText(0, name)
            item.setIcon(0, QIcon("GUI/icons/{}".format(item_icons.get(name, ""))))
            self.tree.addTopLevelItem(item)
            self.tree_items[name] = item
        return item

    def get_nested_item(self, parent, name):
        nested_items = self.tree_items.get(parent)
        if nested_items:
            _top_item = nested_items["_top_item"]
            item = nested_items.get(name)
            if not item:
                item = QTreeWidgetItem()
                item.setText(0, name)
                item.setIcon(0, QIcon("GUI/icons/{}".format(item_icons.get(name, ""))))
                _top_item.addChild(item)
                nested_items[name] = item
            return item
        else:
            _top_item = QTreeWidgetItem()
            _top_item.setText(0, parent)
            self.tree.addTopLevelItem(_top_item)
            self.tree_items[parent] = {"_top_item": _top_item}

            item = QTreeWidgetItem()
            item.setText(0, name)
            _top_item.addChild(item)
            self.tree_items[parent][name] = item
            return item


    @pyqtSlot()
    def update_telemetry(self):
        t = self.device.t

        time = t.get("Time")

        time_item = self.get_top_item("Time")
        time_item.setText(1, time.replace("T", " "))

        for key in sorted(t.keys()):
            if key != "Time":
                v = t[key]
                if isinstance(v, dict):
                    for nested_key, nested_v in v.items():
                        nested_item = self.get_nested_item(key, nested_key)
                        nested_item.setText(1, "{} {}".format(nested_v, item_units.get(nested_key, "")))

                else:
                    item = self.get_top_item(key)
                    item.setText(1, "{}".format(v))

        self.tree.expandAll()
        self.tree.resizeColumnToContents(0)
        self.tree.resizeColumnToContents(1)
