# -*- mode: python -*-
# -*- coding: utf-8 -*-

##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2023 Emmanuel Viennet.  All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#   Emmanuel Viennet      emmanuel.viennet@viennet.net
#
##############################################################################

"""Edition des PV de jury
"""
import io
import re

from PIL import Image as PILImage
from PIL import UnidentifiedImageError

import reportlab
from reportlab.lib.units import cm, mm
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_JUSTIFY
from reportlab.platypus import Paragraph, Spacer, Frame, PageBreak
from reportlab.platypus import Table, TableStyle, Image
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib import styles
from reportlab.lib.colors import Color

from flask import g
from app.models import FormSemestre

import app.scodoc.sco_utils as scu
from app.scodoc import sco_pdf
from app.scodoc.sco_logos import find_logo
from app.scodoc.sco_pdf import SU

LOGO_FOOTER_ASPECT = scu.CONFIG.LOGO_FOOTER_ASPECT  # XXX A AUTOMATISER
LOGO_FOOTER_HEIGHT = scu.CONFIG.LOGO_FOOTER_HEIGHT * mm
LOGO_FOOTER_WIDTH = LOGO_FOOTER_HEIGHT * scu.CONFIG.LOGO_FOOTER_ASPECT

LOGO_HEADER_ASPECT = scu.CONFIG.LOGO_HEADER_ASPECT  # XXX logo IUTV (A AUTOMATISER)
LOGO_HEADER_HEIGHT = scu.CONFIG.LOGO_HEADER_HEIGHT * mm
LOGO_HEADER_WIDTH = LOGO_HEADER_HEIGHT * scu.CONFIG.LOGO_HEADER_ASPECT


def page_footer(canvas, doc, logo, preferences, with_page_numbers=True):
    "Add footer on page"
    width = doc.pagesize[0]  # - doc.pageTemplate.left_p - doc.pageTemplate.right_p
    foot = Frame(
        0.1 * mm,
        0.2 * cm,
        width - 1 * mm,
        2 * cm,
        leftPadding=0,
        rightPadding=0,
        topPadding=0,
        bottomPadding=0,
        id="monfooter",
        showBoundary=0,
    )

    left_foot_style = reportlab.lib.styles.ParagraphStyle({})
    left_foot_style.fontName = preferences["SCOLAR_FONT"]
    left_foot_style.fontSize = preferences["SCOLAR_FONT_SIZE_FOOT"]
    left_foot_style.leftIndent = 0
    left_foot_style.firstLineIndent = 0
    left_foot_style.alignment = TA_RIGHT
    right_foot_style = reportlab.lib.styles.ParagraphStyle({})
    right_foot_style.fontName = preferences["SCOLAR_FONT"]
    right_foot_style.fontSize = preferences["SCOLAR_FONT_SIZE_FOOT"]
    right_foot_style.alignment = TA_RIGHT

    p = sco_pdf.make_paras(
        f"""<para>{preferences["INSTITUTION_NAME"]}</para><para>{
            preferences["INSTITUTION_ADDRESS"]}</para>""",
        left_foot_style,
    )

    np = Paragraph(f'<para fontSize="14">{doc.page}</para>', right_foot_style)
    tabstyle = TableStyle(
        [
            ("LEFTPADDING", (0, 0), (-1, -1), 0),
            ("RIGHTPADDING", (0, 0), (-1, -1), 0),
            ("ALIGN", (0, 0), (-1, -1), "RIGHT"),
            # ('INNERGRID', (0,0), (-1,-1), 0.25, black),#debug
            # ('LINEABOVE', (0,0), (-1,0), 0.5, black),
            ("VALIGN", (1, 0), (1, 0), "MIDDLE"),
            ("RIGHTPADDING", (-1, 0), (-1, 0), 1 * cm),
        ]
    )
    elems = [p]
    if logo:
        elems.append(logo)
    col_widths = [None, LOGO_FOOTER_WIDTH + 2 * mm]
    if with_page_numbers:
        elems.append(np)
        col_widths.append(2 * cm)
    else:
        elems.append("")
        col_widths.append(8 * mm)  # force marge droite
    tab = Table([elems], style=tabstyle, colWidths=col_widths)
    canvas.saveState()  # is it necessary ?
    foot.addFromList([tab], canvas)
    canvas.restoreState()


def page_header(canvas, doc, logo, preferences, only_on_first_page=False):
    "Ajoute au canvas le frame avec le logo"
    if only_on_first_page and int(doc.page) > 1:
        return
    height = doc.pagesize[1]
    head = Frame(
        -22 * mm,
        height - 13 * mm - LOGO_HEADER_HEIGHT,
        10 * cm,
        LOGO_HEADER_HEIGHT + 2 * mm,
        leftPadding=0,
        rightPadding=0,
        topPadding=0,
        bottomPadding=0,
        id="monheader",
        showBoundary=0,
    )
    if logo:
        canvas.saveState()  # is it necessary ?
        head.addFromList([logo], canvas)
        canvas.restoreState()


class CourrierIndividuelTemplate(PageTemplate):
    """Template pour courrier avisant des decisions de jury (1 page par étudiant)"""

    def __init__(
        self,
        document,
        pagesbookmarks=None,
        author=None,
        title=None,
        subject=None,
        margins=(0, 0, 0, 0),  # additional margins in mm (left,top,right, bottom)
        preferences=None,  # dictionnary with preferences, required
        force_header=False,
        force_footer=False,  # always add a footer (whatever the preferences, use for PV)
        template_name="CourrierJuryTemplate",
    ):
        """Initialise our page template."""
        self.pagesbookmarks = pagesbookmarks or {}
        self.pdfmeta_author = author
        self.pdfmeta_title = title
        self.pdfmeta_subject = subject
        self.preferences = preferences
        self.force_header = force_header
        self.force_footer = force_footer
        self.with_footer = (
            self.force_footer or self.preferences["PV_LETTER_WITH_HEADER"]
        )
        self.with_header = (
            self.force_header or self.preferences["PV_LETTER_WITH_FOOTER"]
        )
        self.with_page_background = self.preferences["PV_LETTER_WITH_BACKGROUND"]
        self.with_page_numbers = False
        self.header_only_on_first_page = False
        # Our doc is made of a single frame
        left, top, right, bottom = margins  # marge additionnelle en mm
        # marges du Frame principal
        self.bot_p = 2 * cm
        self.left_p = 2.5 * cm
        self.right_p = 2.5 * cm
        self.top_p = 0 * cm
        # log("margins=%s" % str(margins))
        content = Frame(
            self.left_p + left * mm,
            self.bot_p + bottom * mm,
            document.pagesize[0] - self.right_p - self.left_p - left * mm - right * mm,
            document.pagesize[1] - self.top_p - self.bot_p - top * mm - bottom * mm,
        )

        PageTemplate.__init__(self, template_name, [content])

        self.background_image_filename = None
        self.logo_footer = None
        self.logo_header = None
        # Search logos in dept specific dir, then in global scu.CONFIG dir
        if template_name == "PVJuryTemplate":
            background = find_logo(
                logoname="pvjury_background",
                dept_id=g.scodoc_dept_id,
            ) or find_logo(
                logoname="pvjury_background",
                dept_id=g.scodoc_dept_id,
                prefix="",
            )
        else:
            background = find_logo(
                logoname="letter_background",
                dept_id=g.scodoc_dept_id,
            ) or find_logo(
                logoname="letter_background",
                dept_id=g.scodoc_dept_id,
                prefix="",
            )
        if not self.background_image_filename and background is not None:
            self.background_image_filename = background.filepath

        footer = find_logo(logoname="footer", dept_id=g.scodoc_dept_id)
        if footer is not None:
            self.logo_footer = Image(
                footer.filepath,
                height=LOGO_FOOTER_HEIGHT,
                width=LOGO_FOOTER_WIDTH,
            )

        header = find_logo(logoname="header", dept_id=g.scodoc_dept_id)
        if header is not None:
            self.logo_header = Image(
                header.filepath,
                height=LOGO_HEADER_HEIGHT,
                width=LOGO_HEADER_WIDTH,
            )

    def beforeDrawPage(self, canv, doc):
        """Draws a logo and an contribution message on each page."""
        # ---- Add some meta data and bookmarks
        if self.pdfmeta_author:
            canv.setAuthor(SU(self.pdfmeta_author))
        if self.pdfmeta_title:
            canv.setTitle(SU(self.pdfmeta_title))
        if self.pdfmeta_subject:
            canv.setSubject(SU(self.pdfmeta_subject))
        bm = self.pagesbookmarks.get(doc.page, None)
        if bm is not None:
            key = bm
            txt = SU(bm)
            canv.bookmarkPage(key)
            canv.addOutlineEntry(txt, bm)

        # ---- Background image
        if self.background_image_filename and self.with_page_background:
            canv.drawImage(
                self.background_image_filename, 0, 0, doc.pagesize[0], doc.pagesize[1]
            )

        # ---- Header/Footer
        if self.with_header:
            page_header(
                canv,
                doc,
                self.logo_header,
                self.preferences,
                self.header_only_on_first_page,
            )
        if self.with_footer:
            page_footer(
                canv,
                doc,
                self.logo_footer,
                self.preferences,
                with_page_numbers=self.with_page_numbers,
            )


class PVTemplate(CourrierIndividuelTemplate):
    """Template pour les pages des PV de jury"""

    def __init__(
        self,
        document,
        author=None,
        title=None,
        subject=None,
        margins=None,  # additional margins in mm (left,top,right, bottom)
        preferences=None,  # dictionnary with preferences, required
    ):
        if margins is None:
            margins = (
                preferences["pv_left_margin"],
                preferences["pv_top_margin"],
                preferences["pv_right_margin"],
                preferences["pv_bottom_margin"],
            )
        super().__init__(
            document,
            author=author,
            title=title,
            subject=subject,
            margins=margins,
            preferences=preferences,
            force_header=True,
            force_footer=True,
            template_name="PVJuryTemplate",
        )
        self.with_page_numbers = True
        self.header_only_on_first_page = True
        self.with_header = self.preferences["PV_WITH_HEADER"]
        self.with_footer = self.preferences["PV_WITH_FOOTER"]
        self.with_page_background = self.preferences["PV_WITH_BACKGROUND"]

    # def afterDrawPage(self, canv, doc):
    #     """Called after all flowables have been drawn on a page"""
    #     pass

    # def beforeDrawPage(self, canv, doc):
    #     """Called before any flowables are drawn on a page"""
    #     # If the page number is even, force a page break
    #     super().beforeDrawPage(canv, doc)
    #     # Note: on cherche un moyen de generer un saut de page double
    #     #  (redémarrer sur page impaire, nouvelle feuille en recto/verso). Pas trouvé en Platypus.
    #     #
    #     # if self.__pageNum % 2 == 0:
    #     #    canvas.showPage()
    #     #    # Increment pageNum again since we've added a blank page
    #     #    self.__pageNum += 1


def jury_titres(formsemestre: FormSemestre, diplome: bool) -> tuple[str, str]:
    """Titres du PV ou lettre de jury"""
    if not diplome:
        if formsemestre.formation.is_apc():
            t = f"""BUT{(formsemestre.semestre_id+1)//2}"""
            s = t
        else:
            t = f"""passage de Semestre {formsemestre.semestre_id} en Semestre {formsemestre.semestre_id + 1}"""
            s = "passage de semestre"
    else:
        t = "délivrance du diplôme"
        s = t
    return t, s  # titre long, titre court