import os
from natsort import natsorted
from .widget_sources.Ui_elsa_maindialog import Ui_Dialog
from PyQt6 import QtCore, QtWidgets, QtGui
from PyQt6.QtGui import QRegularExpressionValidator
from PyQt6.QtCore import QDate
from src import Icon, logger
from src.backend import Semester, Database
from src.logic import elsa_word_to_csv, Prof
from src.ui.dialogs import ElsaAddEntry, popus_confirm
from src.ui.widgets import FilePicker, DataGraph


class ElsaDialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.table_elsa_list.setContextMenuPolicy(
            QtCore.Qt.ContextMenuPolicy.CustomContextMenu
        )
        self.table_elsa_list.customContextMenuRequested.connect(self.elsa_context_menu)
        # elsa buttons
        Icon("semester", self.active_semester)
        Icon("today", self.elsa_date_today)
        self.create_frame_elsa.setEnabled(False)
        self.elsa_add_new.clicked.connect(self.add_new_elsa)
        self.elsa_cancel_create.clicked.connect(self.cancel_elsa_creation)
        self.elsa_save.clicked.connect(self.save_elsa)
        self.elsa_date_today.clicked.connect(self.generateTodayDateElsa)
        self.active_semester.clicked.connect(self.addSemester)
        self.elsa_update.clicked.connect(self.update_elsa)
        self.elsa_table.doubleClicked.connect(self.open_elsa)
        self.btn_add_document_elsa.clicked.connect(self.addDokumentElsa)
        self.check_file_elsa.clicked.connect(self.parseDokumentElsa)
        self.btn_open_document_elsa.clicked.connect(self.openDocumentElsa)
        self.quote_entry.clicked.connect(self.elsa_table_entry)
        self.quote_entry.setEnabled(False)
        self.newProf.hide()
        self.splitter = QtWidgets.QSplitter(QtCore.Qt.Orientation.Horizontal)
        self.splitter.addWidget(self.media_table)
        self.splitter.addWidget(self.statistics)
        self.results.layout().removeWidget(self.media_table)
        self.results.layout().removeWidget(self.statistics)
        self.results.layout().addWidget(self.splitter)
        self.elsa_statistics_table.setColumnCount(2)
        # set header to occupy the whole width and auto scale based on table width
        self.elsa_statistics_table.horizontalHeader().setStretchLastSection(True)
        self.elsa_statistics_table.horizontalHeader().setSectionResizeMode(
            QtWidgets.QHeaderView.ResizeMode.Stretch
        )
        # if table size gets smaller, set horitzontal headers text to be left aligned
        self.elsa_statistics_table.horizontalHeader().setDefaultAlignment(
            QtCore.Qt.AlignmentFlag.AlignLeft
        )
        # self.table_elsa_list.
        Icon("person", self.prof_icon)
        # validators
        # prof mail
        self.newProf_mail.setValidator(
            QRegularExpressionValidator(
                QtCore.QRegularExpression(
                    r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}"
                )
            )
        )
        self.newProf_telnr.setValidator(QtGui.QIntValidator())
        self.newProf_telnr.setValidator(
            QtGui.QRegularExpressionValidator(QtCore.QRegularExpression(r"^\d{3,14}"))
        )

        ##Variables
        self.db = Database()
        self.graph_data = {"x": [""], "y": [0]}
        self.createProf = False
        self.profs = self.getProfs()

        self.elsa_prof.addItems([prof[0] for prof in self.profs])
        self.elsa_prof.addItem("")
        self.elsa_prof.setCurrentText("")
        # implement a check for the prof name. if name is not in list and has schema of lastname, firstname, show newProf frame
        self.elsa_prof.currentTextChanged.connect(self.checkProf)
        self.newProf_mail.textChanged.connect(self.checkProfData)
        self.newProf_telnr.textChanged.connect(self.checkProfData)
        self.newProf_title.textChanged.connect(self.checkProfData)

        self.loadFrame()
        logger.info("Elsa Dialog loaded")
        # self.show()

    def checkProfData(self):
        if (
            (self.newProf_mail.text() != "" and self.newProf_mail.hasAcceptableInput())
            and self.newProf_title.text() != ""
            and (
                self.newProf_telnr.text() != ""
                and self.newProf_telnr.hasAcceptableInput()
            )
        ):
            self.elsa_save.setEnabled(True)
            self.elsa_save.setToolTip("")
            self.newProf_mail.setToolTip("")
            self.newProf_telnr.setToolTip("")
        else:
            self.elsa_save.setEnabled(False)
            self.elsa_save.setToolTip("Bitte erst Daten eingeben")
            self.newProf_mail.setToolTip("Bitte geben Sie eine gültige E-Mail ein")
            self.newProf_telnr.setToolTip(
                "Bitte geben Sie eine gültige Telefonnummer ein"
            )

    def checkProf(self):
        if (
            ", " in self.elsa_prof.currentText()
            and self.elsa_prof.currentText() not in [prof[0] for prof in self.profs]
        ):
            self.newProf.show()
            self.elsa_save.setEnabled(False)
            self.elsa_save.setToolTip("Bitte erst Daten eingeben")
            self.createProf = True
        else:
            self.newProf.hide()
            self.createProf = False
            self.elsa_save.setEnabled(True)
            self.elsa_save.setToolTip("")

    def getProfs(self):
        profs = self.db.getProfs()
        profs = [
            ("{}, {}".format(prof.lastname, prof.firstname), prof.id) for prof in profs
        ]

        profs = list(set(profs))
        profs.sort()
        return profs

    def elsa_context_menu(self, position):
        QtWidgets.QMenu()
        # TODO: add functions
        pass

    def elsa_table_entry(self):
        data = ElsaAddEntry()
        selected_row = self.table_elsa_list.currentRow()
        signature = self.table_elsa_list.item(selected_row, 10).text()
        mediatype = self.table_elsa_list.item(selected_row, 11).text()
        pages = self.table_elsa_list.item(selected_row, 7).text().strip()
        data.searchIdent.setText(signature)
        match mediatype:
            case "Monografien":
                data.btn_mono.click()
            case "Herausgeberwerke":
                data.btn_hg.click()
            case "Zeitschriftenaufsätze":
                data.btn_zs.click()
        if ";" in pages:
            data.search()
        else:
            data.search(pages=pages)
        data.exec()

    def add_new_elsa(self):
        self.create_frame_elsa.setEnabled(True)
        self.elsa_cancel_create.setEnabled(True)
        self.dokument_list_elsa.setRowCount(0)

        self.elsa_save.setEnabled(True)
        self.elsa_update.setEnabled(False)
        self.elsa_prof.setFocus()

    def cancel_elsa_creation(self):
        self.create_frame_elsa.setEnabled(False)
        self.elsa_cancel_create.setEnabled(False)
        self.elsa_prof.setCurrentText("")
        self.elsa_date.setText("")
        self.elsa_semester.setText("")
        self.dokument_list_elsa.setRowCount(0)
        self.table_elsa_list.setRowCount(0)
        self.quote_entry.setEnabled(False)
        self.elsa_save.setEnabled(False)
        self.elsa_update.setEnabled(False)
        self.seperateEntries.setChecked(False)

    def generateTodayDateElsa(self):
        self.elsa_date.setText(QDate.currentDate().toString("dd.MM.yyyy"))

    def addSemester(self):
        self.elsa_semester.setText(Semester().value)

    def update_elsa(self):
        prof = self.elsa_prof.currentText()
        date = self.elsa_date.text()
        semester = self.elsa_semester.text()
        elsa_id = self.db.getElsaId(prof, semester, date)
        if elsa_id is None:
            return
        self.db.updateElsaApparat(elsa_id, prof, semester, date)
        self.elsa_update.setEnabled(False)
        self.cancel_elsa_creation()

    def confirm_popup(self, message: str, title: str):
        popup = popus_confirm(title=title)
        popup.textEdit.setReadOnly(True)
        popup.textEdit.setText(message)

        popup.exec()
        return popup.result()

    def save_elsa(self):
        if (
            self.elsa_prof.currentText() == ""
            or self.elsa_semester.text() == ""
            or self.elsa_date.text() == ""
        ):
            # warning message
            self.confirm_popup("Bitte füllen Sie alle Felder aus", title="Fehler")

            return

        prof = self.elsa_prof.currentText()
        semester = self.elsa_semester.text()
        date = self.elsa_date.text()
        profdata = Prof(
            firstname=prof.split(", ")[1],
            lastname=prof.split(", ")[0],
            mail=self.newProf_mail.text(),
            telnr=self.newProf_telnr.text(),
            title=self.newProf_title.text(),
            fullname=f"{prof.split(', ')[0]} {prof.split(', ')[1]}",
        )
        prof_id = self.db.getProfId(profdata)
        logger.debug(profdata, prof_id)

        if prof_id is None:
            self.db.createProf(profdata)
            prof_id = self.db.getProfId(prof)
            self.profs.append(
                "f{}, {}".format(profdata.lastname, profdata.firstname), prof_id
            )
        elsa_id = self.db.createElsaApparat(
            date,
            prof_id,
            semester,
        )

        if self.dokument_list_elsa.rowCount() > 0:
            files = []
            for i in range(self.dokument_list_elsa.rowCount()):
                filename = self.dokument_list_elsa.item(i, 0).text()
                filetype = self.dokument_list_elsa.item(i, 1).text()
                file_path = self.dokument_list_elsa.item(i, 3).text()
                file = {"name": filename, "path": file_path, "type": filetype}
                files.append(file)
            self.db.insertElsaFile(
                files,
                elsa_id,
            )
            logger.info("Stored {} files in the database", len(files))
        self.cancel_elsa_creation()
        self.refresh_elsa_table()
        self.elsa_prof.setCurrentText("")
        self.quote_entry.setEnabled(False)
        logger.info("Saved apparat to database, id {}", elsa_id)

    def refresh_elsa_table(self):
        self.elsa_table.setRowCount(0)
        elsa_apparats = self.db.getElsaApparats()
        for apparat in elsa_apparats:
            self.insert_elsa_into_table(apparat)

    def insert_elsa_into_table(self, apparat):
        self.elsa_table.insertRow(0)
        date = apparat[1]
        semester = apparat[2]
        prof = self.db.getProfNameById(apparat[3])
        self.elsa_table.setItem(0, 0, QtWidgets.QTableWidgetItem(prof))
        self.elsa_table.setItem(0, 1, QtWidgets.QTableWidgetItem(date))
        self.elsa_table.setItem(0, 2, QtWidgets.QTableWidgetItem(semester))
        return (semester, 1)

    def open_elsa(self):
        prof = self.elsa_table.item(self.elsa_table.currentRow(), 0).text()
        logger.info("prof", prof)
        date = self.elsa_table.item(self.elsa_table.currentRow(), 1).text()
        semester = self.elsa_table.item(self.elsa_table.currentRow(), 2).text()
        self.elsa_update.setEnabled(True)
        self.elsa_save.setEnabled(False)
        if self.elsa_prof.currentText() == prof and date == self.elsa_date.text():
            logger.debug("Same prof, stopping")
            return
        self.create_frame_elsa.setEnabled(True)
        self.dokument_list_elsa.setRowCount(0)
        self.table_elsa_list.setRowCount(0)
        self.elsa_cancel_create.setEnabled(True)
        # get elsa apparats, iterate over them and find the one where all matches
        elsa_apparats = self.db.getElsaApparats()
        elsa_id = None
        for apparat in elsa_apparats:
            if (
                apparat[1] == date
                and apparat[2] == semester
                and apparat[3] == self.db.getProfId({"profname": prof})
            ):
                elsa_id = apparat[0]
                break
        self.elsa_date.setText(date)
        self.elsa_semester.setText(semester)
        self.elsa_prof.setCurrentText(prof)
        logger.info("Elsa ID is {}", elsa_id)
        if elsa_id is None:
            return
        documents = self.db.getElsaFiles(elsa_id)
        for document in documents:
            self.dokument_list_elsa.insertRow(0)
            self.dokument_list_elsa.setItem(
                0, 0, QtWidgets.QTableWidgetItem(document[0])
            )
            self.dokument_list_elsa.setItem(
                0, 1, QtWidgets.QTableWidgetItem(document[1])
            )
            self.dokument_list_elsa.setItem(0, 2, QtWidgets.QTableWidgetItem("❌"))
            self.dokument_list_elsa.setItem(
                0, 3, QtWidgets.QTableWidgetItem("Database")
            )
        scans = self.db.getElsaMedia(elsa_id)
        if scans == []:
            self.create_frame_elsa.setEnabled(True)

        for scan in scans:
            self.setElsaRow(scan)

        self.quote_entry.setEnabled(True)
        # self.cancel_elsa_creation()

    def setElsaRow(self, scan):
        self.table_elsa_list.insertRow(0)
        self.table_elsa_list.setItem(
            0, 0, QtWidgets.QTableWidgetItem(scan["work_author"])
        )
        self.table_elsa_list.setItem(
            0, 1, QtWidgets.QTableWidgetItem(scan["section_author"])
        )
        self.table_elsa_list.setItem(0, 2, QtWidgets.QTableWidgetItem(scan["year"]))
        self.table_elsa_list.setItem(0, 3, QtWidgets.QTableWidgetItem(scan["issue"]))
        self.table_elsa_list.setItem(0, 4, QtWidgets.QTableWidgetItem(scan["edition"]))
        self.table_elsa_list.setItem(
            0, 5, QtWidgets.QTableWidgetItem(scan["work_title"])
        )
        self.table_elsa_list.setItem(
            0, 6, QtWidgets.QTableWidgetItem(scan["chapter_title"])
        )
        self.table_elsa_list.setItem(
            0,
            7,
            QtWidgets.QTableWidgetItem(scan["pages"]),
        )
        self.table_elsa_list.setItem(0, 8, QtWidgets.QTableWidgetItem(scan["location"]))
        self.table_elsa_list.setItem(
            0, 9, QtWidgets.QTableWidgetItem(scan["publisher"])
        )
        self.table_elsa_list.setItem(
            0, 10, QtWidgets.QTableWidgetItem(scan["signature"])
        )
        self.table_elsa_list.setItem(0, 11, QtWidgets.QTableWidgetItem(scan["type"]))

    def addDokumentElsa(self):
        picker = FilePicker()
        files = picker.pick_files()
        datalist = []
        for file in files:
            data = {}
            filename = file.split("/")[-1]
            filetype = filename.split(".")[-1]
            self.dokument_list_elsa.insertRow(0)
            self.dokument_list_elsa.setItem(0, 0, QtWidgets.QTableWidgetItem(filename))
            self.dokument_list_elsa.setItem(0, 1, QtWidgets.QTableWidgetItem(filetype))
            self.dokument_list_elsa.setItem(0, 2, QtWidgets.QTableWidgetItem("*"))
            self.dokument_list_elsa.setItem(0, 3, QtWidgets.QTableWidgetItem(file))
            # set tooltip of row 3 to the file path for each row
            self.dokument_list_elsa.item(0, 3).setToolTip(file)
            data["name"] = filename
            data["path"] = file
            data["type"] = filetype
            datalist.append(data)

    def parseDokumentElsa(self):
        if self.dokument_list_elsa.rowCount() == 0:
            return
        else:
            # get the file path of the selected file based on it's row
            row = self.dokument_list_elsa.currentRow()
            file = self.dokument_list_elsa.item(row, 3).text()
            if file == "Database":
                filename = self.dokument_list_elsa.item(row, 0).text()
                filetype = self.dokument_list_elsa.item(row, 1).text()

                file = recreateElsaFile(
                    filename=filename, filetype=filetype, open=False
                )
            data, _ = elsa_word_to_csv(file)
            elsa_id = self.db.getElsaId(
                self.db.getProfId(Prof(fullname=self.elsa_prof.currentText())),
                self.elsa_semester.text(),
                self.elsa_date.text(),
            )
            logger.debug(
                elsa_id,
                self.elsa_prof.currentText(),
                self.elsa_semester.text(),
                self.elsa_date.text(),
            )
            for row in data:
                if self.seperateEntries.isChecked():
                    if ";" in row["pages"]:
                        count = row["pages"].split(";")
                        for i in range(len(count)):
                            row["pages"] = count[i]
                            self.setElsaRow(
                                row,
                            )
                            self.db.addElsaMedia(row, elsa_id)
                else:
                    self.setElsaRow(row)
                    self.db.addElsaMedia(row, elsa_id)
        self.quote_entry.setEnabled(True)

    def openDocumentElsa(self):
        # open the selected document
        row = self.dokument_list_elsa.currentRow()
        location = self.dokument_list_elsa.item(row, 3).text()
        filetype = self.dokument_list_elsa.item(row, 1).text()
        filename = self.dokument_list_elsa.item(row, 0).text()
        if location == "Database":
            recreateElsaFile(filename, filetype, open=True)
        else:
            os.system(f"{filename}")

    def loadFrame(self):
        self.elsa_cancel_create.click()
        try:
            self.elsa_statistics.removeTab(1)
        except:
            logger.debug("No tab to remove")
        self.elsa_table.setRowCount(0)
        elsa_apparats = self.db.getElsaApparats()
        elsa_apparats = natsorted(elsa_apparats, key=lambda x: x[2], reverse=True)
        # x = semester, y = number of apparats

        for apparat in elsa_apparats:
            data = self.insert_elsa_into_table(apparat)
            semester = data[0]
            number = data[1]
            if semester not in self.graph_data["x"]:
                self.graph_data["x"].append(semester)
                self.graph_data["y"].append(number)
            else:
                index = self.graph_data["x"].index(semester)
                self.graph_data["y"][index] += number

        generateMissing = True if len(self.graph_data["x"]) > 1 else False
        graph = DataGraph(
            "ELSA Apparate pro Semester",
            self.graph_data,
            generateMissing,
            "Anzahl der Apparate",
        )
        logger.debug(self.graph_data)
        self.elsa_statistics_table.setRowCount(0)
        for i in range(len(self.graph_data["x"])):
            self.elsa_statistics_table.insertRow(0)
            self.elsa_statistics_table.setItem(
                0, 0, QtWidgets.QTableWidgetItem(self.graph_data["x"][i])
            )
            self.elsa_statistics_table.setItem(
                0, 1, QtWidgets.QTableWidgetItem(str(self.graph_data["y"][i]))
            )
        self.elsa_statistics.addTab(graph, "Graph")


def launch():
    logger.debug("Launching Elsa Dialog")
    app = QtWidgets.QApplication([])
    window = ElsaDialog()
    window.show()
    app.exec()
