import asyncio

import datetime

import math
import qasync
from PySide6 import QtWidgets, QtCore
from PySide6.QtCore import QTimer
from astropy.coordinates import Angle
from astropy.time import Time, TimeDelta
import astropy.units as u

from pybrotlib import BROT, Telemetry
from pybrotlib.components import TelescopeStatus
from .qt.status_ui import Ui_Status


class QStatus(QtWidgets.QWidget, Ui_Status):
    def __init__(self, parent=None) -> None:
        QtWidgets.QWidget.__init__(self, parent)
        self.setupUi(self)
        self.telemetry = Telemetry()
        self.brot: BROT | None = None
        QTimer.singleShot(100, self._update_values_loop)

    @qasync.asyncSlot()
    async def _update_values_loop(self) -> None:
        while True:
            try:
                await self._update_values()
            finally:
                await asyncio.sleep(0.5)

    @qasync.asyncSlot()
    async def _update_values(self) -> None:
        """Updates the values received from the Telescope."""
        if self.brot is None:
            return

        # current time
        now = Time.now()

        # something moving? -> orange
        if self.telemetry.AUXILIARY.DOME.MOTION_STATE == 0.0 and self.telemetry.AUXILIARY.DOME.REALPOS != 0.5:
            self.labelStatusDome.setStyleSheet("color: green")
        else:
            self.labelStatusDome.setStyleSheet("color: orange")

        shutter = self.brot.dome.shutter
        match self.telemetry.AUXILIARY.DOME.READY_STATE:
            case 0.0:
                self.labelStatusDome.setText("parked")
            case -1.0:
                self.labelStatusDome.setStyleSheet("color: red")
                self.labelStatusDome.setText("ERROR")
            case 8.0:
                self.labelStatusDome.setStyleSheet("color: violet")
                #self.labelStatusDome.setText(shutter + " -> tracking")
            case 1.0:
                pass
                #self.labelStatusDome.setText(shutter)
            case _:
                self.labelStatusDome.setText("unknown")

        #if self.brot.telescope.status == TelescopeStatus.INITPARK:
        #    telescope_state = f"readyness: {int(self.brot.telescope.initpark)} %"
        #else:
        telescope_state = self.brot.telescope.status.value

        match self.telemetry.TELESCOPE.MOTION_STATE:
            case 0.0:
                self.labelStatusTelescope.setStyleSheet("color: green")
                telescope_motion = "stopped"
            case 1.0:
                self.labelStatusTelescope.setStyleSheet("color: orange")
                telescope_motion = "sliding"
            case 8.0:
                self.labelStatusTelescope.setStyleSheet("color: violet")
                telescope_motion = "tracking"
            case _:
                self.labelStatusTelescope.setStyleSheet("color: red")
                telescope_motion = "unknown"

        match self.telemetry.TELESCOPE.STATUS.GLOBAL:
            case 0:
                self.labelStatusTelescope.setText(telescope_state + " " + telescope_motion)
            case 1 | 2 | _:
                self.labelStatusTelescope.setStyleSheet("color: red")
                match self.telemetry.TELESCOPE.STATUS.GLOBAL:
                    case 1:
                        self.labelStatusTelescope.setText("E-Stop triggered")
                    case 2:
                        self.labelStatusTelescope.setText("internal error")
                    case _:
                        self.labelStatusTelescope.setText("unknown")

        # coordinates
        ra = Angle(self.telemetry.POSITION.EQUATORIAL.RA_J2000 * 15 * u.deg)
        dec = Angle(self.telemetry.POSITION.EQUATORIAL.DEC_J2000 * u.deg)
        alt = Angle(self.telemetry.POSITION.HORIZONTAL.ALT * u.deg)
        az = Angle(self.telemetry.POSITION.HORIZONTAL.AZ * u.deg)
        self.labelRA.setText(ra.to_string(unit=u.hour, precision=1))
        self.labelDec.setText(dec.to_string(precision=1))
        self.labelAlt.setText(f"{alt.degree:.2f}°")
        self.labelAz.setText(f"{az.degree:.2f}°")

        # time values
        time = Time(self.telemetry.POSITION.LOCAL.JD, format="jd")
        self.labelJD.setText(f"{self.telemetry.POSITION.LOCAL.JD:.4f}")
        self.labelLocalTime.setText(time.isot.split("T")[1].split(".")[0])
        self.labelLST.setText(f"{self.telemetry.POSITION.LOCAL.SIDEREAL_TIME:.4f}")
