"""
 * @author Xiaobo Sun
 * created  on 23.06.2018
 * @copyright (C) 2018 Sogood International GmbH - all rights reserved
 * @licence
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
"""

import datetime
import json
import logging

from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle, Flowable
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch, cm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.enums import TA_RIGHT, TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
from reportlab.graphics.barcode import createBarcodeDrawing

# Get an instance of a logger
logger = logging.getLogger('django')

pdfmetrics.registerFont(TTFont('DejaVuSans', 'fonts/DejaVuSans.ttf'))


class SampleFlowable(Flowable):
    """
    Sample Flowable Usage
    Usage : elements.append(SampleFlowable())
    """

    def __init__(self):
        Flowable.__init__(self)
        self.width = 50
        self.height = 50

    def draw(self) -> None:
        """
        Draw a line
        """
        self.canv.line(0, self.height, self.width, self.height)

class NumberedCanvas(canvas.Canvas):
    """
    Page Number - Canvas Sample
    """

    def __init__(self, *args, **kwargs):
        canvas.Canvas.__init__(self, *args, **kwargs)
        self._saved_page_states = []

    def showPage(self) -> None:
        """
        Show page
        """
        self._saved_page_states.append(dict(self.__dict__))
        self._startPage()

    def save(self) -> None:
        """
        Add page info to each page (page x of y)
        """
        num_pages = len(self._saved_page_states)
        for state in self._saved_page_states:
            self.__dict__.update(state)
            self.draw_page_number(num_pages)
            canvas.Canvas.showPage(self)
        canvas.Canvas.save(self)

    def draw_page_number(self, page_count) -> None:
        """
        Draw page number
        :param page_count: page number
        """
        # Change the position of this to wherever you want the page number to be
        self.setFontSize(6)
        self.drawCentredString(100 * mm, 10 * mm,
                               "%d von %d" % (self._pageNumber, page_count))

class Order:
    def __init__(self, date, orderId, productName):
        self._date = date
        self._orderId = orderId
        self._productName = productName

class PicklistPrintable:
    """
    Main Class
    A4 is 210mm x 297mm, 8.27 x 11.69 inches. 1 inch is 72 points (not pixel)
    dimension 592 x 842 points
    """

    def __init__(self, buffer, list):
        self._buffer = buffer
        self._list = list

    def write_content(self, elements) -> None:
        """
        write first page content
        :param elements:
        """
        styles = getSampleStyleSheet()
        styles.add(ParagraphStyle(name='MY_Justify', alignment=TA_JUSTIFY, leading=16))
        styles.add(ParagraphStyle(name='MY_Right', alignment=TA_RIGHT))
        styles.add(ParagraphStyle(name='MY_Center', alignment=TA_CENTER))
        styles.add(ParagraphStyle(name='MY_Head', alignment=TA_CENTER, fontSize=24, fontName="Helvetica-Bold"))

        data = []
        data.append(["Datum", "Auftrag ID", "Code", "Details"])
        for order in self._list:
            row = []
            row.append(order._date)
            row.append(order._orderId)
            row.append(createBarcodeDrawing('Code128', value=order._orderId, height=10, width=120))
            row.append(order._productName)
            data.append(row)

        # Configure style and word wrap
        # which overrides the table style regarding fontSize
        s_right = getSampleStyleSheet()
        s_right = s_right["BodyText"]
        s_right.wordWrap = 'CJK'
        s_right.fontSize = 8
        s_right.alignment = TA_RIGHT

        data_with_style = []
        for row in data:
            data_with_style_row = []
            for i in range(len(row)):
                if i == len(row) - 1:
                    data_with_style_row.append(Paragraph(str(row[i]), s_right))
                else:
                    data_with_style_row.append(row[i])
            data_with_style.append(data_with_style_row)

        t = Table(data_with_style, colWidths=[100, 70, 120, 210])  # whole width is 500
        style = TableStyle([('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
                            ('BOX', (0, 0), (-1, -1), 0.25, colors.black),  # border of table
                            ])
        t.setStyle(style)
        elements.append(t)   

    def do(self):
        """
        Entry method of the class
        :rtype: BytesIO
        """
        logger.info("picklist.py do()")

        doc = SimpleDocTemplate(self._buffer, pagesize=A4,
                                rightMargin=72, leftMargin=72,
                                topMargin=72, bottomMargin=72)
        elements = []
        self.write_content(elements)
        doc.build(elements, canvasmaker=NumberedCanvas)

        # Get the value of the BytesIO buffer and write it to the response.
        # comment the following lines if debug with __main__
        pdf = self._buffer.getvalue()
        self._buffer.close()
        return pdf
