from io import BytesIO

import extract_msg
import nh3

from bs4 import BeautifulSoup
from pypdf import PdfWriter

from functools import partial
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.units import cm
from reportlab.pdfgen import canvas
from reportlab.platypus import (
    PageBreak, Paragraph, Preformatted, SimpleDocTemplate, Spacer, Table, TableStyle
)

from django.contrib.staticfiles.finders import find
from django.utils.text import slugify

from .utils import format_d_m_Y, format_duree, format_Ymd


def format_booleen(val):
    return '?' if val is None else ('oui' if val else 'non')


class PageNumCanvas(canvas.Canvas):
    """A special canvas to be able to draw the total page number in the footer."""
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._pages = []

    def showPage(self):
        self._pages.append(dict(self.__dict__))
        self._startPage()

    def save(self):
        page_count = len(self._pages)
        for page in self._pages:
            self.__dict__.update(page)
            self.draw_page_number(page_count)
            canvas.Canvas.showPage(self)
        super().save()

    def draw_page_number(self, page_count):
        self.setFont("Helvetica", 9)
        self.drawRightString(self._pagesize[0] - 1.6*cm, 2.3*cm, "p. %s/%s" % (self._pageNumber, page_count))


class CleanParagraph(Paragraph):
    """If the (HTML) text cannot be parsed, try to clean it."""
    def __init__(self, text, *args, **kwargs):
        if text:
            text = text.replace('</p>', '</p><br/>')
            if '<ul>' in text:
                text = text.replace('<li>', '&nbsp;&nbsp;&bull; ').replace('</ul>','<br>').replace('</li>', '<br>')
        try:
            super().__init__(text, *args, **kwargs)
        except ValueError:
            text = nh3.clean(
                text, tags={'p', 'br', 'b', 'strong', 'u', 'i', 'em', 'ul', 'li'}
            ).replace('<br>', '<br/>')
        super().__init__(text, *args, **kwargs)


class RawParagraph(Paragraph):
    """Raw text, replace new lines by <br/>."""
    def __init__(self, text='', *args, **kwargs):
        if text:
            text = text.replace('\r\n', '\n').replace('\n', '\n<br/>')
        super().__init__(text, *args, **kwargs)


class StyleMixin:
    FONTSIZE = 9
    MAXLINELENGTH = 120

    def __init__(self, base_font='Helvetica', **kwargs):
        self.styles = getSampleStyleSheet()
        self.style_title = ParagraphStyle(
            name='title', fontName='Helvetica-Bold', fontSize=self.FONTSIZE + 4,
            leading=self.FONTSIZE + 5, alignment=TA_CENTER
        )
        self.style_normal = ParagraphStyle(
            name='normal', fontName='Helvetica', fontSize=self.FONTSIZE, alignment=TA_LEFT,
            leading=self.FONTSIZE + 1, spaceAfter=0
        )
        self.style_justifie = ParagraphStyle(
            name='justifie', parent=self.style_normal, alignment=TA_JUSTIFY, spaceAfter=0.2 * cm
        )
        self.style_sub_title = ParagraphStyle(
            name='sous_titre', fontName='Helvetica-Bold', fontSize=self.FONTSIZE + 2,
            alignment=TA_LEFT, spaceBefore=0.5 * cm, spaceAfter=0.1 * cm
        )
        self.style_inter_title = ParagraphStyle(
            name='inter_titre', fontName='Helvetica-Bold', fontSize=self.FONTSIZE + 1,
            alignment=TA_LEFT, spaceBefore=0.3 * cm, spaceAfter=0
        )
        self.style_bold = ParagraphStyle(
            name='bold', fontName='Helvetica-Bold', fontSize=self.FONTSIZE, leading=self.FONTSIZE + 1
        )
        self.style_italic = ParagraphStyle(
            name='italic', fontName='Helvetica-Oblique', fontSize=self.FONTSIZE - 1, leading=self.FONTSIZE
        )
        self.style_indent = ParagraphStyle(
            name='indent', fontName='Helvetica', fontSize=self.FONTSIZE, alignment=TA_LEFT,
            leftIndent=1 * cm
        )
        super().__init__(**kwargs)


class HeaderFooterMixin:
    LOGO = find('img/logo-cr.png')
    EDUQUA = find('img/eduqua.png')
    DON = find('img/logo-zewo.png')

    def draw_header(self, canvas, doc):
        canvas.saveState()
        canvas.drawImage(
            self.LOGO, doc.leftMargin + 316, doc.height+60, 7 * cm, 1.6 * cm, preserveAspectRatio=True, mask='auto'
        )
        canvas.restoreState()

    def draw_footer(self, canvas, doc):
        canvas.saveState()
        canvas.drawImage(
            self.EDUQUA, doc.leftMargin, doc.height - 670, 1.8 * cm, 0.8 * cm, preserveAspectRatio=True
        )
        canvas.drawImage(
            self.DON, doc.leftMargin + 60, doc.height - 670, 2.5 * cm, 0.8 * cm, preserveAspectRatio=True, mask='auto'
        )
        tab = [220, 365]
        line = [658, 667, 676, 685]

        canvas.setFont("Helvetica", 8)
        canvas.drawRightString(doc.leftMargin + tab[0], doc.height - line[2], "CCP ?")
        canvas.drawRightString(doc.leftMargin + tab[0], doc.height - line[3], "IBAN ?")
        canvas.setLineWidth(0.5)
        canvas.line(doc.leftMargin + 230, 2.2 * cm, doc.leftMargin + 230, 1.0 * cm)

        canvas.drawRightString(doc.leftMargin + tab[1], doc.height - line[0], "Rte d’Englisberg 3")
        canvas.setFont("Helvetica-Bold", 8)
        canvas.drawRightString(doc.leftMargin + tab[1], doc.height - line[1], "1763 Granges-Paccot")
        canvas.setFont("Helvetica", 8)
        canvas.line(doc.leftMargin + 375, 2.2 * cm, doc.leftMargin + 375, 1.0 * cm)
        canvas.drawRightString(doc.leftMargin + doc.width, doc.height - line[0], "+41 26 407 70 44")
        canvas.drawRightString(doc.leftMargin + doc.width, doc.height - line[1], "secretariat@fondation-transit.ch")
        canvas.drawRightString(doc.leftMargin + doc.width, doc.height - line[2], "fondation-transit.ch/aemo")
        canvas.restoreState()


class BasePDF(HeaderFooterMixin, StyleMixin):

    def __init__(self, tampon, instance, **kwargs):
        self.instance = instance
        self.kwargs = kwargs
        self.doc = SimpleDocTemplate(
            tampon, title=self.title, pagesize=A4,
            leftMargin=1.5 * cm, rightMargin=1.5 * cm, topMargin=2 * cm, bottomMargin=2.5 * cm
        )
        self.story = []
        super().__init__(**kwargs)

    def draw_header_footer(self, canvas, doc):
        self.draw_header(canvas, doc)
        self.draw_footer(canvas, doc)

    def produce(self):
        # subclass should call self.doc.build(self.story, onFirstPage=self.draw_header_footer)
        raise NotImplementedError

    def get_filename(self):
        raise NotImplementedError

    @staticmethod
    def format_note(note, length=StyleMixin.MAXLINELENGTH):
        return Preformatted(note.replace('\r\n', '\n'), maxLineLength=length)

    def set_title(self, title=''):
        self.story.append(Spacer(0, 1 * cm))
        self.story.append(Paragraph(title, self.style_title))
        self.story.append(Spacer(0, 1.2 * cm))

    def parent_data(self, person):
        """Return parent data ready to be used in a 2-column table."""
        parents = person.parents()
        par1 = parents[0] if len(parents) > 0 else None
        par2 = parents[1] if len(parents) > 1 else None
        data = [
            [('Parent 1 (%s)' % par1.role.nom) if par1 else '-',
                ('Parent 2 (%s)' % par2.role.nom) if par2 else '-'],
            [par1.contact.nom_prenom if par1 else '', par2.contact.nom_prenom if par2 else ''],
            [par1.contact.adresse if par1 else '', par2.contact.adresse if par2 else ''],
            [par1.contact.contact if par1 else '', par2.contact.contact if par2 else ''],

            ['Autorité parentale: {}'.format(format_booleen(par1.contact.autorite_parentale)) if par1 else '',
                'Autorité parentale: {}'.format(format_booleen(par2.contact.autorite_parentale)) if par2 else ''],
        ]
        return data

    def formate_persons(self, parents_list):
        labels = (
            ("Nom", "nom"), ("Prénom", "prenom"), ("Adresse", "rue"),
            ("Localité", 'localite_display'), ("Profession", 'profession'), ("Tél.", 'telephone'),
            ("Courriel", 'email'), ('Remarque', 'remarque'),
        )
        P = partial(Paragraph, style=self.style_normal)
        Pbold = partial(Paragraph, style=self.style_bold)
        data = []
        parents = [parent for parent in parents_list if parent is not None]
        if len(parents) == 0:
            pass
        elif len(parents) == 1:
            data.append([Pbold('Rôle:'), Pbold(parents[0].role.nom), '', ''])
            for label in labels:
                data.append([
                    label[0], P(getattr(parents[0], label[1])), '', ''
                ])
        elif len(parents) == 2:
            data.append([
                Pbold('Rôle:'), Pbold(parents[0].role.nom),
                Pbold('Rôle:'), Pbold(parents[1].role.nom)
            ])
            for label in labels:
                data.append([
                    label[0], P(getattr(parents[0], label[1]) if parents[0] else ''),
                    label[0], P(getattr(parents[1], label[1]) if parents[1] else '')
                ])
        return data

    def get_table(self, data, columns, before=0.0, after=0.0, inter=None):
        """Prepare a Table instance with data and columns, with a common style."""
        if inter:
            inter = inter * cm
        cols = [c * cm for c in columns]

        t = Table(
            data=data, colWidths=cols, hAlign=TA_LEFT,
            spaceBefore=before * cm, spaceAfter=after * cm
        )
        t.hAlign = 0
        t.setStyle(tblstyle=TableStyle([
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('FONTSIZE', (0, 0), (-1, -1), self.FONTSIZE),
            ('VALIGN', (0, 0), (-1, -1), "TOP"),
            ('LEFTPADDING', (0, 0), (0, -1), 1),
            ('LEADING', (0, 0), (-1, -1), 7),
        ]))
        return t

    def _add_subtitle(self, data):
        t = Table(
            data=[data], colWidths=[18 * cm / len(data)] * len(data),
            hAlign=TA_LEFT,
            spaceBefore=0.2 * cm, spaceAfter=0.5 * cm
        )
        t.hAlign = 0
        t.setStyle(tblstyle=TableStyle([
            ('FONT', (0, 0), (-1, -1), "Helvetica-Bold"),
            ('FONTSIZE', (0, 0), (-1, -1), self.FONTSIZE + 2),
            ('LINEBELOW', (0, -1), (-1, -1), 0.25, colors.black),
            ('ALIGN', (-1, -1), (-1, -1), 'RIGHT'),
        ]))
        self.story.append(t)

    def write_paragraph(self, title, text, html=False, justifie=False):
        if title:
            self.story.append(Paragraph(title, self.style_sub_title))
        style = self.style_justifie if justifie else self.style_normal
        if html:
            if text.startswith('<p>') and text.endswith('</p>'):
                soup = BeautifulSoup(text, features="html5lib")
                for tag in soup.find_all(['p', 'ul']):
                    self.story.append(CleanParagraph(str(tag), style))
            else:
                self.story.append(CleanParagraph(text, style))
        else:
            self.story.append(RawParagraph(text, style))

    def enfant_data(self, enfant):
        labels = [('Tél.', enfant.telephone)]
        if hasattr(enfant, 'formation'):
            labels.extend([
                ('Statut scol', enfant.formation.get_statut_display()),
                ('Centre', enfant.formation.cercle_scolaire),
                ('Collège', enfant.formation.college),
                ('Classe', enfant.formation.classe),
                ('Struct. extra-fam.', enfant.formation.creche),
                ('Ens.', enfant.formation.enseignant),
            ])
        labels.extend([
            ('Permis de séjour', enfant.permis),
            ('Validité', enfant.validite),
        ])
        row = [f"{enfant.nom_prenom} (*{format_d_m_Y(enfant.date_naissance)})"]
        for label in labels:
            if label[1]:
                row.append(f"{label[0]}: {label[1]}")
        return '; '.join(row)


class DemandeAccompagnement(BasePDF):
    title = None

    def produce(self):
        famille = self.instance
        suivi = famille.suivi
        self.set_title("Famille {} - {}".format(famille.nom, self.title))

        self.story.append(Paragraph("<strong>Motif(s) de la demande:</strong> {}".format(
            suivi.get_motif_demande_display()), self.style_normal
        ))
        self.story.append(Paragraph('_' * 90, self.style_normal))

        self.write_paragraph("Dates", suivi.dates_demande)
        self.write_paragraph(
            "Difficultés",
            "{}<br/>{}<br/><br/>{}".format(
                "<em>Quelles sont les difficultés éducatives que vous rencontrez et depuis combien de "
                "temps ?",
                "Fonctionnement familial: règles, coucher, lever, repas, jeux, relations "
                "parent-enfants, rapport au sein de la fratrie, … (exemple)</em>",
                suivi.difficultes
            ),
            html=True
        )
        self.write_paragraph(
            "Autres services",
            "<em>{}</em><br/>{}".format(
                "Avez-vous fait appel à d'autres services ? Si oui, avec quels vécus ?",
                suivi.autres_contacts
            ),
            html=True
        )
        self.write_paragraph("Aides souhaitées", suivi.aides, html=True)
        self.write_paragraph("Ressources/Compétences", suivi.competences, html=True)
        self.write_paragraph("Disponibilités", suivi.disponibilites, html=True)
        self.write_paragraph("Remarques", suivi.remarque)

        self.doc.build(self.story, onFirstPage=self.draw_header_footer)


class JournalPdf(BasePDF):
    title = "Journal de bord"

    def get_filename(self):
        return '{}_journal.pdf'.format(slugify(self.instance.nom))

    def get_title(self):
        return 'Famille {} - {}'.format(self.instance.nom, self.title)

    def produce(self):
        famille = self.instance
        self.set_title(self.get_title())

        self.style_bold.spaceAfter = 0.2*cm
        self.style_italic.spaceBefore = 0.2 * cm
        self.style_italic.spaceAfter = 0.7 * cm
        for prest in famille.prestations.all().prefetch_related('intervenants'):
            self.story.append(CleanParagraph(prest.texte, self.style_normal))
            self.story.append(
                Paragraph('{} - {} ({})'.format(
                    '/'.join(interv.sigle for interv in prest.intervenants.all()),
                    format_d_m_Y(prest.date_prestation),
                    format_duree(prest.duree)
                ), self.style_italic)
            )

        self.doc.build(
            self.story,
            onFirstPage=self.draw_header_footer, onLaterPages=self.draw_footer,
            canvasmaker=PageNumCanvas
        )


class RapportPdf(BasePDF):
    title = None

    def get_filename(self):
        return "{}_resume_{}.pdf".format(
            slugify(self.instance.famille.nom),
            format_Ymd(self.instance.date)
        )

    def produce(self):
        rapport = self.instance
        self.style_normal.fontSize += 2
        self.style_normal.leading += 2
        self.style_justifie.fontSize += 2
        self.style_justifie.leading += 2
        self.doc.title = 'Résumé "AEMO"'
        self.set_title('Famille {} - {}'.format(rapport.famille.nom, self.doc.title))
        self._add_subtitle([f"Date: {format_d_m_Y(rapport.date)}"])

        data = [
            ("Enfant(s)", '<br/>'.join(
                [f"{enfant.nom_prenom} (*{format_d_m_Y(enfant.date_naissance)})"
                 for enfant in rapport.famille.membres_suivis()]), False),
            ("Intervenant-e-s", ', '.join([i.nom_prenom for i in rapport.intervenants()]), False),
            ("Début du suivi", format_d_m_Y(rapport.famille.suivi.date_debut_suivi), False),
            ("Situation / contexte familial", rapport.situation, True),
        ]
        data.append(("Observations", rapport.observations, True))
        data.append(("Perspectives d'avenir", rapport.projet, True))

        for title, text, html in data:
            self.write_paragraph(title, text, html=html, justifie=True)

        if hasattr(rapport, 'sig_interv'):
            self.story.append(Spacer(0, 0.5 * cm))

            for idx, interv in enumerate(rapport.sig_interv.all()):
                if idx == 0:
                    self.write_paragraph("Signature des intervenant-e-s :", '')
                    self.story.append(Spacer(0, 0.2 * cm))
                self.write_paragraph('', interv.nom_prenom + (f', {interv.profession}' if interv.profession else ''))
                self.story.append(Spacer(0, 1 * cm))

        secret_style = ParagraphStyle(
            name='italic', fontName='Helvetica-Oblique', fontSize=self.FONTSIZE - 1, leading=self.FONTSIZE + 1,
            backColor=colors.Color(0.96, 0.96, 0.96, 1), borderRadius=12,
        )
        self.story.append(Paragraph(
            "Le présent résumé comporte des éléments <b>couverts par le secret professionnel au sens "
            "de la LPSy et du Code pénal</b>. Seuls les propriétaires des données, à savoir les membres "
            "de la famille faisant l’objet du résumé, peuvent <b>ensemble</b> lever ce secret ou "
            "accepter la divulgation des données. Si cette autorisation n’est pas donnée, l’autorité "
            "compétente en matière de levée du secret professionnel doit impérativement être saisie.",
            secret_style
        ))

        self.doc.build(self.story, onFirstPage=self.draw_header_footer, onLaterPages=self.draw_footer)


class MessagePdf(BasePDF):
    title = 'Message'

    def get_filename(self):
        return '{}_message.pdf'.format(slugify(self.instance.subject))

    def produce(self):
        doc = self.instance
        self.set_title('{} - Famille {}'.format(self.title, doc.famille.nom))
        with extract_msg.Message(doc.fichier.path) as msg:
            P = partial(Paragraph, style=self.style_normal)
            Pbold = partial(Paragraph, style=self.style_bold)

            msg_headers = [
                [Pbold('De:'), P(msg.sender)],
                [Pbold('À:'), P(msg.to)],
            ]
            if msg.cc:
                msg_headers.append([Pbold('CC:'), P(msg.cc)])
            if msg.date:
                msg_headers.append([Pbold('Date:'), P(msg.date)])
            msg_headers.append([Pbold('Sujet:'), P(msg.subject)])
            self.story.append(self.get_table(msg_headers, [3, 15]))
            self.story.append(Pbold('Message:'))
            self.story.append(RawParagraph(msg.body, style=self.style_normal))
        return self.doc.build(
            self.story,
            onFirstPage=self.draw_header_footer, onLaterPages=self.draw_footer,
            canvasmaker=PageNumCanvas
        )


class EvaluationPdf:
    def __init__(self, tampon, famille):
        self.tampon = tampon
        self.famille = famille
        self.merger = PdfWriter()

    def append_pdf(self, PDFClass):
        tampon = BytesIO()
        pdf = PDFClass(tampon, self.famille)
        pdf.produce()
        self.merger.append(tampon)

    def produce(self):

        self.append_pdf(CoordonneesPagePdf)
        self.append_pdf(DemandeAccompagnementPagePdf)
        self.merger.write(self.tampon)

    def get_filename(self):
        return '{}_aemo_evaluation.pdf'.format(slugify(self.famille.nom))


class CoordonneesFamillePdf(BasePDF):
    title = "Informations"

    def get_filename(self):
        return '{}_coordonnees.pdf'.format(slugify(self.instance.nom))

    def produce(self):
        famille = self.instance
        suivi = famille.suivi
        self.set_title('Famille {} - {}'.format(famille.nom, self.title))

        # Parents
        self.story.append(Paragraph('Parents', self.style_sub_title))
        data = self.formate_persons(famille.parents())
        if data:
            self.story.append(self.get_table(data, columns=[2, 7, 2, 7], before=0, after=0))
        else:
            self.story.append(Paragraph('-', self.style_normal))

        # Situation matrimoniale
        data = [
            ['Situation matrimoniale: {}'.format(famille.get_statut_marital_display()),
             'Autorité parentale: {}'.format(famille.get_autorite_parentale_display())],
        ]
        self.story.append(self.get_table(data, columns=[9, 9], before=0, after=0))

        # Personnes significatives
        autres_parents = list(famille.autres_parents())
        if autres_parents:
            self.story.append(Paragraph('Personne-s significative-s', self.style_sub_title))
            data = self.formate_persons(autres_parents)
            self.story.append(self.get_table(data, columns=[2, 7, 3, 6], before=0, after=0))
            if len(autres_parents) > 2:
                self.story.append(PageBreak())

        # Enfants suivis
        self.write_paragraph(
            "Enfant(s)",
            '<br/>'.join(self.enfant_data(enfant) for enfant in famille.membres_suivis())
        )
        # Réseau
        self.story.append(Paragraph("Réseau", self.style_sub_title))
        data = [
            ['AS OPE', '{} - (Mandat: {})'.format(
                ', '.join(ope.nom_prenom for ope in suivi.ope_referents),
                suivi.get_mandat_ope_display()
            )],
            ['Interv. CRNE', '{}'.format(
                ', '.join('{}'.format(i.nom_prenom) for i in suivi.intervenants.all().distinct())
            )]
        ]
        for enfant in famille.membres_suivis():
            for contact in enfant.reseaux.all():
                data.append([
                    enfant.prenom,
                    '{} ({})'.format(contact, contact.contact)
                ])
        self.story.append(self.get_table(data, columns=[2, 16], before=0, after=0))

        self.write_paragraph("Motif de la demande", famille.suivi.motif_detail)
        self.write_paragraph("Collaborations", famille.suivi.collaboration)

        # Historique
        self.story.append(Paragraph('Historique', self.style_sub_title))
        P = partial(Paragraph, style=self.style_normal)
        Pbold = partial(Paragraph, style=self.style_bold)
        fields = ['date_demande', 'date_debut_evaluation', 'date_fin_evaluation',
                  'date_debut_suivi', 'date_fin_suivi']
        data = []
        for field_name in fields:
            field = famille.suivi._meta.get_field(field_name)
            if getattr(famille.suivi, field_name):
                data.append(
                    [Pbold(f"{field.verbose_name} :"), P(format_d_m_Y(getattr(famille.suivi, field_name)))]
                )
        if famille.suivi.motif_fin_suivi:
            data.append([Pbold("Motif de fin de suivi :"), famille.suivi.get_motif_fin_suivi_display()])
        if famille.destination:
            data.append([Pbold("Destination :"), famille.get_destination_display()])
        if famille.archived_at:
            data.append([Pbold("Date d'archivage :"), format_d_m_Y(famille.archived_at)])

        self.story.append(self.get_table(data, [4, 5]))
        self.doc.build(self.story, onFirstPage=self.draw_header_footer)


class DemandeAccompagnementPagePdf(DemandeAccompagnement):
    title = "Évaluation AEMO"


class BilanPdf(BasePDF):
    title = "Bilan AEMO"

    def get_filename(self):
        return "{}_bilan_{}.pdf".format(
            slugify(self.instance.famille.nom),
            format_Ymd(self.instance.date)
        )

    def produce(self):
        bilan = self.instance
        self.style_normal.fontSize += 2
        self.style_normal.leading += 2
        self.style_justifie.fontSize += 2
        self.style_justifie.leading += 2
        self.set_title('Famille {} - {}'.format(bilan.famille.nom, self.title))
        self._add_subtitle([f"Date: {format_d_m_Y(bilan.date)}"])

        for title, text, html in (
            ("Enfant(s)", '<br/>'.join(
                [f"{enfant.nom_prenom} (*{format_d_m_Y(enfant.date_naissance)})"
                 for enfant in bilan.famille.membres_suivis()]), False),
            ("Intervenant-e-s", ', '.join(
                [i.intervenant.nom_prenom for i in bilan.famille.interventions_actives(bilan.date)]
            ), False),
            ("Début du suivi", format_d_m_Y(bilan.famille.suivi.date_debut_suivi), False),
            ("Besoins et objectifs", bilan.objectifs, True),
            ("Rythme et fréquence", bilan.rythme, True),
        ):
            self.write_paragraph(title, text, html=html, justifie=True)

        self.story.append(Spacer(0, 0.5 * cm))

        for idx, interv in enumerate(bilan.sig_interv.all()):
            if idx == 0:
                self.write_paragraph("Signature des intervenant-e-s AEMO :", '')
                self.story.append(Spacer(0, 0.2 * cm))
            self.write_paragraph('', interv.nom_prenom + (f', {interv.profession}' if interv.profession else ''))
            self.story.append(Spacer(0, 1 * cm))

        if bilan.sig_famille:
            self.write_paragraph("Signature de la famille :", '')

        self.doc.build(self.story, onFirstPage=self.draw_header_footer, onLaterPages=self.draw_footer)


class CoordonneesPagePdf(CoordonneesFamillePdf):
    title = "Informations"

    def get_filename(self, famille):
        return '{}_aemo_evaluation.pdf'.format(slugify(famille.nom))


def str_or_empty(value):
    return '' if not value else str(value)
