import logging
from PyQt5.QtWidgets import (
    QGridLayout,
    QLabel,
    QGroupBox,
    QLineEdit,
    QCheckBox,
    QRadioButton,
    QHBoxLayout,
)
from tofu.ez.params import EZVARS
from tofu.ez.util import add_value_to_dict_entry, get_int_validator, get_double_validator

LOG = logging.getLogger(__name__)


class FFCGroup(QGroupBox):
    """
    Flat Field Correction Settings
    """

    def __init__(self):
        super().__init__()

        self.setTitle("Flat Field Correction")
        self.setStyleSheet("QGroupBox {color: indigo;}")

        self.method_label = QLabel("Method:")

        self.average_rButton = QRadioButton("Average")
        self.average_rButton.clicked.connect(self.set_method)

        self.ssim_rButton = QRadioButton("SSIM")
        self.ssim_rButton.clicked.connect(self.set_method)

        self.eigen_rButton = QRadioButton("Eigen")
        self.eigen_rButton.clicked.connect(self.set_method)

        self.enable_sinFFC_checkbox = QCheckBox(
            "Use Smart Intensity Normalization Flat Field Correction"
        )
        self.enable_sinFFC_checkbox.stateChanged.connect(self.set_sinFFC)

        self.eigen_pco_repetitions_label = QLabel("Eigen PCO Repetitions")
        self.eigen_pco_repetitions_entry = QLineEdit()
        self.eigen_pco_repetitions_entry.setValidator(get_int_validator())
        self.eigen_pco_repetitions_entry.editingFinished.connect(self.set_pcoReps)

        self.eigen_pco_downsample_label = QLabel("Eigen PCO Downsample")
        self.eigen_pco_downsample_entry = QLineEdit()
        self.eigen_pco_downsample_entry.setValidator(get_int_validator())
        self.eigen_pco_downsample_entry.editingFinished.connect(self.set_pcoDowns)

        self.downsample_label = QLabel("Downsample")
        self.downsample_entry = QLineEdit()
        self.downsample_entry.setValidator(get_int_validator())
        self.downsample_entry.editingFinished.connect(self.set_downsample)

        self.flat_scale_label = QLabel("Scale flats by a factor of")
        self.flat_scale_entry = QLineEdit()
        self.flat_scale_entry.setValidator(get_double_validator())
        self.flat_scale_entry.editingFinished.connect(self.set_flat_scale)

        self.reduction_label = QLabel("Reduction Mode:")
        self.median_reduction_rButton = QRadioButton("Median")
        self.median_reduction_rButton.clicked.connect(self.set_reduction_mode)
        self.average_reduction_rButton = QRadioButton("Average")
        self.average_reduction_rButton.clicked.connect(self.set_reduction_mode)

        self.set_layout()

    def set_layout(self):
        layout = QGridLayout()

        layout.addWidget(self.flat_scale_label, 0, 0)
        layout.addWidget(self.flat_scale_entry, 0, 1)

        reduction_layout = QHBoxLayout()
        reduction_layout.addWidget(self.reduction_label)
        reduction_layout.addWidget(self.average_reduction_rButton)
        reduction_layout.addWidget(self.median_reduction_rButton)

        layout.addLayout(reduction_layout, 1, 0, 1, 2)

        rbutton_layout = QHBoxLayout()
        rbutton_layout.addWidget(self.method_label)
        rbutton_layout.addWidget(self.eigen_rButton)
        rbutton_layout.addWidget(self.average_rButton)
        rbutton_layout.addWidget(self.ssim_rButton)

        layout.addWidget(self.enable_sinFFC_checkbox, 2, 0)
        layout.addItem(rbutton_layout, 3, 0, 1, 2)
        layout.addWidget(self.eigen_pco_repetitions_label, 4, 0)
        layout.addWidget(self.eigen_pco_repetitions_entry, 4, 1)
        layout.addWidget(self.eigen_pco_downsample_label, 5, 0)
        layout.addWidget(self.eigen_pco_downsample_entry, 5, 1)
        layout.addWidget(self.downsample_label, 6, 0)
        layout.addWidget(self.downsample_entry, 6, 1)

        self.setLayout(layout)

    def load_values(self):
        self.enable_sinFFC_checkbox.setChecked(EZVARS['flat-correction']['smart-ffc']['value'])
        self.set_method_from_params()
        self.set_reduction_mode_from_params()
        self.eigen_pco_repetitions_entry.setText(str(EZVARS['flat-correction']['eigen-pco-reps']['value']))
        self.eigen_pco_downsample_entry.setText(str(EZVARS['flat-correction']['eigen-pco-downsample']['value']))
        self.downsample_entry.setText(str(EZVARS['flat-correction']['downsample']['value']))
        self.flat_scale_entry.setText(str(EZVARS['flat-correction']['flat-scale']['value']))

    def set_flat_scale(self):
        LOG.debug(self.flat_scale_entry.text())
        dict_entry = EZVARS['flat-correction']['flat-scale']
        add_value_to_dict_entry(dict_entry, str(self.flat_scale_entry.text()))
        self.flat_scale_entry.setText(str(dict_entry['value']))

    def set_sinFFC(self):
        LOG.debug("sinFFC: " + str(self.enable_sinFFC_checkbox.isChecked()))
        dict_entry = EZVARS['flat-correction']['smart-ffc']
        add_value_to_dict_entry(dict_entry, self.enable_sinFFC_checkbox.isChecked())

    def set_pcoReps(self):
        LOG.debug("PCO Reps: " + str(self.eigen_pco_repetitions_entry.text()))
        dict_entry = EZVARS['flat-correction']['eigen-pco-reps']
        add_value_to_dict_entry(dict_entry, str(self.eigen_pco_repetitions_entry.text()))
        self.eigen_pco_repetitions_entry.setText(str(dict_entry['value']))

    def set_pcoDowns(self):
        LOG.debug("PCO Downsample: " + str(self.eigen_pco_downsample_entry.text()))
        dict_entry = EZVARS['flat-correction']['eigen-pco-downsample']
        add_value_to_dict_entry(dict_entry, str(self.eigen_pco_downsample_entry.text()))
        self.eigen_pco_downsample_entry.setText(str(dict_entry['value']))

    def set_downsample(self):
        LOG.debug("Downsample: " + str(self.downsample_entry.text()))
        dict_entry = EZVARS['flat-correction']['downsample']
        add_value_to_dict_entry(dict_entry, str(self.downsample_entry.text()))
        self.downsample_entry.setText(str(dict_entry['value']))

    def set_method(self):
        if self.eigen_rButton.isChecked():
            LOG.debug("Method: Eigen")
            EZVARS['flat-correction']['smart-ffc-method']['value'] = "eigen"
        elif self.average_rButton.isChecked():
            LOG.debug("Method: Average")
            EZVARS['flat-correction']['smart-ffc-method']['value'] = "average"
        elif self.ssim_rButton.isChecked():
            LOG.debug("Method: SSIM")
            EZVARS['flat-correction']['smart-ffc-method']['value'] = "ssim"

    def set_method_from_params(self):
        if EZVARS['flat-correction']['smart-ffc-method']['value'] == "eigen":
            self.eigen_rButton.setChecked(True)
            self.average_rButton.setChecked(False)
            self.ssim_rButton.setChecked(False)
        elif EZVARS['flat-correction']['smart-ffc-method']['value'] == "average":
            self.eigen_rButton.setChecked(False)
            self.average_rButton.setChecked(True)
            self.ssim_rButton.setChecked(False)
        elif EZVARS['flat-correction']['smart-ffc-method']['value'] == "ssim":
            self.eigen_rButton.setChecked(False)
            self.average_rButton.setChecked(False)
            self.ssim_rButton.setChecked(True)

    def set_reduction_mode(self):
        if self.median_reduction_rButton.isChecked():
            LOG.debug("Reduction Mode: Median")
            EZVARS['flat-correction']['reduction-mode']['value'] = "median"
        elif self.average_reduction_rButton.isChecked():
            LOG.debug("Reduction Mode: Average")
            EZVARS['flat-correction']['reduction-mode']['value'] = "average"

    def set_reduction_mode_from_params(self):
        if EZVARS['flat-correction']['reduction-mode']['value'] == "median":
            self.median_reduction_rButton.setChecked(True)
            self.average_reduction_rButton.setChecked(False)
        elif EZVARS['flat-correction']['reduction-mode']['value'] == "average":
            self.median_reduction_rButton.setChecked(False)
            self.average_reduction_rButton.setChecked(True)
