from __future__ import annotations

import pathlib

from ..Qt import QtWidgets, QtCore


class FileDialog(QtWidgets.QFileDialog):
    last_path = None

    def __init__(self, directory=None, caption=None, filter='', mode='open', parent=None):
        super().__init__(parent=parent)

        self.setOption(QtWidgets.QFileDialog.DontUseNativeDialog, True)
        self.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen if mode == 'open' else QtWidgets.QFileDialog.AcceptSave)

        self.setWindowTitle(caption)
        if directory:
            self.setDirectory(str(directory))
        elif self.last_path is not None:
            self.setDirectory(str(FileDialog.last_path))

        self.setNameFilters(filter.split(';;'))

        file_tree = self.findChild(QtWidgets.QTreeView, 'treeView')
        file_tree.setSortingEnabled(True)
        for i in range(file_tree.header().count()):
            file_tree.header().setSectionResizeMode(i, 0)
        file_tree.model().sort(0)

        file_list = self.findChild(QtWidgets.QListView, 'listView')
        file_list.model().sort(0)

        line = QtWidgets.QFrame(self)
        line.setFrameShape(line.HLine)
        line.setFrameShadow(line.Sunken)
        self.layout().addWidget(line, self.layout().rowCount(), 0, 1, self.layout().columnCount())

    def save_file(self) -> pathlib.Path | None:
        outfile = self.selectedFiles()
        if outfile:
            if self.is_valid(outfile[0]):
                return pathlib.Path(outfile[0])
            else:
                _ = QtWidgets.QMessageBox.warning(self, 'Save file',
                                                  'Filename contains one or more invalid character: / * < > \\ | : "')
        return

    @staticmethod
    def is_valid(filename: str):
        return True

        # bad_character = r'/*<>\|:"'
        # for c in bad_character:
        #     if c in filename:
        #         return False
        #
        # return True

    def close(self):
        FileDialog.last_path = self.directory()
        super().close()


class OpenFileDialog(FileDialog):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.setFileMode(QtWidgets.QFileDialog.ExistingFiles)

        self.checkBox = QtWidgets.QCheckBox(self)
        self.checkBox.setChecked(False)
        self.checkBox.setText('Use existing graph')
        self.checkBox.stateChanged.connect(self.checkbox_state)
        self.layout().addWidget(self.checkBox)

        self.comboBox = QtWidgets.QComboBox(self)
        self.comboBox.setEnabled(False)
        self.layout().addWidget(self.comboBox)

        self.add_to_graph = None

    def set_graphs(self, graphs):
        self.comboBox.blockSignals(True)
        for gid, name in graphs:
            self.comboBox.addItem(name, userData=gid)
        self.comboBox.blockSignals(False)

        if not self.comboBox.count():
            self.comboBox.hide()
            self.checkBox.hide()

    def checkbox_state(self, checked: QtCore.Qt.CheckState):
        if checked == QtCore.Qt.Checked:
            self.comboBox.setEnabled(True)
            self.add_to_graph = self.comboBox.currentData()
        else:
            self.comboBox.setEnabled(False)
            self.add_to_graph = None

    @QtCore.pyqtSlot(int, name='on_comboBox_currentIndexChanged')
    def graph_changed(self, idx: int):
        self.add_to_graph = self.comboBox.itemData(idx)


class SaveDirectoryDialog(FileDialog):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.setOption(QtWidgets.QFileDialog.DontConfirmOverwrite, False)
        self.setAcceptMode(QtWidgets.QFileDialog.AcceptSave)

        lay = self.layout()

        self.label = QtWidgets.QLabel(self)
        self.label.setTextFormat(QtCore.Qt.RichText)
        self.label.setText('Use <b>&lt;label&gt;</b> as placeholder in filename. (e.g. <i>t1_&lt;label&gt;.dat</i>)')
        lay.addWidget(self.label, lay.rowCount(), 0, 1, lay.columnCount())

        line = QtWidgets.QFrame(self)
        line.setFrameShape(line.HLine)
        line.setFrameShadow(line.Sunken)
        lay.addWidget(line, lay.rowCount(), 0, 1, lay.columnCount())

        h_layout = QtWidgets.QHBoxLayout()
        h_layout.setContentsMargins(0, 0, 0, 0)
        h_layout.setSpacing(3)

        self.checkBox = QtWidgets.QCheckBox(self)
        self.checkBox.setChecked(True)
        self.checkBox.setText('Replace spaces with _')
        h_layout.addWidget(self.checkBox)

        self.agr_cb = QtWidgets.QCheckBox(self)
        self.agr_cb.setChecked(True)
        self.agr_cb.setText('Save graph as Grace file')
        h_layout.addWidget(self.agr_cb)

        self.fit_cb = QtWidgets.QCheckBox(self)
        self.fit_cb.setChecked(True)
        self.fit_cb.setText('Save fit parameter')
        h_layout.addWidget(self.fit_cb)

        lay.addLayout(h_layout, lay.rowCount(), 0, 1, lay.columnCount())

        self.setWindowTitle('Save')
        self.setNameFilters(['All files (*.*)', 'Session file (*.nmr)', 'Text file (*.dat)',
                             'HDF file (*.h5)', 'Grace files (*.agr)'])
