from PySide6 import QtWidgets

from .InvariantUtils import WIDGETS

# local
from .UI.InvariantDetailsUI import Ui_Dialog

# ERROR_COLOR = wx.Colour(255, 0, 0, 128)
# EXTRAPOLATION_COLOR = wx.Colour(169, 169, 168, 128)
# INVARIANT_COLOR = wx.Colour(67, 208, 128, 128)


class DetailsDialog(QtWidgets.QDialog, Ui_Dialog):
    """
    This class stores some values resulting from invariant calculations.
    Given the value of total invariant, this class can also
    determine the percentage of invariants resulting from extrapolation.
    """

    def __init__(self, parent):
        super(DetailsDialog, self).__init__(parent)

        self.setupUi(self)

        DEFAULT_STYLE = """
        QProgressBar{
            border: 2px solid grey;
            border-radius: 5px;
            text-align: center
        }

        QProgressBar::chunk {
            background-color: #b1daf9;
            width: 10px;
            margin: 1px;
        }
        """
        self.setWindowTitle('Status')
        self.progressBarLowQ.setStyleSheet(DEFAULT_STYLE)
        self.progressBarData.setStyleSheet(DEFAULT_STYLE)
        self.progressBarHighQ.setStyleSheet(DEFAULT_STYLE)

        self.progressBarLowQ.setMinimum(0)
        self.progressBarLowQ.setMaximum(100)

        self.progressBarData.setMinimum(0)
        self.progressBarData.setMaximum(100)

        self.progressBarHighQ.setMinimum(0)
        self.progressBarHighQ.setMaximum(100)

        # Modify font in order to display Angstrom symbol correctly
        new_font = 'font-family: -apple-system, "Helvetica Neue", "Ubuntu";'
        self.lblQLowQUnits.setStyleSheet(new_font)
        self.lblQDataUnits.setStyleSheet(new_font)
        self.lblQHighQUnits.setStyleSheet(new_font)

        self.cmdOK.clicked.connect(self.accept)

        self.warning_msg = "No Details on calculations available...\n"

        # invariant total
        self.qstar_total = None
        self.qdata = None
        self.qhigh = None
        self.qlow = None
        self._model = None

        self.progress_low_qstar = 0.0
        self.progress_high_qstar = 0.0
        self.progress_data_qstar = 100.0

    def closeEvent(self, event):
        """Re-enables the status button when closed"""
        parent = self.parent()
        parent.cmdStatus.setEnabled(True)
        super().closeEvent(event)

    def setModel(self, model):
        """ """
        self._model = model

    def showDialog(self):
        """Fill the dialog with values of calculated Q, progress bars"""
        # Pull out data from the model
        self.qstar_total = float(self._model.item(WIDGETS.W_INVARIANT).text())

        # Reset progress counters
        self.progress_low_qstar = 0.0
        self.progress_high_qstar = 0.0
        self.progress_data_qstar = 100.0

        # Reset numerical values
        self.txtQData.setText(None)
        self.txtQDataErr.setText(None)
        self.txtQLowQ.setText(None)
        self.txtQLowQErr.setText(None)
        self.txtQHighQ.setText(None)
        self.txtQHighQErr.setText(None)

        # Q* from data
        self.qdata = float(self._model.item(WIDGETS.D_DATA_QSTAR).text())

        self.txtQData.setText(str(self.qdata))
        self.txtQDataErr.setText(self._model.item(WIDGETS.D_DATA_QSTAR_ERR).text())
        try:
            self.progress_data_qstar = (self.qdata / self.qstar_total) * 100.0
        except ZeroDivisionError:
            self.progress_data_qstar = "error"

        # Low-Q
        if self._model.item(WIDGETS.W_ENABLE_LOWQ_EX).text() == "true":
            self.qlow = float(self._model.item(WIDGETS.D_LOW_QSTAR).text())

            self.txtQLowQ.setText(str(self.qlow))
            self.txtQLowQErr.setText(self._model.item(WIDGETS.D_LOW_QSTAR_ERR).text())
            try:
                self.progress_low_qstar = (self.qlow / self.qstar_total) * 100.0
            except ZeroDivisionError:
                self.progress_low_qstar = "error"

        # High-Q
        if self._model.item(WIDGETS.W_ENABLE_HIGHQ_EX).text() == "true":
            self.qhigh = float(self._model.item(WIDGETS.D_HIGH_QSTAR).text())

            self.txtQHighQ.setText(str(self.qhigh))
            self.txtQHighQErr.setText(self._model.item(WIDGETS.D_HIGH_QSTAR_ERR).text())
            try:
                self.progress_high_qstar = (self.qhigh / self.qstar_total) * 100.0
            except ZeroDivisionError:
                self.progress_high_qstar = "error"

        # check values and display warning
        if self.checkValues():
            self.lblWarning.setText(self.checkValues())

        # update progress bars
        if self.progress_low_qstar == "error":
            self.progressBarLowQ.setValue(0)
        else:
            self.progressBarLowQ.setValue(int(self.progress_low_qstar))
            self.progressBarLowQ.setFormat("%.2f %%" % self.progress_low_qstar)

        if self.progress_high_qstar == "error":
            self.progressBarHighQ.setValue(0)
        else:
            self.progressBarHighQ.setValue(int(self.progress_high_qstar))
            self.progressBarHighQ.setFormat("%.2f %%" % self.progress_high_qstar)

        if self.progress_data_qstar == "error":
            self.progressBarData.setValue(0)
        else:
            self.progressBarData.setValue(int(self.progress_data_qstar))
            self.progressBarData.setFormat("%.2f %%" % self.progress_data_qstar)

        self.show()

    def checkValues(self):
        """
        Create a warning message to be displayed in panel
        if problems with values
        """

        if self.qstar_total is None:
            warning_msg = "Invariant not calculated.\n"
            return warning_msg
        elif self.qstar_total == 0:
            warning_msg = "Invariant is zero. \n The calculations are likely to be unreliable!\n"
            return warning_msg

        msg = ""
        if self.progress_data_qstar == "error":
            msg += "Error occurred when computing invariant from data.\n "
        try:
            if float(self.progress_data_qstar) > 100:
                msg += "Invariant Q contribution is greater than 100% .\n"
        except ValueError:
            # Text message, skip msg update
            pass

        if self.progress_low_qstar == "error":
            try:
                float(self.qlow)
            except ValueError:
                msg += "Error occurred when computing extrapolated invariant at low-Q region.\n"

        elif self.progress_low_qstar is not None:
            if self.progress_low_qstar >= 5:
                msg += "Extrapolated contribution at Low Q is higher than 5% of the invariant.\n"
            elif self.progress_low_qstar < 0:
                msg += "Extrapolated contribution at Low Q < 0.\n"
            elif self.progress_low_qstar > 100:
                msg += "Extrapolated contribution at Low Q is greater than 100% .\n"

        # High-Q
        if self.progress_high_qstar == "error":
            try:
                float(self.qhigh)
            except ValueError:
                msg += "Error occurred when computing extrapolated invariant at high-Q region.\n"

        elif self.progress_high_qstar is not None:
            if self.progress_high_qstar >= 5:
                msg += "Extrapolated contribution at High Q is higher than 5% of the invariant.\n"
            elif self.progress_high_qstar < 0:
                msg += "Extrapolated contribution at High Q < 0.\n"
            elif self.progress_high_qstar > 100:
                msg += "Extrapolated contribution at High Q is greater than 100% .\n"

        if (
            (self.progress_low_qstar not in [None, "error"])
            and (self.progress_high_qstar not in [None, "error"])
            and self.progress_low_qstar + self.progress_high_qstar >= 5
        ):
            msg += "The sum of all extrapolated contributions is higher than 5% of the invariant.\n"

        if msg == "":
            msg = "No Warnings to report\n"

        return msg
