# By: Riasat Ullah
# This file contains the class that creates an invoice.

from fpdf import FPDF
from utils import constants, var_names


class Invoice(FPDF):

    def __init__(self, *args, **kwargs):
        super().__init__()
        self.font_family = 'helvetica'

    def create_pdf(self, location, details):
        self.add_page()
        self.company_info(details[var_names.account_id], details[var_names.organization_name],
                          details[var_names.address], details[var_names.city], details[var_names.state],
                          details[var_names.zip_code], details[var_names.country_name], details[var_names.vat_id])
        self.invoice_summary(details[var_names.bill_id], details[var_names.bill_date],
                             details[var_names.billing_currency], details[var_names.bill_total])
        self.bill(details[var_names.start_period], details[var_names.end_period], details[var_names.billing_currency],
                  details[var_names.bill_items], details[var_names.sub_total], details[var_names.bill_total],
                  details[var_names.vat], details[var_names.vat_percent], details[var_names.discount_items],
                  details[var_names.credit_used])
        self.output(location)

    def company_info(self, account_number, organization_name, address, city, state, zip_code, country_name, vat_id):
        self.set_font(self.font_family, '', 10)
        self.cell(70, txt='Account Number:')
        self.ln()
        self.set_font(self.font_family, '', 14)
        self.cell(70, txt=account_number)
        self.ln(20)

        self.set_font(self.font_family, '', 10)
        self.cell(70, txt='Bill to:')
        self.ln()
        self.set_font(self.font_family, '', 12)
        self.multi_cell(70, txt='ATTN: ' + organization_name, new_y='LAST')
        self.ln()
        self.multi_cell(70, txt=address, new_y='LAST')
        self.ln()
        self.multi_cell(70, txt=', '.join([city, state, zip_code]), new_y='LAST')
        self.ln()
        self.multi_cell(70, txt=country_name, new_y='LAST')
        if vat_id is not None:
            self.ln(5)
            self.multi_cell(70, txt='VAT ID: ' + vat_id)
        self.ln()

    def invoice_summary(self, bill_id, bill_date, billing_currency, bill_total):
        self.set_xy(self.l_margin + 75, self.t_margin)
        self.set_font(self.font_family, 'B', 15)
        self.cell(w=self.epw-75, txt='TaskCall Inc. Invoice')
        self.ln()
        self.set_x(self.l_margin + 75)
        self.set_font(self.font_family, '', 10)
        self.set_line_width(0.7)
        self.set_draw_color(192, 192, 192)
        self.cell(w=self.epw-75, h=9, txt='Email us about your account or bill at support@taskcallapp.com', border='B')
        self.ln(18)

        self.set_x(self.l_margin + 75)
        self.set_font(self.font_family, 'B', 12)
        self.cell(w=self.epw-75, txt='Invoice Summary')
        self.ln()
        self.set_x(self.l_margin + 75)
        self.set_font(self.font_family, '', 10)
        self.cell(w=self.epw-75-50, txt='Invoice number:')
        self.cell(w=50, txt=bill_id, align='R')
        self.ln()
        self.set_x(self.l_margin + 75)
        self.set_font(self.font_family, '', 10)
        self.cell(w=self.epw-75-50, txt='Invoice date:')
        self.cell(w=50, txt=bill_date.strftime(constants.date_hyphen_format), align='R')
        self.ln()
        self.set_x(self.l_margin + 75)
        self.set_font(self.font_family, 'B', 12)
        self.set_line_width(0.7)
        self.set_draw_color(192, 192, 192)
        self.cell(w=self.epw-75-50, h=13, txt='Total Amount Due On ' + bill_date.strftime(constants.date_hyphen_format),
                  border='B')
        self.cell(w=50, h=13, txt=billing_currency + ' ' + str(bill_total), border='B', align='R')
        self.ln()

    def bill(self, start_period, end_period, billing_currency, bill_items, sub_total, bill_total, vat,
             vat_percent, discount_items, credit_used):
        self.set_x(self.l_margin)
        self.ln(15)
        self.set_font(self.font_family, 'B', 13)
        self.cell(txt='Billing Period: ' + start_period.strftime(constants.date_hyphen_format) + ' - ' +
                      end_period.strftime(constants.date_hyphen_format))
        self.ln()
        self.set_font(self.font_family, '', 10)
        self.multi_cell(w=self.epw, txt="Greetings from TaskCall Inc. This document is an electronic " +
                                        "invoice for your usage of TaskCall's services. If you have any questions " +
                                        "please reach out to us from your account's support page.")
        self.ln()

        # table column widths
        t1_desc_col_width = (self.epw/10) * 5
        t2_desc_col_width = (self.epw/10) * 6.66667
        item_col_width = (self.epw/10) * 1.66667

        # create bill items table
        self.create_table(['Description', 'Unit Price (' + billing_currency + ')',
                           'Quantity', 'Amount (' + billing_currency + ')'],
                          [[x[var_names.item_description], x[var_names.subscription_fee],
                            x[var_names.item_quantity], x[var_names.item_total]] for x in bill_items],
                          t1_desc_col_width, item_col_width, False)

        # create bill summary table
        bill_summary_data = [['Subtotal', billing_currency, sub_total]]
        if discount_items is not None:
            for item in discount_items:
                bill_summary_data.append(
                    [item[var_names.description], item[var_names.billing_currency], item[var_names.discount]]
                )
        if credit_used is not None and credit_used > 0:
            bill_summary_data.append(['Credits Applied', billing_currency, credit_used])

        bill_summary_data.append(['VAT (' + str(vat_percent) + ')', billing_currency, vat])
        bill_summary_data.append(['Total', billing_currency, bill_total])

        self.create_table(['Summary', '', ''], bill_summary_data, t2_desc_col_width, item_col_width, True)

    def create_table(self, headers, data, desc_col_width, item_col_width, last_row_bold=False):
        rows = [headers]
        rows += data
        for i in range(0, len(rows)):
            for j in range(0, len(rows[i])):
                if j == 0:
                    col_width = desc_col_width
                    alignment = 'L'
                else:
                    col_width = item_col_width
                    alignment = 'R'

                self.set_line_width(0.2)
                self.set_draw_color(192, 192, 192)
                if i == 0:
                    self.set_font(self.font_family, 'B', 10)
                    self.set_fill_color(181, 211, 231)
                    self.multi_cell(w=col_width, h=12, txt=str(rows[i][j]), border='TB', fill=True, new_y='LAST',
                                    align=alignment)
                else:
                    if i == len(rows) - 1 and last_row_bold:
                        self.set_font(self.font_family, 'B', 12)
                    else:
                        self.set_font(self.font_family, '', 10)
                    self.multi_cell(w=col_width, h=12, txt=str(rows[i][j]), border='B', fill=False, new_y='LAST',
                                    align=alignment)
            self.ln()
        self.ln()
