from __future__ import annotations

import pathlib

from nmreval.io.fcbatchreader import FCReader

from ..lib.utils import busy_cursor
from ..Qt import QtCore, QtWidgets, QtGui
from .._py.fcreader import Ui_FCEval_dialog


class QFCReader(QtWidgets.QDialog, Ui_FCEval_dialog):
    data_read = QtCore.pyqtSignal(list, str)

    def __init__(self, path=None, parent=None):
        super().__init__(parent=parent)
        self.setupUi(self)
        if path is None:
            path = pathlib.Path().home()
        self.path = path

        self.start_lineedit.setValidator(QtGui.QDoubleValidator())
        self.stop_lineedit.setValidator(QtGui.QDoubleValidator())

        self.graph_checkbox.stateChanged.connect(lambda x: self.graph_comboBox.setEnabled(not bool(x)))

        self.listWidget.installEventFilter(self)

    def eventFilter(self, src: QtCore.QObject, evt: QtCore.QEvent) -> bool:
        # intercept key press in listwidget to allow deletion with Del
        if evt.type() == QtCore.QEvent.KeyPress:
            if evt.key() == QtCore.Qt.Key_Delete:
                self.listWidget.takeItem(self.listWidget.currentRow())
                return True

        return super().eventFilter(src, evt)

    def add_graphs(self, graphs: list[tuple[str, str]]):
        for gid, graph_name in graphs:
            self.graph_comboBox.addItem(graph_name, gid)

    @QtCore.pyqtSlot(int, name='on_region_checkBox_stateChanged')
    def use_region(self, state: int):
        self.start_lineedit.setEnabled(state == QtCore.Qt.Checked)
        self.stop_lineedit.setEnabled(state == QtCore.Qt.Checked)

    @QtCore.pyqtSlot(name='on_file_pushbutton_clicked')
    @QtCore.pyqtSlot(name='on_dir_pushbutton_clicked')
    def get_input(self):
        if self.sender() == self.file_pushbutton:
            infiles, _ = QtWidgets.QFileDialog.getOpenFileNames(caption='Select HDF files',
                                                                directory=str(self.path),
                                                                filter='HDF files (*.h5)')

        else:
            infiles = QtWidgets.QFileDialog.getExistingDirectory(caption='Select input directory',
                                                                 directory=str(self.path),
                                                                 options=QtWidgets.QFileDialog.ShowDirsOnly)
            infiles = [infiles] if infiles else infiles

        if infiles:
            self.listWidget.addItems(infiles)
            self.path = pathlib.Path(infiles[-1]).parent
            self.label.setText(str(self.path))

    @QtCore.pyqtSlot(name='on_savebutton_clicked')
    def save_path(self):
        outfile = QtWidgets.QFileDialog.getExistingDirectory(self, caption='Select directory',
                                                             directory=self.label.text(),
                                                             options=QtWidgets.QFileDialog.ShowDirsOnly)
        if outfile:
            self.label.setText(outfile)

    def accept(self):
        items = [self.listWidget.item(i).text() for i in range(self.listWidget.count())]
        if items:
            with busy_cursor():
                self.read(items)

        self.close()

    def read(self, items):
        region = None
        if self.region_box.isChecked():
            start = None
            if self.start_lineedit.text():
                start = float(self.start_lineedit.text())*1e-6

            stop = None
            if self.stop_lineedit.text():
                stop = float(self.stop_lineedit.text())*1e-6
            region = (start, stop)

        fc_eval = FCReader(items)
        try:
            fc_eval.load_magnetization(region=region, overwrite=self.overwrite_cb.isChecked())
        except OSError as e:
            QtWidgets.QMessageBox.warning(self, 'Missing data', e.strerror)
            return

        fc_eval.fit(kww=self.kww_checkbox.isChecked(), save_fits=True, save_fig=True)

        save_variables = []
        for name, cb in [('t1', self.t1_cb), ('beta', self.beta_cb), ('m0', self.m0_cb), ('off', self.off_cb)]:
            if cb.isChecked():
                save_variables.append(name)

        ret_vals = []
        ret_vals.extend(fc_eval.get_parameter(path=self.label.text(), kind='temp', parameter=save_variables))

        grp = ''
        if not self.graph_checkbox.isChecked():
            grp = self.graph_comboBox.currentData(QtCore.Qt.UserRole)

        self.data_read.emit(ret_vals, grp)