from werkzeug.utils import secure_filename
from app import app, mail
from app.models import licenze
import os, PyPDF2, pikepdf, re, io
from flask import redirect, url_for
from flask_mail import Message
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from datetime import date, datetime
from email.mime.base import MIMEBase
from email import encoders


def insert_pin(cliente, files): # prende i dati dal form e per ogni file inserisce il relativo PIN nel DB ed invia una mail a MAIL_DEST
    app.logger.info('Sono in insert_pin')
    files_names = upload(files) # decifro i file e li salvo su disco
    if not files_names:
        return False
    app.logger.info('Ho salvato tutti i file su disco')
    indice = 1 # creo un indice - parto da 1 perchè è umano
    pdf_file = []
    for file in files_names: # ciclo sui singoli file
        app.logger.info('Sono nel FOR')
        dati = converti_licenza(read_pdf(file)) # creo i dati variabili
        pdf_file.append(scrivi_pdf(cliente, dati, indice)) # creo il pdf con il pin e lo metto nella lista
    subject = create_subject(cliente)
    try:
        send_email(subject, ' ', ' ', pdf_file)
        return True
    except:
        return False
    

def upload(files): #legge i file caricati e li salva senza password e ritorna la lista dei nuovi nomi
    app.logger.info('Sono in upload')
    files_filenames = []
    for file in files:
        app.logger.info('Sto aprendo il file: %s', file)
        file_filename = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(file))
        try:
            pdf = pikepdf.open(file_filename,password="FSPA7691")
            app.logger.info('Ho aperto il file con la pwd')
            file_dec = file_filename+"_dec.pdf"
            pdf.save(file_dec)
            app.logger.info('Ho scritto il nuovo file su disco: %s', file_dec)
            os.remove(file_filename)
            app.logger.info('Ho cancellato il file: %s', file_filename)
            files_filenames.append(file_dec)
        except:
            app.logger.info('File non valido')
            return False
    app.logger.info('Ho lavorato tutti i file ed esco da upload')
    return files_filenames

def converti_licenza(dati): # prendo i dati del pdf Matrix e li trasformo negli equivalenti Fitre
    licenza = licenze.search_desM(licenze, dati[1])  # cerco nel DB la licenza in base al nome Matrix
    app.logger.info('Ho ricavato la licenza: %s', licenza)
    return [dati[0], licenza.codFitre, licenza.desFitre]

def read_pdf(file): # estrae il PIN ed il nome della licenza dal file PDF e li ritorna come due elementi di una lista
    Pdf = PyPDF2.PdfReader(file)
    os.remove(file) # dopo averlo letto elimino il file da disco
    app.logger.info('Ho cancellato il file: %s', file)
    dati = []
    try:
     page1 = Pdf.pages[1]
    except IndexError as error:
     # devo ritornare un errore in qualche modo
     #print("Il file '"+file+"' non sembra essere un file contenente PIN per centrali ML")
     exit()
    testo1 = page1.extract_text()
    #estraggo il pin
    p = re.compile(r'[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}') #cerco un'espressione che sia come quella del PIN aaaa-aaaa-aaaa-aaaa
    try:
     dati.append(re.findall(p, testo1)[0])
     app.logger.info('Dati[0]  : %s', dati[0])
    except IndexError as error:
     # devo ritornare un errore in qualche modo
     #print("Il file '"+file+"' non sembra essere un file contenente PIN per centrali ML")
     exit()
    page0 = Pdf.pages[0]
    testo0 = page0.extract_text()
    matchf = re.search(r'\d{2}/\d{2}/\d{4}', testo0) # nel testo estratto il nome della licenza precede la data. cerco quindi un'espressione che sia una data mm/gg/aaaa
    fine = matchf.start() # segno l'inizio della data come fine del testo da estrarre
    matchi = re.search('SARVAM ', testo0) # tutti i nomi delle licenze iniziano con SARVAM
    inizio = matchi.end() #segno la fine di SARVAM come inizio del testo da estrarre
    dati.append(testo0[inizio:fine].replace("\n","")) 
    app.logger.info('Dati[1]  : %s', dati[1])
    return dati

def scrivi_pdf(cliente, dati, indice): # crea il modulo pdf con i dati del cliente ed il PIN, dandogli un nome file indicizzato (nel caso di PIN multipli sullo stesso ordine; ritorna il nome file
    # scrivo la parte variabile
    packet = io.BytesIO()
    can = canvas.Canvas(packet, pagesize=letter)
    can.setFont('Courier-Bold', 11)
    can.drawString(75, 475, dati[1]) # codice licenza
    can.drawString(135, 475, dati[2]) # descrizione licenza
    can.drawString(390, 475, dati[0]) # PIN licenza
    can.drawString(180, 530, cliente['oc']) # numero ordine cliente
    can.drawString(425, 530, cliente['doc'].strftime("%d/%m/%Y")) # data ordine cliente
    can.drawString(140, 610, cliente['ns']) # numero ordine Fitre
    can.drawString(120, 640, date.today().strftime("%d/%m/%Y")) # data di oggi
    can.setFont('Courier-Bold', 10)
    can.drawString(355, 675, cliente['rs']) # ragione sociale
    can.drawString(335, 652, cliente['em']) # email
    can.save()
    packet.seek(0) #move to the beginning of the StringIO buffer
    PDF_var = PyPDF2.PdfReader(packet) # creo il PDF con i soli dati variabili
    app.logger.info('Ho creato il testo del pdf')
    modulo = PyPDF2.PdfReader(open(app.config['BASE_FOLDER']+app.config['MODULO_PIN'], "rb")) # apro il modulo per invio a cliente
    app.logger.info('Ho letto il modello ')
    page = modulo.pages[0] # mi metto sulla prima pagina
    page.merge_page(PDF_var.pages[0]) #aggiungo il testo variabile
    output = PyPDF2.PdfWriter() # creo un nuovo file
    output.add_page(page) # ed aggiungo la pagina completa dei dati
    nomefile = app.config['UPLOAD_FOLDER']+"/PIN_"+dati[1]+"_"+cliente['ns']+"_"+str(indice)+".pdf" #creo il file finale dandogli come nome, il nostro riferimento ordine e l'indice incrementale
    app.logger.info('Ho generato il nome del file %s ', nomefile)
    outputStream = open(nomefile, "wb") # creo il file sul disco
    output.write(outputStream) # scrivo il PDF sul file
    outputStream.close() # chiudo il file sul disco
    app.logger.info('Ho scritto e salvato il file su disco')
    return nomefile

def create_subject(cliente):
    subject = 'Invio PIN licenza ML - Nostro riferimento: '+cliente['ns']+' - Cliente: '+cliente['rs']
    app.logger.info('Creo il subject %s', subject)
    return(subject)
    

def salva_files(form_files):
    files = []
    for file in form_files:
        filename = secure_filename(file.filename)
        app.logger.info('Sto salvando %s', filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        files.append(filename)
    return files

def send_email(subject, text_body, html_body, files): #invia la mail con i PIN
    msg = Message(subject, sender=app.config['MAIL_SENDER'], recipients=app.config['MAIL_DEST'])
    msg.body = text_body
    msg.html = html_body
    for file in files: # aggiungo gli allegati
         with app.open_resource(file) as allegato:
             msg.attach(file, "application/pdf", allegato.read())
    file_istr = app.config['BASE_FOLDER']+app.config['ISTR_OPER']
    with app.open_resource(file_istr) as istruzioni:
        msg.attach(file_istr, "application/pdf", istruzioni.read())
    mail.send(msg) #devo verificare l'invio e ritornare qualcosa


