"""Module for constructing and interacting with PDF reports for Pylinac."""
from datetime import datetime
import os

from PIL import Image
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.units import cm
from reportlab.lib.pagesizes import A4
from reportlab.lib.utils import ImageReader

from pylinac import __version__
from .io import retrieve_demo_file


PDF_FONT = "Helvetica"


def draw_text(canvas, x, y, text, fontsize=10):
    """Generic text drawing function.

    Parameters
    ----------
    x : float
        Distance from left edge.
    y : float
        Distance from bottom edge.
    text : str, list of strings
        Text data; if str, prints single line.
        If list of strings, each list item is printed on its own line.
    fontsize : int
        Text fontsize.
    """
    textobj = canvas.beginText()
    textobj.setTextOrigin(x, y)
    textobj.setFont(PDF_FONT, int(fontsize))
    if isinstance(text, str):
        textobj.textLine(text)
    elif isinstance(text, list):
        for line in text:
            textobj.textLine(line)
    canvas.drawText(textobj)


def create_pylinac_page_template(filename, analysis_title, file_name=None, file_created=None, unit=None, author=None):
    """Create a new pylinac PDF template report.

    Parameters
    ----------
    filename : str
        PDF report file name.
    analysis_title : str
        Text to be displayed in the header of the report.
    file_name : str, optional
        Name of the file that was analyzed.
    file_created : str, optional
        When the file being analyzed was created.
    unit : str, optional
        Name of the unit that made the image/data.
    author : str, optional
        The author of the analysis; for tracking who did what.

    Returns
    -------
    Reportlab canvas
    """
    pdf_canvas = Canvas(filename, pagesize=A4)
    add_pylinac_page_template(pdf_canvas, analysis_title, unit=unit, author=author, file_name=file_name,
                              file_created=file_created)
    return pdf_canvas


def add_pylinac_page_template(canvas, analysis_title, file_name=None, file_created=None, unit=None, author=None):
    """Add a new pylinac template page to an existing report; for constructing multipage reports.

    Parameters
    ----------
    canvas : reportlab.canvas
        The canvas that has already been constructed.
    analysis_title : str
        Title to be displayed in the page header.
    """
    # draw logo and header separation line
    canvas.drawImage(retrieve_demo_file(url='Pylinac_Full_cropped.png'),
                         1 * cm, 26.5 * cm, width=5 * cm, height=3 * cm, preserveAspectRatio=True)
    canvas.line(1 * cm, 26.5 * cm, 20 * cm, 26.5 * cm)
    # draw title
    draw_text(canvas, x=7 * cm, y=27 * cm, fontsize=24, text=analysis_title)
    text = ['Metadata:']
    if file_name:
        text.append('File: {}'.format(file_name))
    if file_created:
        text.append('File created: {}'.format(file_created))
    if unit:
        text.append('Unit: {}'.format(unit))
    if author:
        text.append('Author: {}'.format(author))
    date = datetime.now().strftime("%A, %B %d, %Y")
    text.append('Analyzed on: {}'.format(date))
    if any((file_name, file_created, unit, author)):
        draw_text(canvas, x=2*cm, y=25.5*cm, text=text)
    # draw "generated by" tag
    draw_text(canvas, 0.5 * cm, 0.5 * cm, "Generated with Pylinac version {}".format(__version__), fontsize=8)


def create_stream_image(data_io):
    """Take in a buffered image and make it compatible with reportlab's image functionality.

    Parameters
    ----------
    data_io : BytesIO instance
    """
    data_io.seek(0)
    return ImageReader(Image.open(data_io))


def finish(canvas, open_file, filename):
    canvas.showPage()
    canvas.save()
    if open_file:
        utilities.open_path(filename)
