import re
import sys

import tkinter as tk
from tkinter import messagebox, filedialog, ttk

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
import os

from PyQt5 import QtGui
from PyQt5.QtWidgets import QApplication, QDialog, QComboBox, QVBoxLayout, QLabel
from PyQt5.QtCore import QSize, Qt
from PyQt5 import QtWidgets
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import *
from PyQt5.QtGui import * 

from pysender.outlook import OutlookClient

class FormButton(QPushButton):
    def __init__(self, text):
        super(FormButton, self).__init__()
        self.setText(text)
        self.setMinimumWidth(5)

class MiComboBox(QWidget):
    def __init__(self):
        super().__init__()

        self.comboBox = QComboBox(self)
        #self.comboBox.setGeometry(50, 50, 400, 35)
        self.comboBox.addItems()

        self.btn = QPushButton('Click', self)
        #self.btn.setGeometry(170, 120, 120, 35)
        self.btn.clicked.connect(self.getComboValue)

    def getComboValue(self):
        print((self.comboBox.currentText(), self.comboBox.currentIndex()))

class FormLabel(QLabel):
    def __init__(self, text):
        super(FormLabel, self).__init__()
        self.setText(text)
        # Configuración de fuente y tamaño
        self.setFont(QFont('Arial', 11))
        self.setMinimumWidth(60)


class AboutDialog(QMessageBox):
    def __init__(self):
        super(AboutDialog, self).__init__()
        self.setWindowTitle("Acerca de")
        # Configuración de fuente y tamaño
        self.setFont(QFont('Arial', 11))

        self.setIcon(QMessageBox.Information)
        self.setText("PySender version 1.0.0")
        self.setInformativeText("Envío masivo de correo electrónico desde Outlook. "
                                "Asegúrese de tener Outlook instalado en su sistema. "
                                "¿Dudas?, comunicarse con ")

        self.setStandardButtons(QMessageBox.Close)


class ErrorDialog(QMessageBox):
    def __init__(self, title, message):
        super(ErrorDialog, self).__init__()
        self.setWindowTitle("Error")

        self.setIcon(QMessageBox.Warning)
        self.setText(title)
        self.setInformativeText(message)

        self.setStandardButtons(QMessageBox.Ok)


class MessageForm(QWidget):
    def __init__(self):
        super(MessageForm, self).__init__()
        # Configuración de fuente y tamaño
        self.setFont(QFont('Montserrat', 11))

        self.from_field = QLineEdit()
        self.from_field.setDisabled(True)
        self.to_field = QLineEdit() #QTextEdit()
        self.cc_field = QLineEdit()     ##
        self.bcc_field = QLineEdit()    ##
        self.subject_field = QLineEdit()
        self.message_field = QTextEdit()
        self.Attach_field = QLineEdit()       ##
        self.Attach_field.setDisabled(True)   ##

        self.init_widgets()

    def init_widgets(self):
        address_form = QGridLayout()
        address_form.setSpacing(10)
        address_form.addWidget(FormLabel("De:"), 1, 0)
        address_form.addWidget(self.from_field, 1, 1)
        address_form.addWidget(FormButton("Para:"), 2, 0)        
        address_form.addWidget(self.to_field, 2, 1)
        address_form.addWidget(FormLabel("CC:"), 3, 0)  ##
        address_form.addWidget(self.cc_field, 3, 1)     ##
        address_form.addWidget(FormLabel("BCC:"), 4, 0) ##
        address_form.addWidget(self.bcc_field, 4, 1)    ##

        attachment_form = QGridLayout()
        attachment_form.setSpacing(10)
        #toolbar = self.addToolBar("Tools")
        window = QWidget()
        
        ## **
        # Crear una etiqueta para mostrar la ruta del archivo adjunto
        ##attachment_label = tk.Label(window, text="Ningún archivo seleccionado", anchor="w")
        ##style = ttk.Style()
        ##style.configure("Custom.TButton", padding=(0,0,0,0), font=('Arial', 12),anchor='center')
        ##style.map("Custom.TButton",
                  ##foreground=[('pressed', 'black'), ('active', 'black'), ('!disabled', 'black')],
                  ##background=[('pressed', '!disabled', 'white'), ('active', 'white')])
        ## **
        
        self.browse_button = QtWidgets.QPushButton("📎")
        self.browse_button.clicked.connect(self.browse_file)
        attachment_form.addWidget(self.browse_button, 1, 0)
        
        self.file_combobox = QtWidgets.QComboBox(self)              ##
        self.file_combobox.setObjectName("comboBox")                ##
        # Haciéndolo si o no editable (True o False)
        self.file_combobox.setEditable(True)                        ##
        self.file_combobox.activated.connect(self.elegirLista)
        attachment_form.addWidget(self.file_combobox, 1, 1, 1, 1)   ##

        self.remove_button = QtWidgets.QPushButton("❌")             ##
        self.remove_button.clicked.connect(self.remove_file)        ##
        attachment_form.addWidget(self.remove_button, 2, 0)         ##
        
        attachment_form.addWidget(self.Attach_field, 2, 1, 1, 1)    ##

        message_form = QGridLayout()
        message_form.setSpacing(10)
        message_form.addWidget(FormLabel("Asunto:"), 1, 0)
        message_form.addWidget(self.subject_field, 1, 1)
        message_form.addWidget(FormLabel("Cuerpo de mensaje:"), 2, 0)
        message_form.addWidget(self.message_field, 2, 1)    #, 2, 1)

        address_group = QGroupBox("Dirección")
        address_group.setLayout(address_form)

        attachment_group = QGroupBox("Adjuntar")
        attachment_group.setLayout(attachment_form)

        message_group = QGroupBox("Mensaje")
        message_group.setLayout(message_form)

        main_layout = QBoxLayout(QBoxLayout.Down)
        main_layout.addWidget(address_group)
        main_layout.addWidget(attachment_group)
        main_layout.addWidget(message_group)

        self.setLayout(main_layout)

## *******************************************INICIO ARCHIVOS ADJUNTOS*******************************************
    #Definir la función con la que se trabajará el ComboBox
    def elegirLista(self):
        #print((self.comboBox.currentText(), self.comboBox.currentIndex()))
        print((self.file_combobox.currentText(), self.file_combobox.currentIndex()))


    def clear_text_input(self):
        text_input.delete('1.0', tk.END)
        e1.delete(0, tk.END)
        subj.delete(0, tk.END)
        self.attachment_label.config(text="Ningún archivo seleccionado")
        self.file_combobox["values"] = []
        self.file_combobox.set("")

    def browse_file(self):
        file_paths = filedialog.askopenfilenames(filetypes=[("Todos los archivos", "*.*")])
        if len(file_paths) == 0 and self.attachment_label["text"] == "Ningún archivo seleccionado":
            self.attachment_label.config(text="Ningún archivo seleccionado")
            self.file_combobox["values"] = []
        else:
            attachment_path = self.attachment_label["text"]
            if attachment_path!='Ningún archivo seleccionado':
                file_paths = [file_path for file_path in file_paths if file_path not in attachment_path.split(", ")]
                file_paths = (attachment_path.split(", ")) + file_paths
            self.file_combobox["values"] = [file_name.split('/')[-1] for file_name in file_paths]
            self.attachment_label.config(text=", ".join(file_paths))
            self.file_combobox.current(len(file_paths)-1)

    def remove_file(self):
        selected_item = self.file_combobox.get()
        if len(selected_item)!=0:
            attachment_path = self.attachment_label["text"]
            attachment_path = attachment_path.split(", ")
            attachment_path = [path for path in attachment_path if path.split('/')[-1] != selected_item]
            self.attachment_label.config(text=", ".join(attachment_path))
            self.file_combobox["values"] = [file_name.split('/')[-1] for file_name in attachment_path]
            if(len(attachment_path)==0):
                self.file_combobox.set("")
                self.attachment_label.config(text="Ningún archivo seleccionado")
            else:
                self.file_combobox.current(0)
        else:
            messagebox.showerror("Error", "Ningún archivo seleccionado")
## *******************************************FINAL ARCHIVOS ADJUNTOS*******************************************

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.message_form = MessageForm()
        # Configuración de fuente y tamaño
        self.setFont(QFont('Arial', 11))

        self.init_window()
        self.init_menubar()

        self.statusBar()
        self.show()

    def init_window(self):
        self.setWindowTitle("ENVÍO DE EMAIL MASIVO")
        self.setCentralWidget(self.message_form)
        self.resize(800, 600)

    def init_menubar(self):
        # Configuración de fuente y tamaño
        self.setFont(QFont('Arial', 11))

        quit_action = QAction("&Quitar", self)
        quit_action.setIcon(self.style().standardIcon(QStyle.SP_TitleBarCloseButton))
        quit_action.setShortcut("Ctrl+Q")
        quit_action.setStatusTip("Cerrar la aplicación")
        quit_action.triggered.connect(self.quit_application)

        send_action = QAction("&Enviar", self)
        send_action.setIcon(self.style().standardIcon(QStyle.SP_DialogApplyButton))
        send_action.setShortcut("Ctrl+Enter")
        send_action.setStatusTip("Enviar mensaje a todos los destinatarios")
        send_action.triggered.connect(self.send_message)

        reset_action = QAction("&Restablecer", self)
        reset_action.setIcon(self.style().standardIcon(QStyle.SP_DialogResetButton))
        reset_action.setShortcut("Ctrl+Del")
        reset_action.setStatusTip("Restablecer todos los datos ingresados")
        reset_action.triggered.connect(self.reset_input)

        about_action = QAction("&Acerca de", self)
        about_action.setStatusTip("Mostrar información de la aplicación")
        about_action.triggered.connect(self.show_info)

        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu("&Archivo")
        file_menu.addAction(quit_action)

        action_menu = menu_bar.addMenu("&Acción")
        action_menu.addActions([send_action, reset_action])

        about_menu = menu_bar.addMenu("&Ayuda")
        about_menu.addAction(about_action)

        tool_bar = self.addToolBar("Main")
        tool_bar.setIconSize(QSize(18, 18))
        ##tool_bar.setIconSize(QSize(24, 24))
        tool_bar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        tool_bar.addActions([send_action, reset_action])

    def send_message(self):
        #address_to = self.message_form.to_field.toPlainText()
        address_to = self.message_form.to_field.text()
        address_cc = self.message_form.cc_field.text()  ##
        address_bcc = self.message_form.bcc_field.text()  ##
        subject = self.message_form.subject_field.text()
        body_plain = self.message_form.message_field.toPlainText()
        body_html = self.message_form.message_field.toHtml()

        if not address_to:
            dialog = ErrorDialog("Datos faltantes", "Por favor complete el campo \"Para\" con las direcciones de Correo electrónico de los destinatarios.")
            dialog.exec_()
            return
        else:
            address_to = re.sub(r"\s+", ";", address_to)

        if not subject:
            dialog = ErrorDialog("Datos faltantes", "Por favor complete el campo \"Asunto\" con el asunto del correo electrónico.")
            dialog.exec_()
            return

        if not body_plain or not body_html:
            dialog = ErrorDialog("Datos faltantes", "Por favor complete el campo \"Cuerpo del mensaje\" con algún contenido.")
            dialog.exec_()
            return

### **
        # Adjuntar el archivo
        attachment_path = self.attachment_label["text"]
        if attachment_path!='Ningún archivo seleccionado':
            for path in attachment_path.split(", "):
                with open(path, "rb") as attachment_file:
                    attachment = MIMEApplication(attachment_file.read())

                attachment.add_header(
                    "Content-Disposition",
                    "attachment",
                    filename=os.path.basename(path)
                )
                message.attach(attachment)

### **
        outlook_client = OutlookClient()
        outlook_client.send_email(address_to, address_cc, address_bcc, subject, body_plain, body_html)

        clear_text_input()

    def reset_input(self):
        self.message_form.to_field.setText("")
        self.message_form.cc_field.setText("")
        self.message_form.bcc_field.setText("")
        self.message_form.subject_field.setText("")
        self.message_form.message_field.setText("")

    @staticmethod
    def show_info(self):
        dialog = AboutDialog()
        dialog.exec_()

    @staticmethod
    def quit_application():
        sys.exit(0)
