import os.path
import time

from PySide6.QtCore import QTimer, QObject, Signal
from PySide6.QtWidgets import QFileDialog
from PySide6.QtQml import QQmlApplicationEngine

from .bms import BMSData
from .profile_handler import ProfileHandler, ProfileState


class GUI(QObject):
    _profile_handler: ProfileHandler
    _engine: QQmlApplicationEngine
    _win: QObject
    _update_timer: QTimer
    _profile_chooser_btn: QObject
    _start_pause_btn: QObject
    _stop_btn: QObject

    def __init__(self, profile_handler: ProfileHandler, bmsUpdated: Signal):
        super().__init__(None)

        self._engine = QQmlApplicationEngine()
        qml_path = os.path.join(
            os.path.dirname(__file__), "..", "ui", "main_window.qml"
        )
        self._engine.load(qml_path)
        self._win = self._engine.rootObjects()[0]
        self._win.setProperty("profile_handler", profile_handler)

        self._profile_chooser_btn = self._win.findChild(QObject, "profile_chooser")
        self._profile_chooser_btn.clicked.connect(self._choose_profile)

        self._start_pause_btn = self._win.findChild(QObject, "start_pause")
        self._start_pause_btn.clicked.connect(self._start_pause)
        self._stop_btn = self._win.findChild(QObject, "stop")
        self._stop_btn.clicked.connect(self._stop)
        self._profile_handler = profile_handler
        self._profile_handler.finished.connect(self._stop)

        self._update_timer = QTimer()
        self._update_timer.timeout.connect(self._update)
        self._update_timer.start(100)

        bmsUpdated.connect(self._updateBMS)

    def _choose_profile(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.FileMode.ExistingFile)
        dlg.setNameFilter("Profiles (*.csv)")
        if not dlg.exec():
            return

        profile_path = dlg.selectedFiles()[0]
        print(f"Profile: {profile_path}")
        self._profile_handler.load_profile(profile_path)

        self._win.setProperty("profile", profile_path)
        self._win.findChild(QObject, "start_pause").setProperty("enabled", True)

    def _start_pause(self):
        if self._profile_handler.state == ProfileState.STOPPED:
            self._profile_handler.start()
            self._start_pause_btn.setProperty("text", "PAUSE")
            self._stop_btn.setProperty("enabled", True)
            self._profile_chooser_btn.setProperty("enabled", False)
            # TODO: Start logging
        elif self._profile_handler.state == ProfileState.RUNNING:
            self._profile_handler.pause()
            self._start_pause_btn.setProperty("text", "RESUME")
        else:
            self._profile_handler.resume()
            self._start_pause_btn.setProperty("text", "PAUSE")

    def _stop(self):
        self._start_pause_btn.setProperty("text", "START")
        self._stop_btn.setProperty("enabled", False)
        self._profile_chooser_btn.setProperty("enabled", True)

    def _update(self):
        if self._profile_handler.state == ProfileState.RUNNING:
            dt = time.time() - self._profile_handler.profile_start
            self._win.setProperty("profileTime", dt)

    def _updateBMS(self, data: BMSData):
        self._win.setProperty("voltage_min", min(data.voltages))
        self._win.setProperty("voltage_max", max(data.voltages))
        self._win.setProperty("temp_min", min(data.temperatures))
        self._win.setProperty("temp_max", max(data.temperatures))
        self._win.setProperty("bmsError", str(data.error))
        self._win.setProperty("currentActual", data.current)
        self._win.setProperty("currentIntegrated", data.current_integrated)
