"""
 * @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 locale

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
from reportlab.graphics.shapes import Drawing
from reportlab.graphics.barcode import eanbc, qr, usps
from reportlab.platypus.doctemplate import KeepTogether
from reportlab.lib.pagesizes import letter

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

locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')


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 SogoodPrintable:
    """
    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,
                 is_sogood,
                 platform_id,
                 order_date,
                 type,
                 tax,
                 customerCompany,
                 customerTitle,
                 customerSurname,
                 customerFirstname,
                 customerStreet,
                 customerPostcode,
                 customerCity,
                 customerCountry,
                 customerMail,
                 customerTelephone,
                 paymentMethod,
                 paymentDetails,
                 paidSum,
                 paidTax,
                 shippingMethod,
                 shippingDatails,
                 soldItems,
                 comment,
                 memo_ab,
                 docNo,
                 shippingDate,
                 docDate,
                 show_customer_name_in_doc,
                 vat_nr,
                 arbeitsort,
                 dealWith,
                 country,
                 orderId,
                 systemId):
        """
        :param buffer:
        :param is_sogood: False
        :param platform_id(new): 9876543210 : if afterbuy-id available, else goodone-order id
        :param order_date(new): "25.06.2018 09:30:00" - new
        :param type(new): 0 Angebot, 1 Auftragsbestätigung, 2 Lieferschein, 3 Rechnung
        :param tax(new): 19
        :param customerCompany: "Muster International GmbH"
        :param customerTitle(new): "Herr"
        :param customerSurname: "Müller"
        :param customerFirstname: "Thomas"
        :param customerStreet: "Hans-Kohl-Str. 27"
        :param customerPostcode: "64646"
        :param customerCity: "Heppenheim"
        :param customerCountry: "Deutschland"
        :param customerMail: "thomas.müller@muster.de"
        :param customerTelephone: "+49 151 00000000"
        :param customerShippingCompany: "Muster International GmbH"
        :param customerShippingSurname: "Müller"
        :param customerShippingFirstname: "Thomas"
        :param customerShippingStreet: "Hans-Kohl-Str. 27"
        :param customerShippingPostcode: "64646"
        :param customerShippingCity: "Heppenheim"
        :param customerShippingCountry: "Deutschland"
        :param paymentMethod: "Paypal"
        :param paymentDetails: "http://url_to_qrcode"
        :param paidSum: "289.00"
        :param paidTax(new): "50.00"
        :param shippingMethod: "DHL/DPD/EkremTranksport"
        :param shippingDatails: "28.06.2018"
        :param soldItems:
             {"items":
              [
                {
                  "ean": "4250755330211",
                  "quantity": "1",
                  "price": "310.99",
                  "comment": "ECHT GLAS DUSCHE DUSCHABTRENNUNG DUSCHKABINE AUS SICHERHEITSGLAS RAVENNA17-2",
                  "tax": "19"
                 },
                {
                  "ean": "4250755304137",
                  "quantity": "3",
                  "price": "60.99",
                  "comment": "WC SITZ TOILETTENDECKEL KLODECKEL KLOBRILLE TOILETTENSITZ SOFTCLOSE WCD376",
                  "tax": "19"
                },
                {
                  "ean": "4250755323091",
                  "quantity": "1",
                  "price": "260.99",
                  "comment": "140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 <br/>
                             Breite (cm): 140 cm <br/>
                             Stabilisator: 4 - eckig (BRAM2)",
                  "tax": "19"
                },
                {
                  "ean": "4250755323091",
                  "quantity": "2",
                  "price": "520.99",
                  "comment": "LUXUS DUSCHE DUSCHWAND DUSCHABTRENNUNG AUS ECHTGLAS VARIABEL 80-120CM BREMEN 1s",
                  "tax": "19"
                },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "109.99",
                  "comment": "ABLAUFGARNITUR SIPHON DUSCHTASSE Ø90MM <br/> ABLAUFLOCH GERUCHVERSCHLUSS AL02",
                  "tax": "19"
                },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "29.95",
                  "comment": "Nano-M für Duschwand Wachbecken WC & <br/> Bildet SOGOOD",
                  "tax": "19"},
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "29.95",
                  "comment": "Nano-M für Duschwand Wachbecken WC & <br/> Bildet SOGOOD",
                  "tax": "19"
                 },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "29.95",
                  "comment": "Nano-M für Duschwand Wachbecken WC & <br/> Bildet SOGOOD",
                  "tax": "19"
                },
                {
                  "ean": "4250755323527",
                  "quantity": "1",
                  "price": "329.95",
                  "comment": "Bremen2ms 90x200 cm 10 mm (BR10703MS 90)",
                  "tax": "19"
                },
                {
                  "ean": "4250755323091",
                  "quantity": "1",
                  "price": "260.99",
                  "comment": "140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 <br/>
                            Breite (cm): 140 cm <br/>
                            Stabilisator: 4 - eckig (BRAM2)",
                  "tax": "19"
                },
                {
                  "ean": "",
                  "quantity": "1",
                  "price": "-260.99",
                  "comment": "4% Rabatt auf Ihre Bestellung",
                  "tax": "19"
                },
                {
                  "ean": "",
                  "quantity": "1",
                  "price": "-300.99",
                  "comment": "5% Rabatt auf Ihre Bestellung",
                  "tax": "19"
                }
              ]
            }
        :param comment: "testing memo..."
        """
        self._buffer = buffer
        self._type = type
        self._is_sogood = is_sogood
        self._platform_id = platform_id
        self._order_date = order_date
        self._tax = tax
        self._customer_company = customerCompany
        self._customer_title = customerTitle
        self._customer_surname = customerSurname
        self._customer_firstname = customerFirstname
        self._customer_street = customerStreet
        self._customer_postcode = customerPostcode
        self._customer_city = customerCity
        self._customer_country = customerCountry
        self._customer_mail = customerMail
        self._customer_Telephone = customerTelephone
        self._payment_method = paymentMethod
        self._payment_details = paymentDetails
        self._payment_sum = paidSum
        self._payment_tax = paidTax
        self._shipping_method = shippingMethod
        self._shiping_details = shippingDatails
        self._sold_items = soldItems
        self._comment = comment
        self._memo_ab = memo_ab
        self._docNo = docNo
        self._shippingDate = shippingDate
        self._docDate = docDate
        self._show_customer_name_in_doc = show_customer_name_in_doc
        self._vat_nr = vat_nr
        self._arbeitsort = arbeitsort
        self._deal_with = dealWith
        self._country = country
        self._orderId = orderId
        self._systemId = systemId

    def header(self, c, doc, is_first_page) -> None:
        """
        Header on each page
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """

        styles = getSampleStyleSheet()
        styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
        styles.add(ParagraphStyle(name='Right', alignment=TA_RIGHT))
        print(f"self._is_sogood: {self._is_sogood}, type: {type(self._is_sogood)}")  # 调试输出
        # FIXME: check self._is_sogood
        logo = "images/sogood.png"
        if self._is_sogood:
            im = Image(logo, 1.980 * inch, 0.580 * inch)
        else:
            logo = "images/newmaimai.png"
            im = Image(logo, 1.980 * inch, 0.680 * inch)
        if self._country == "":
            logo = "images/logo_pdf.png"
            im = Image(logo, 2.4 * inch, 0.859 * inch)
            im.drawHeight = 1.0 * inch  # Adjust as necessary
            im.drawWidth = 2.5 * inch

        if is_first_page:
            print("is_first_page")
        else:
            im.drawOn(c, doc.leftMargin + 2 * mm, doc.height + doc.bottomMargin)

        if is_first_page:

            # Style
            PaSt1 = ParagraphStyle(name='Normal', fontSize=9, leading=12)
            #  alignment=TA_RIGHT这个是右对齐的意思
            PaSt2 = ParagraphStyle(name='Normal', fontSize=9, leading=12, alignment=TA_RIGHT)
            # 创建一个段营样式，使得文本在段营中靠右但不右对齐
            # PaSt2 = ParagraphStyle(name='Normal', fontSize=9, leading=10,alignment=TA_LEFT)  # 使用 TA_LEFT 来使文本在段营中靠右但不右对齐

            # Val
            doc_nr_title = "Dokumenten-Nr."
            if self._type == "0":
                doc_nr_title = "Angebots-Nr.";
            elif self._type == "1":
                doc_nr_title = "Bestell-Nr.";
            elif self._type == "2":
                doc_nr_title = "Lieferschein-Nr.";
            elif self._type == "3":
                doc_nr_title = "Rechnungs-Nr.";
            elif self._type == "5":
                doc_nr_title = "Gutschrift Nr.:";

            vendor_addr_inLine = """<font size="7">
             <br/>
             <br/>
            <u> Mai & Mai GmbH,Albert-Einstein-Str.6,63128 Dietzenbach,DE</u>
            </font>
            """
            if (self._is_sogood):
                vendor_addr_inLine = """<font size="7" >
                    <br/>
                    <br/>
                    <u>Sogood International GmbH, Gutenbergring 1- 63110 Rodgau, DE</u>
                    </font>
                    """
            # 创建包含实际文本的 Paragraph 对象
            vendor_addr_inLine_p = Paragraph(vendor_addr_inLine, styles["Normal"])
            # distance between two addrs
            empty_row_between_addrs_p = Paragraph("""<font size="9"> <br/></font>""", styles["Normal"]);
            if (len(self._customer_company) < 1):
                empty_row_between_addrs_p = Paragraph("""<font size="9"></font>""", styles["Normal"]);

            # address of customer
            if (self._show_customer_name_in_doc == 'Y'):
                if self._type == "2":
                    customer_addr = """<font>
                        <b>%s</b><br/>
                        %s %s<br/>
                        ( %s )<br/>
                        %s<br/>
                        %s %s<br/>
                        %s</font>
                        """ % (self._customer_shipping_company,
                               self._customer_shipping_firstname, self._customer_shipping_surname,
                               self._customer_shipping_Telephone,
                               self._customer_shipping_street,
                               self._customer_shipping_postcode, self._customer_shipping_city,
                               self._customer_shipping_country)
                else:
                    customer_addr = """<font>
                                    <b>
                                    %s %s</b><br/>
                                    %s<br/>
                                    %s %s<br/>
                                    %s</font>
                                    """ % (
                        self._customer_firstname, " & " + self._customer_surname,
                        self._customer_street,
                        self._customer_postcode, self._customer_city,
                        self._customer_country)
            else:
                if self._type == "2":
                    customer_addr = """<font>
                        <b>%s</b><br/>
                        ( %s )<br/>
                        %s<br/>
                        %s %s<br/>
                        %s</font>
                        """ % (self._customer_shipping_company,
                               self._customer_shipping_Telephone,
                               self._customer_shipping_street,
                               self._customer_shipping_postcode, self._customer_shipping_city,
                               self._customer_shipping_country)
                else:
                    customer_addr = """<font>
                        <b>%s</b><br/>
                        %s<br/>
                        %s %s<br/>
                        %s</font>
                        """ % (
                    self._customer_company if self._customer_company is not None else self._customer_shipping_company,
                    self._customer_street if self._customer_street is not None else self._customer_shipping_street,
                    self._customer_postcode if self._customer_postcode is not None else self._customer_shipping_postcode,
                    self._customer_city if self._customer_city is not None else self._customer_shipping_city,
                    self._customer_country if self._customer_country is not None else self._customer_shipping_country)

            customer_addr_p = Paragraph(customer_addr, PaSt1)
            im1 = Image("images/phone.png", 0.15 * inch, 0.15 * inch)
            im2 = Image("images/email.png", 0.15 * inch, 0.15 * inch)
            im3 = Image("images/web.png", 0.15 * inch, 0.15 * inch)

            # FIXME: check self._is_sogood
            # tel = "+49 6106 6670592"
            # email_info = "info@maimai24.de"
            # web_info = "www.maimai24.de"
            tel = """
                   <font><img src="images/phone.png" width="12" height="12"/>
                   &nbsp;+49 6106 6670592</font>
                  """
            email_info = """
                        <font><img src="images/email.png" width="12" height="12"/>
                        &nbsp;info@maimai24.de</font>
                       """
            web_info = """
                        <font><img src="images/web.png" width="12" height="12"/>
                        &nbsp;www.maimai24.de</font>
                       """
            if self._is_sogood:
                tel = """
                     <font><img src="images/phone.png" width="12" height="12"/>
                     &nbsp;+49 6106 6667585</font>
                    """
                email_info = """
                            <font><img src="images/email.png" width="12" height="12"/>
                            &nbsp;info@sogood.de</font>
                             """
                web_info = """
                              <font><img src="images/web.png" width="12" height="12"/>
                              &nbsp;www.sogood.de</font>
                           """
            if (self._arbeitsort == 'Showroom-Gelnhausen'):
                vendor_addr = """<font>
                          <b>Mai & Mai GmbH</b><br/>
                          Gutenbergring 1<br/>
                          63110 Rodgau<br/>
                          Tel.: +49 6106 667585<br/>
                          E-Mail: M.Oymak@doporro.de<br/>
                          www.doporro.com<br/>
                          <br/>
                          </font>
                          """

            if (self._arbeitsort == 'Showroom-Heusenstamm'):
                vendor_addr = """<font>
                          <b>Mai & Mai GmbH</b><br/>
                          Seligenstädter Grund 11<br/>
                          63150 Heusenstamm<br/>
                          Tel.: +49 6104 8023762<br/>
                          E-Mail: M.Oymak@doporro.de<br/>
                          www.doporro.com<br/>
                          <br/>
                          </font>
                          """

            if (self._arbeitsort == 'Showroom-Dietzenbach'):
                vendor_addr = """<font>
                    <b>Mai & Mai GmbH</b><br/>
                    Albert-Einstein-Str. 6<br/>
                    63128 Dietzenbach<br/>
                    Tel.: +49 6074 9146769<br/>
                    E-Mail: M.Oymak@doporro.de<br/>
                    www.doporro.com<br/>
                    <br/>
                    </font>
                    """

            if (self._deal_with == 'ersatzteil' and self._is_sogood):
                vendor_addr = """<font>
                    <b>Sogood international GmbH</b><br/>
                    Gutenbergring 1<br/>
                    63110 Rodgau<br/>
                    Tel.: +49 6106 6670592<br/>
                    www.sogood.de<br/>
                    <br/>
                    </font>
                    """

            # 假设这些是你要用在新表格中的数据
            new_data = [
                [[], Paragraph(tel, PaSt1)],
                [[], Paragraph(email_info, PaSt1)],
                [[], Paragraph(web_info, PaSt1)],
            ]
            # new_data = [
            #     [im1, Paragraph(tel, PaSt1)],
            #     [im2, Paragraph(email_info, PaSt1)],
            #     [im3, Paragraph(web_info, PaSt1)],
            # ]
            # 创建新的三行两列的表格，设置行高为相同的值
            row_height = 5.5 * mm  # 可以根据需要调整这个值。可以设置表格的高度
            # new_table = Table(new_data, colWidths=[1.788 * inch, 1.5 * inch], rowHeights=[row_height] * len(new_data))
            new_table = Table(new_data, colWidths=[1.530 * inch, 1.5 * inch], rowHeights=[row_height] * len(new_data))
            # new_table = Table(new_data, colWidths=[1.79 * inch, 1.5 * inch])

            # 设置新表格的样式
            new_table.setStyle(TableStyle([
                ('FONT', (0, 0), (-1, -1), 'Helvetica'),
                ('BACKGROUND', (0, 0), (-1, -1), colors.white),  # 设置背景颜色为白色
                ('GRID', (0, 0), (-1, -1), 0, colors.white),  # 设置边框宽度为0,边框颜色为白色
                ('ALIGN', (0, 0), (0, -1), 'RIGHT'),  # 第一列右对齐
                ('ALIGN', (1, 0), (1, -1), 'LEFT'),  # 第二列左对齐
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 设置内容垂直居中
            ]))
            # vendor_addr_p = Paragraph(vendor_addr, PaSt2)
            newInfo1 = """
                      <font size="9"> 
                      <br/>
                      </font>
                        """;
            vendor_new_info1 = Paragraph(newInfo1, PaSt2)
            # 这是新增的右边中间的那一行
            newInfo = """<font>
                        <b>Lager:</b>Gutenbergring1<br/>
                          63110 Rodgau, DE<br/>
                        <b>Tel.:</b>+49 6106 667585<br/>
                         <br/>
                        </font>"""
            vendor_new_info = Paragraph(newInfo, PaSt2)

            self._vat_nr = ""
            if (self._vat_nr == ""):
                doc_info = """<font>
                <b>%s: </b>%s<br/>
                <b>Datum: </b>%s<br/>
                <b>Bezug auf Rechnung Nr.: </b>%s<br/>
                <b>Bestellnummer: </b>%s
                </font>""" % (doc_nr_title, self._platform_id,self._docDate, self._docNo, self._systemId)
            else:
                doc_info = """<font>
                <b>%s: </b>%s<br/>
                <b>Datum: </b>%s<br/>
                <b>Lieferdatum: </b>%s<br/><br/>
                <b>MwSt-Nr.(VAT): </b>%s
                </font>""" % (doc_nr_title, self._docNo, self._docDate, self._shippingDate, self._vat_nr)

            doc_info_p = Paragraph(doc_info, PaSt2);

            data = [[[im, vendor_addr_inLine_p, empty_row_between_addrs_p, customer_addr_p],
                     [new_table, vendor_new_info1, vendor_new_info, doc_info_p]]]
            # data = [[[vendor_addr_inLine_p, empty_row_between_addrs_p, customer_addr_p], [vendor_addr_p,doc_info_p]]]
            table = Table(data, colWidths=4 * inch, rowHeights=100 * mm)

            style = TableStyle([
                ('FONT', (0, 0), (-1, -1), 'Helvetica'),
                ('LEFTPADDING', (0, 0), (-1, -1), 40),  # not clean solution, but works somehow
                ('RIGHTPADDING', (0, 0), (-1, -1), 40),  # not clean solution, but works somehow
                ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                # TEST
                # ('GRID', (0, 0), (-1, -1), 0.5, colors.red)
            ])

            table.setStyle(style)
            w1, h1 = table.wrap(doc.width, doc.bottomMargin)
            table.drawOn(c, doc.width / 2 + doc.leftMargin - w1 / 2, doc.height + doc.bottomMargin - (85 * mm))
            # # 在表格下方绘制线条。300代表距离A4纸最上面的高度
            line_y = letter[1] - 165  # 设置线条的y坐标，距离顶表格高度
            c.setStrokeColor(colors.black)  # 设置线条颜色为黑色
            c.setLineWidth(1)  # 设置线条宽度
            # 设置线条的宽度为w1 -30
            c.line(50, line_y, w1 - 30, line_y)  # 绘制线条

    def footer(self, c, doc) -> None:
        """
        Footer on each page
                Runs demo demonstrating usage of Spreadsheet Tables.
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """
        # 创建样式
        normal_style = ParagraphStyle('Normal', fontSize=7, leading=12)
        # FIXME: check self._is_sogood
        # data = [
        #     ["Mai & Mai GmbH", "Telefon: +49 6106 6670592", "Amtsgericht Offenbach", "Bankverbindung:", "IBAN: DE7250 040000"],
        #     ["Gutenbergring 1", "E-Mail: info@maimai24.de", "HRB 44229", "Commerzbank", "0413 0589 00"],
        #     ["63110 Rodgau", "", "Geschäftsführerin: Wei Tao".encode('utf-8'), "BLZ: 50040000", "BIC: COBADEFF004"],
        #     ["Deutschland", "", "", "Konto: 413058900", "USt-IdNr: DE265808049"]
        # ]
        first_info = """<font>
                        Amtsgelicht Offenbach<br/>
                        HRB 42229<br/>
                        <b>Geschäftsführer:</b> Wei Tao<br/>
                        </font>
                        """
        first_info1 = Paragraph(first_info, normal_style)
        two_info = """<font>
                      <b>Bankverbindung:</b> Commerzbank<br/>
                      <b>BLZ:</b> 50040000<br/>
                      <b>Konto:</b> 413058900<br/>
                      </font>
                      """
        two_info1 = Paragraph(two_info, normal_style)
        third_info = """<font>
                         <b>BIC:</b> COBADEFF004<br/>
                         <b>IBAN:</b> DE7250 040000 0413 0589 00<br/>
                         <b>USt-IdNr:</b> DE265808049<br/>
                         </font>
                         """
        third_info1 = Paragraph(third_info, normal_style)
        if (self._is_sogood):
            first_info = """<font>
                             Amtsgelicht Offenbach<br/>
                             HRB 42229<br/>
                             <b>Geschäftsführer:</b> Shaoyan Huang<br/>
                             </font>
                             """
            first_info1 = Paragraph(first_info, normal_style)
            two_info = """<font>
                           <b>Bankverbindung:</b> Commerzbank<br/>
                           <b>BLZ:</b> 50080000<br/>
                           <b>Konto:</b> 0635289300<br/>
                           </font>
                           """
            two_info1 = Paragraph(two_info, normal_style)
            third_info = """<font>
                              <b>BIC:</b> DRESDEFFXXX<br/>
                              <b>IBAN:</b> DE3350 080000 0635 2893 00<br/>
                              <b>USt-IdNr:</b> DE814341426<br/>
                              </font>
                              """
            third_info1 = Paragraph(third_info, normal_style)
        data = [[[first_info1], [two_info1], [third_info1]]]

        # 设置表格样式
        style = TableStyle([
            ('FONT', (0, 0), (-1, -1), 'Helvetica'),  # 所有单元格字体为 Helvetica
            ('FONTSIZE', (0, 0), (-1, -1), 6),  # 所有单元格字体大小为 6
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),  # 所有单元格水平左对齐
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有单元格垂直居中
        ])

        # 调整列宽以确保均匀分布
        col_widths = [2.6 * inch, 2.6 * inch, 2.6 * inch]
        table = Table(data, colWidths=col_widths, rowHeights=0.5 * cm)
        # Configure style and word wrap
        # s = getSampleStyleSheet()
        # s = s["BodyText"]
        # s.wordWrap = 'CJK'
        # data2 = [[Paragraph(cell, s) for cell in row] for row in data]
        # t = Table(data2)
        # table = Table(data, colWidths=[91.711, 116.654, 117.038, 86.339, 88.257], rowHeights=0.3 * cm)
        table.setStyle(style)

        w, h = table.wrap(doc.width, doc.bottomMargin)
        # doc.height - doc.bottomMargin - (182*mm)代表的是表格距离顶部的距离，
        table.drawOn(c, doc.leftMargin, doc.height - doc.bottomMargin - (182 * mm))
        # 在表格上方绘制线条
        line_y = 80 + table._height + 1  # 使用 _height 属性获取表格的高度
        c.setStrokeColor(colors.black)
        c.setLineWidth(1)
        line_width = doc.width - 20  # 设置线条的宽度
        # 48代表距离页面左边的距离。50 + line_width 代表距离页面右边的距离 + 线条长度
        c.line(48, line_y, 50 + line_width, line_y)

    def header_footer_first_page(self, c, doc) -> None:
        """
        First Page
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """
        # Save the state of our canvas so we can draw on it
        c.saveState()
        self.header(c, doc, True)
        self.footer(c, doc)
        # Release the canvas
        c.restoreState()

    def header_footer_later_pages(self, c, doc) -> None:
        """
        First Page
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """
        # Save the state of our canvas so we can draw on it
        c.saveState()
        self.header(c, doc, False)
        self.footer(c, doc)
        # Release the canvas
        c.restoreState()

    def write_content(self, elements, doc) -> None:
        """
        write first page content
        :param elements:
        """
        # MY_Justify 用于正文内容的两端对齐。
        # MY_Right 用于右侧对齐的文本（例如日期、地址等信息）。
        # MY_Center 用于居中的文本（例如标题或注释）。
        # MY_Head 用于大标题或强调的文本。
        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"))

        if (self._type == "2"):
            elements.append(Spacer(1, 120))
            ptext = '<font size=8>Auftrag %s am %s</font>' % (self._platform_id, self._order_date)
            elements.append(Paragraph(ptext, styles["Normal"]))
            elements.append(createBarcodeDrawing('Code128', value=self._platform_id, height=40, width=120))

        # Val
        letter_greeting = "Sehr geehrte Damen und Herren"
        letter_text = ""
        if self._type == "0":
            letter_text = "herzlichen Dank für Ihre Anfrage.<br/>gerne unterbreiten wir Ihnen hiermit folgendes Angebot:"
        elif self._type == "1":
            letter_text = "vielen Dank für Ihre Bestellung. Wir freuen uns über Ihren Auftrag.<br/>Details entnehmen Sie bitte der folgenden Übersicht:"
        elif self._type == "2":
            letter_text = "wir bedanken uns für die gute Zusammenarbeit und liefern Ihnen wie vereinbart folgende Waren:"
        elif self._type == "3":
            letter_text = "vielen Dank für Ihre Bestellung und das uns entgegengebrachte Vertrauen.<br/>Wir berechnen Ihnen hiermit wie folgt:"
        letter_text = "vielen Dank für Ihre Bestellung und das uns entgegengebrachte Vertrauen.<br/>Wir stellen Ihnen hiermit folgende Gutschrift aus:"
        # elements.append(Spacer(1, 60))
        # ptext = '<font size=8>Auftrag %s am %s</font>' % (self._platform_id, self._order_date)
        # elements.append(Paragraph(ptext, styles["Normal"]))
        # elements.append(createBarcodeDrawing('Code128', value='001234567890',  height=40))

        # 创建空白区域
        if (self._type == "2"):
            elements.append(Spacer(1, 20))
        else:
            elements.append(Spacer(1, 115))

        elements.append(Spacer(1, 25))
        # FIXME: check self._type
        if self._type == '0':
            ptext = '<font size=20><b>Angebot</b></font>'
        elif self._type == '1':
            ptext = '<font size=20><b>Auftragsbestätigung</b></font>'
        elif self._type == '2':
            ptext = '<font size=20><b>Lieferschein</b></font>'
        else:
            ptext = '<font size=20><b>Gutschrift</b></font>'

        elements.append(Paragraph(ptext, styles["Normal"]))

        # 创建一个空白行
        elements.append(Spacer(1, 26))
        # 空白行下面添加内容
        ptext = '<font size=10><b>%s</b>,</font>' % (letter_greeting)
        elements.append(Paragraph(ptext, styles["Normal"]))

        # 添加一个空白行
        elements.append(Spacer(1, 10))
        ptext = '<font size=10>%s</font>' % (letter_text)
        # 使用了My_Justify样式，左右对齐
        elements.append(Paragraph(ptext, styles["MY_Justify"]))

        # 添加空白行，创建表格
        # Spacer(1, 15)：第一个参数 1 表示宽度（通常用于水平方向上的空隙，但此处为1说明没有水平方向上的空隙），第二个参数 15 表示空白的高度为 15 点。
        elements.append(Spacer(1, 15))
        elements.append(self.table1())

        if (self._type != '2'):
            elements.append(Spacer(1, 20))
            elements.append(self.tableSumInfo())

        elements.append(Spacer(1, 40))

        ptext = '<font size=10><b>Zahlungsmethode: (GOGSA)</b></font>'
        elements.append(Paragraph(ptext, styles["Normal"]))
        elements.append(Spacer(1, 5))
        ptext = '<font size=10>[Gutschrift] Die originale Afterbuy Order-ID: %s<br/>Die ware wurde schon an den Kunden versendet.</font>' % (self._orderId)
        elements.append(Paragraph(ptext, styles["Normal"]))
        elements.append(Spacer(1, 10))
        if self._is_sogood :
            ptext = '<font size=10>Mit freundlichen Grüßen<br/>Ihr Sogood Team</font>'
        else:
            ptext = '<font size=10>Mit freundlichen Grüßen<br/>Ihr Mai & Mai Team</font>'
        elements.append(Paragraph(ptext, styles["Normal"]))

        # Paypal QRCode Tip
        if self._payment_method == "Paypal" and self._type != '2':
            elements.append(Spacer(1, 30))
            elements.append(
                Paragraph("<font size=10><b>Zahlungsmethode:</b> %s</font>" % self._payment_method, styles["Normal"]))
            ptext = '<font size=10><br/>Mit Paypal zahlen Sie mittels QR-Code schnell und sicher.<br/>Bitte scannen Sie den folgenden QR-Code:</font>'
            elements.append(Paragraph(ptext, styles["Normal"]))
            # elements.append(Spacer(1, 10))
            # Paypal Logo
            i_p_logo = Image("images/paypal.png", 1.2 * inch, 0.4 * inch)
            # i_p_logo.hAlign = "LEFT"
            elements.append(Spacer(1, 8))  # 将高度从 10 改为 5
            # QR-Code
            i_qr = qr.QrCodeWidget(self._payment_details)
            bounds = i_qr.getBounds()
            width = bounds[2] - bounds[0]
            height = bounds[3] - bounds[1]
            # i_qr_d = Drawing(45, 120, transform=[100./width,0,0,100./height,0,0])
            # i_qr_d.add(i_qr)
            # 调整二维码的大小
            qr_size = 60  # 设置一个比 logo 稍大的尺寸，这里乘以1.5
            scale_factor = qr_size / max(width, height)
            i_qr_d = Drawing(qr_size, qr_size, transform=[scale_factor, 0, 0, scale_factor, 0, 0])
            i_qr_d.add(i_qr)

            # 创建一个包含 logo 和二维码的表格，设置列宽
            data = [[i_p_logo, i_qr_d]]  # 在 logo 和二维码之间添加一个小的 Spacer
            # 使用 drawWidth 获取 logo 的宽度
            table = Table(data, colWidths=[i_p_logo.drawWidth, i_qr_d.width], hAlign='LEFT')

            # 设置表格样式，调整间距
            table.setStyle(TableStyle([
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 垂直居中
                ('BACKGROUND', (0, 0), (-1, -1), colors.white),  # 背景颜色
                ('LEFTPADDING', (0, 0), (-1, -1), 0),  # 左边距
                ('RIGHTPADDING', (0, 0), (-1, -1), 0),  # 右边距
                ('TOPPADDING', (0, 0), (-1, -1), 0),  # 上边距
                ('BOTTOMPADDING', (0, 0), (-1, -1), 0),  # 下边距
                ('GRID', (0, 0), (-1, -1), 0, colors.white),  # 设置表格边框为0
            ]))
            # 调整 logo 和二维码之间的水平间距
            table._argW[0] = i_p_logo.drawWidth  # 调整 logo 列的宽度
            elements.append(table)

            elements.append(Spacer(1, 10))
            # elements.append(i_qr_d)
            # qr-code link
            # elements.append(Spacer(1, 5))
            # ptext = '<font size=10>Als Alternative zur Zahlung können Sie auch den folgenden Link im Computer besuchen:<br/>%s</font>' % (self._payment_details)
            # elements.append(Paragraph(ptext, styles["Normal"]))

        if self._type == '3':
            # Rechnungsbemerkung
            elements.append(Spacer(1, 20))
            ptext = '<font size=10>%s</font>' % (self._comment)
            elements.append(Paragraph(ptext, styles["Normal"]))
        elif self._type == '2':
            # Memo in Lieferschein
            elements.append(Spacer(1, 20))
            ptext = '<font size=10>%s</font>' % (self._memo_ab)
            elements.append(Paragraph(ptext, styles["Normal"]))

        elements.append(Spacer(1, 30))
        # ptext = '<font size=10>Mit freundlichen Grüßen<br/>Ihr Doporro Team</font>'
        # elements.append(Paragraph(ptext, styles["Normal"]))
        # elements.append(Spacer(1, 10))

    @staticmethod
    def table():
        """
        Runs demo demonstrating usage of Spreadsheet Tables.
        :return: Table
        """
        pos = 0
        i = 1
        data = [
            ["Pos", "EAN", "Artikelbezeichnung", "Stammbezeichnung", "P", "A", "Preis"],
            ["%d" % (pos + i), "4251242935322", "ABLAUFGARNITUR SIPHON DUSCHTASSE Ø90MM", "ABLAUFGARNITUR AL02", "1",
             "1", "8,99"],
            ["%d" % (pos + 2), "4250755391915", "140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 \
                                    Breite (cm): 140 cm \
                                    Stabilisator: 4 - eckig (BRAM2)", "Bremen01VG 140 + MMBR2", "1", "1", "288,99"],
            ["%d" % (pos + 3), "", "4% Rabatt auf Ihre Bestellung", "", "1", "1", "-8,99"],
            ["%d" % (pos + 4), "", "5% Rabatt auf Ihre Bestellung", "", "1", "1", "-10,99"],
        ]

        # Configure style and word wrap
        # which overrides the table style regarding fontSize
        s = getSampleStyleSheet()
        s = s["BodyText"]
        s.wordWrap = 'CJK'
        s.fontSize = 8
        data_with_style = [[Paragraph(cell, s) for cell in row] for row in data]
        t = Table(data_with_style, colWidths=[30, 80, 160, 90, 20, 20, 50])  # whole width is 450
        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)
        return t

    def table1(self):
        """
        Runs demo demonstrating usage of Spreadsheet Tables.
        :return: Table
        """
        # data = [
        #     ["Artikelbezeichnung", "Anzahl", "Preis"],
        #     ["ABLAUFGARNITUR SIPHON DUSCHTASSE Ø90MM",  "1", "8,99 Euro"],
        #     ["140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 <br/>\
        #                             Breite (cm): 140 cm <br/>\
        #                             Stabilisator: 4 - eckig (BRAM2)", "1", "288,99 Euro"],
        #     ["5% Rabatt auf Ihre Bestellung", "1", "-10,99 Euro"],
        #     ["", "", "Versandkosten: 0,00 Euro <br/> \
        #               Gesamtkosten ohne Mwst: 250,84 Euro <br/> \
        #               19% Mwst: 29,77 Euro <br/> \
        #               Gesamtkosten: 279 Euro\
        #              "],
        # ]

        data = []

        if self._type != '2':
            data.append(["<b>Pos</b>", "<b>Artikelbezeichnung</b>", "<b>Einzelpreis</b>", "<b>Anzahl</b>",
                         "<b>Gesamtpreis</b>"])
        else:
            data.append(["<b>Pos</b>", "<b>Artikelbezeichnung</b>", "<b>Anzahl</b>"])

        loaded_json = json.loads(self._sold_items, strict=False)

        items_json = loaded_json["items"]
        pos_count = 1
        for x in items_json:
            row = []
            row.append(str(pos_count))
            row.append("<b>" + x["comment"] + "</b><br/>Artikelnummer: " + x["ean"])
            # row.append(self.completeGermanPrice('{0:n}'.format(float(x["price"]))) + " EUR")

            if self._type != '2':
                row.append("0,00" + " EUR")

            row.append("0")

            if self._type != '2':
                row.append("0,00" + " EUR")

            data.append(row)
            pos_count += 1


        gutschrift_comment = "Gutschriftbetrag"
        gutschrift_ean = "8888888888"

        row = []
        row.append(str(pos_count))
        row.append(f"<b>{gutschrift_comment}</b><br/>Artikelnummer: {gutschrift_ean}")

        row.append("-" + self._payment_sum + " EUR")

        row.append("1")

        row.append("-" + self._payment_sum + " EUR")

        data.append(row)

        # FIXME: calculate the price
        # sum_1_val = "0,00"
        # sum_1 = ["", "", "<br/>Versandkosten : ", "", "<br/>" + self.completeGermanPrice(sum_1_val) + " EUR"]
        # data.append(sum_1)
        # sum_2_val = '{0:n}'.format(float(round((float(self._payment_sum)-float(self._payment_tax)), 2)))
        # sum_2 = ["", "", "Zwischensumme : ", "", self.completeGermanPrice(sum_2_val) + " EUR"]
        # data.append(sum_2)
        # sum_3_val = '{0:n}'.format(round(float(self._payment_tax),2))
        # sum_3 = ["", "", "MwSt. " + self._tax + "% : ", "", self.completeGermanPrice(sum_3_val) + " EUR"]
        # data.append(sum_3)
        # sum_4_val = '{0:n}'.format(round(float(self._payment_sum), 2))
        # sum_4 = ["", "", "Gesamtsumme : ", "", self.completeGermanPrice(sum_4_val) + " EUR"]
        # data.append(sum_4)

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

        data_with_style = []
        for row in data:
            data_with_style_row = []
            for i in range(len(row)):
                if self._type != '2':
                    if i == 0:
                        data_with_style_row.append(Paragraph(row[i], s_center))
                    elif i == len(row) - 1:
                        data_with_style_row.append(Paragraph(row[i], s_center))
                    elif i == len(row) - 2:
                        data_with_style_row.append(Paragraph(row[i], s_center))
                    elif i == len(row) - 3:
                        data_with_style_row.append(Paragraph(row[i], s_center))
                    else:
                        data_with_style_row.append(Paragraph(row[i], s))
                else:
                    if i == 0 or i == 2:
                        data_with_style_row.append(Paragraph(row[i], s_center))
                    else:
                        data_with_style_row.append(Paragraph(row[i], s))

            data_with_style.append(data_with_style_row)

        if self._type != '2':
            t = Table(data_with_style, colWidths=[30, 260, 70, 60, 80])  # whole width is 500
            # t = Table(data_with_style, colWidths=[200, 50, 200])
        else:
            t = Table(data_with_style, colWidths=[50, 350, 100])

        # style = TableStyle([
        #     ('VALIGN', (0, 0), (-1, -1), 'CENTER'),
        #     ('LINEBELOW', (0, 0), (-1, -1), 0.25, colors.black),
        #     ('LINEBELOW', (0, 1), (-1, 1), 0.01, colors.black),  # 第二行的下边线变细
        # ])
        new_row = len(data)
        # 设置表格样式
        style = TableStyle([
            ('VALIGN', (0, 0), (-1, -1), 'CENTER'),
            # 第一行下边线为黑色
            ('LINEBELOW', (0, 0), (-1, 0), 0.25, colors.black),
            # ('GRID', (0, 0), (-1, -1), 1, colors.black)  # 添加边框
        ])
        # 为中间的行设置红色下边线
        if new_row > 2:  # 确保有足够的行
            for ro in range(1, new_row - 1):
                style.add('LINEBELOW', (0, ro), (-1, ro), 0.01, colors.gray)
        # 最后一行下边线为黑色
        style.add('LINEBELOW', (0, new_row - 1), (-1, new_row - 1), 0.25, colors.black)
        t.setStyle(style)
        return t

    def tableSumInfo(self):
        """
        This table show the sum info of the order
        :return: Table
        """

        data = []

        # FIXME: calculate the price
        sum_1_val = "-0,00"
        sum_1 = ["", "", "Versandkosten : ", sum_1_val + " EUR"]
        data.append(sum_1)
        sum_2_val = float(self._payment_sum) - float(self._payment_tax)
        # sum_2 = ["", "", "Zwischensumme : ", self.completeGermanPrice(sum_2_val) + " EUR"]
        sum_2 = ["", "", "Zwischensumme : ",  "-" + self.formatPrice(sum_2_val) + " EUR"]
        data.append(sum_2)
        # sum_3_val = '{0:n}'.format(self.roundedTo2Decimals(float(self._payment_tax)))
        # sum_3 = ["", "", "MwSt. " + self._tax + "% : ", self.completeGermanPrice(sum_3_val) + " EUR"]
        sum_3 = ["", "", "MwSt. " + self._tax + "% : ", "-" + self.formatPrice(self._payment_tax) + " EUR"]
        data.append(sum_3)
        # sum_4_val = '{0:n}'.format(self.roundedTo2Decimals(float(self._payment_sum)))
        # sum_4 = ["", "", "<b>Gesamtsumme : </b>", "<b>" + self.completeGermanPrice(sum_4_val) + " EUR</b>"]
        sum_4 = ["", "", "<b>Gesamtsumme :</b>", "<b>" + "-" + self.formatPrice(self._payment_sum) + " EUR</b>"]
        data.append(sum_4)

        # Configure style and word wrap
        # which overrides the table style regarding fontSize
        # 右对齐
        s = getSampleStyleSheet()
        s = s["BodyText"]
        s.wordWrap = 'CJK'
        s.fontSize = 8
        s.alignment = TA_RIGHT
        s.rightIndent = 22
        # 右对齐
        s_right = getSampleStyleSheet()
        s_right = s_right["BodyText"]
        s_right.wordWrap = 'CJK'
        s_right.fontSize = 8
        s_right.alignment = TA_RIGHT
        # 居中对齐
        s_center = getSampleStyleSheet()
        s_center = s_center["BodyText"]
        s_center.wordWrap = 'CJK'
        s_center.fontSize = 8
        s_center.alignment = TA_CENTER

        data_with_style = []
        for row in data:
            data_with_style_row = []
            for i in range(len(row)):
                if i == len(row) - 2:
                    data_with_style_row.append(Paragraph(row[i], s))
                else:
                    data_with_style_row.append(Paragraph(row[i], s_center))
            data_with_style.append(data_with_style_row)

        t = Table(data_with_style, colWidths=[150, 170, 100, 80])  # whole width is 500
        style = TableStyle([
            ('VALIGN', (0, 0), (-1, -1), 'CENTER'),
            # border bottom for summery
            ('LINEBELOW', (-2, 0), (-1, -2), 0.01, colors.black),
            ('LINEBELOW', (-2, -1), (-1, -1), 1.0, colors.black),
            # ('GRID', (0, 0), (-1, -1), 1, colors.black)  # 添加边框
        ])
        t.setStyle(style)
        return t

    def formatPrice(self, p):
        # return locale.currency(float(p), 'EUR')
        p_new = str('{:12,.2f}'.format(float(p)))
        p_new = p_new.replace(",", "#")
        p_new = p_new.replace(".", ",")
        p_new = p_new.replace("#", ".")
        return p_new

    def do(self):
        """
        Entry method of the class
        :rtype: BytesIO
        """
        doc = SimpleDocTemplate(self._buffer, pagesize=A4,
                                rightMargin=43, leftMargin=43,
                                topMargin=90, bottomMargin=90)
        elements = []
        self.write_content(elements, doc)
        doc.build(elements, onFirstPage=self.header_footer_first_page, onLaterPages=self.header_footer_later_pages,
                  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
