# This Python file uses the following encoding: utf-8
import os
import io
import sys
import shutil
import base64
from docx import Document
from msoffice2pdf import convert
import pandas as pd
import requests
from PySide6.QtWidgets import QApplication, QWidget, QFileDialog
from PySide6.QtCore import QFile, QIODevice

# NOTE:
# You need to run the following command to generate the ui_form.py file
#     pyside6-uic form.ui -o ui_form.py, or
#     pyside2-uic form.ui -o ui_form.py
from ui_form import Ui_Widget

import resources_rc


class Widget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_Widget()
        self.ui.setupUi(self)
        self.setWindowTitle("AKMI Utilities")
        self.ui.file_selector.clicked.connect(self.file_selector)
        self.ui.file_template.clicked.connect(self.file_template)
        self.ui.create_button.clicked.connect(self.create_button)
        self.ui.enable_email.clicked.connect(self.enable_token)
        self.selected_file = False
        self.selected_template = False
        self.filepath_template = ""
        self.filepath = ""
        self.img_dir = os.path.join(os.path.dirname(__file__), "images")
        self.font_dir = os.path.join(os.path.dirname(__file__), "FONTS")

    def qrc_to_bytes(self, filename):
        file = QFile(filename)
        if not file.open(QIODevice.ReadOnly):
            raise RuntimeError(file.errorString())
            return
        f = io.BytesIO(file.readAll().data())
        return f

    def enable_create(self):
        if self.selected_file and self.selected_template:
            self.ui.create_button.setEnabled(True)

    def enable_token(self):
        print(self.ui.oauth2_token.isEnabled())
        if self.ui.oauth2_token.isEnabled():
            self.ui.oauth2_token.setEnabled(False)
        else:
            self.ui.oauth2_token.setEnabled(True)
            
    def file_selector(self):
        self.filepath = QFileDialog.getOpenFileName(self, "Επιλογή Αρχείου")
        if self.filepath[0]:
            ext = os.path.splitext(self.filepath[0])[-1].lower()
            if ext in [".xlsx", ".xls"]:
                self.ui.log_output.appendPlainText("Επιλέχθηκε το αρχείο δεδομενων: {}".format(self.filepath[0]))
                self.ui.label_3.setText("{}".format(self.filepath[0]))
                self.selected_file = True
                self.in_file = self.filepath[0]
                self.file_path = os.path.dirname(self.filepath[0])
            else:
                self.ui.label_3.setText("Το αρχείο πρέπει να είναι της μορφής .xlsx ή .xls")
                self.selected_file = False
        self.enable_create()

    def file_template(self):
        self.filepath_template = QFileDialog.getOpenFileName(self, "Επιλογή Αρχείου")
        if self.filepath_template[0]:
            ext = os.path.splitext(self.filepath_template[0])[-1].lower()
            if ext in [".docx", ".doc"]:
                self.ui.log_output.appendPlainText("Επιλέχθηκε το προσχέδιο: {}".format(self.filepath_template[0]))
                self.ui.label_4.setText("{}".format(self.filepath_template[0]))
                self.selected_template = True
                self.in_template = self.filepath_template[0]
                self.template_path = os.path.dirname(self.filepath_template[0])
            else:
                self.ui.label_4.setText("Το αρχείο πρέπει να είναι της μορφής .docx ή .doc")
                self.selected_template = False
                
        self.enable_create()

    def create_button(self):
        df = pd.read_excel("{}".format(self.filepath[0]))
        doc = Document("{}".format(self.filepath_template[0]))
        self.create_certificates(df, doc)    

    def replace_text_styled(self, paragraph, key, value):
        if key in paragraph.text:
            inline = paragraph.runs
            for i in range(len(inline)):
                if key in inline[i].text:
                    text = inline[i].text.replace(key, value)
                    inline[i].text = text

    def send_email(self, data_row, attachement):
        endpoint = "https://graph.microsoft.com/v1.0/me/sendMail"
        headers = {
            "Authorization": "{}".format(self.ui.oauth2_token.toPlainText()),
            "Content-Type": "application/json"
        }
        
        cert_file = open("./OUTPUT/{}".format(attachement), "rb")
        data = cert_file.read()
        
        email_data = {
            "message": {
                "subject": "ΠΙΣΤΟΠΟΙΗΤΙΚΟ ΠΑΡΑΚΟΛΟΥΘΗΣΗΣ ΣΕΜΙΝΑΡΙΟΥ: {}".format(data_row['ΘΕΜΑ ΣΕΜΙΝΑΡΙΟΥ']),
                "body": {
                    "contentType": "Text",
                    "content": "Χαίρετε,\nΣτο παρόν email επισυνάπτεται το πιστοποιητικό παρακολούθησης του σεμιναρίου {} που παρακολουθήσατε στη δομή {} το μήνα {}".format(data_row['ΘΕΜΑ ΣΕΜΙΝΑΡΙΟΥ'], data_row['CAMPUS'], data_row['DATE'])
                },
                "toRecipients": [
                    {
                        "emailAddress": {
                            "address": "{}".format(data_row['EMAIL'])
                        }
                    }
                ],
                "attachments": [
                    {
                        "@odata.type": "#microsoft.graph.fileAttachment",
                        "name": "{}".format(attachement),
                        "contentType": "application/pdf",
                        "contentBytes": base64.b64encode(data).decode('utf-8')
                    }
                    ]
            },
            "saveToSentItems": "true"
        }

        response = requests.post(endpoint, headers=headers, json=email_data)
        cert_file.close()

        if response.status_code == 202:
            self.ui.log_output.appendPlainText("Email στάλθηκε: {}".format(data_row['EMAIL']))
        else:
            self.ui.log_output.appendPlainText(f"Αποτυχία αποστολής. Status code: {response.status_code}, Error: {response.text}")
    
    def create_certificates(self, in_df, in_doc):
        if not os.path.exists("./OUTPUT"):
            os.makedirs("./OUTPUT")
            
        for index, row in in_df.iterrows():
            if row['ΟΝΟΜΑΤΕΠΩΝΥΜΟ'] in ['EMPTY', None] or pd.isna(row['ΟΝΟΜΑΤΕΠΩΝΥΜΟ']):
                student_name = "{} {} του {}".format(row['ΕΠΩΝΥΜΟ'],row['ΟΝΟΜΑ'], row['ΠΑΤΡΩΝΥΜΟ'])
            else:
                student_name = "{} {} του {}".format(row['ΟΝΟΜΑΤΕΠΩΝΥΜΟ'], row['ΠΑΤΡΩΝΥΜΟ'])

            mock_data = {
                'ΟΝΟΜΑΤΕΠΩΝΥΜΟ': student_name,
                'ΘΕΜΑ_ΣΕΜΙΝΑΡΙΟΥ': row['ΘΕΜΑ ΣΕΜΙΝΑΡΙΟΥ'],
                'DATE': row['DATE'],
                'CAMPUS': row['CAMPUS'],
                'EMAIL': row['EMAIL']
            }

            for paragraph in in_doc.paragraphs:
                for key in mock_data:
                    self.replace_text_styled(paragraph, key, mock_data[key])

            if os.path.exists("./edit.docx"):
                os.remove("./edit.docx")
            in_doc.save('edit.docx')
            
            output = convert(source="edit.docx", output_dir="./", soft=0)
            fname = output.rsplit('/')[-1]
            shutil.move("./{}".format(fname), "./OUTPUT/{}.pdf".format(student_name.replace(" ", "_")))

            print("PDF created: {}.pdf".format(student_name.replace(" ", "_")))
            if self.ui.enable_email.isChecked():
                self.send_email(row, attachement="{}.pdf".format(student_name.replace(" ", "_")))
            self.ui.label_4.setText(
                "Τα αρχείο PDF δημιουργήθηκαν εντός του φακέλου OUTPUT."
            )
            self.ui.create_button.setEnabled(False)
            
        if os.path.exists("./edit.docx"):
            os.remove("./edit.docx")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    widget = Widget()
    widget.show()
    sys.exit(app.exec())
