import subprocess
import tempfile

from io import BytesIO
from pathlib import Path
from pypdf import PdfWriter, PdfReader

from django.utils.text import slugify
from aemo.pdf import BasePDF, BilanPdf, EvaluationPdf, MessagePdf, RapportPdf, JournalPdf


class ArchiveBase(BasePDF):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.merger = PdfWriter()

    def get_filename(self):
        return f"{slugify(self.instance.nom)}-{self.instance.pk}.pdf"

    def append_pdf(self, PDFClass, obj):
        temp = BytesIO()
        pdf = PDFClass(temp, obj)
        pdf.produce()
        self.merger.append(temp)

    def append_other_docs(self, documents):
        msg = []
        for doc in documents:
            doc_path = Path(doc.fichier.path)
            if not doc_path.exists():
                msg.append(f"Le fichier «{doc.titre}» n'existe pas!")
                continue
            if doc_path.suffix.lower() == '.pdf':
                self.merger.append(PdfReader(str(doc_path)))
            elif doc_path.suffix.lower() in ['.doc', '.docx']:
                with tempfile.TemporaryDirectory() as tmpdir:
                    cmd = ['libreoffice', '--headless', '--convert-to', 'pdf', '--outdir', tmpdir, doc_path]
                    subprocess.run(cmd, capture_output=True)
                    converted_path = Path(tmpdir) / f'{doc_path.stem}.pdf'
                    if converted_path.exists():
                        self.merger.append(PdfReader(str(converted_path)))
                    else:
                        msg.append(f"La conversion du fichier «{doc.titre}» a échoué")
            elif doc_path.suffix.lower() == '.msg':
                self.append_pdf(MessagePdf, doc)
            else:
                msg.append(f"Le format du fichier «{doc.titre}» ne peut pas être intégré.")
        return msg


class ArchivePdf(ArchiveBase):
    title = "Archive"

    def produce(self):
        famille = self.instance
        self.append_pdf(EvaluationPdf, famille)
        self.append_pdf(JournalPdf, famille)
        for bilan in famille.bilans.all():
            self.append_pdf(BilanPdf, bilan)
        for rapport in famille.rapports.all():
            self.append_pdf(RapportPdf, rapport)
        msg = self.append_other_docs(famille.documents.all())
        self.merger.write(self.doc.filename)
        return msg
