from typing import List

from basereport import ReportColumnDefinition, AlignTypes, TableReport
from report import Part
from report.command import NewLineCommand, AlignCommand, RepeatCommand
from reportsdata.benefitsreport.dto import BenefitsBodyDto
from utils import format_price
from utils.report_formatters import remove_accents


class BenefitConsolidatedBuilder(object):
    def __init__(self, body, columns):
        # type: (BenefitsBodyDto, int) -> ()

        self.body = body
        self.columns = columns

        self.header_table_column_definitions = [
            ReportColumnDefinition(width=15, after_text=' ', fill_with_char=''),
            ReportColumnDefinition(width=5,  after_text=' ', fill_with_char='', align=AlignTypes.CENTER),
            ReportColumnDefinition(width=9,  after_text=' ', fill_with_char='', align=AlignTypes.CENTER),
            ReportColumnDefinition(width=9,  after_text=' ', fill_with_char='', align=AlignTypes.CENTER),
        ]

        self.items_table_column_definitions = [
            ReportColumnDefinition(width=15, after_text=' ', fill_with_char=''),
            ReportColumnDefinition(width=5, after_text=' ', fill_with_char='', align=AlignTypes.CENTER),
            ReportColumnDefinition(width=9, align=AlignTypes.RIGHT, fill_with_char='', after_text=' '),
            ReportColumnDefinition(width=9, align=AlignTypes.RIGHT, fill_with_char=''),
        ]

    def generate(self):
        # type: () -> List

        lines = self.body.items
        parts = []
        parts.extend(self._build_header_table())
        total_qty = 0
        total_default_price = 0.0
        total_discount_value = 0.0
        for line in lines:
            qty, default_value, discount_value, benefit_description = lines[line]
            formatted_value = format_price(default_value)
            formatted_discount = format_price(discount_value)
            benefit_description = str(remove_accents(benefit_description)).upper()
            data_table = [benefit_description, str(qty).zfill(4), formatted_value, formatted_discount]
            parts.extend([TableReport([data_table], self.items_table_column_definitions)])

            total_qty += qty
            total_default_price += default_value
            total_discount_value += discount_value

        total_default_price = format_price(total_default_price)
        total_discount_value = format_price(total_discount_value)
        grand_total = [str(total_qty).zfill(4), total_default_price, total_discount_value]
        parts.extend([Part(None, [RepeatCommand(self.columns, "="), NewLineCommand()])])
        parts.extend(self._build_footer_table(grand_total))
        parts.extend([Part(None, [RepeatCommand(self.columns, "="), NewLineCommand()])])

        return parts

    def _build_header_table(self):
        # type: () -> List

        header = [
            Part(None, [NewLineCommand()]),
            TableReport([["$BENEFIT_REPORT_HEADER_PROMOTION_NAME",
                          "$QTY",
                          "$BENEFIT_REPORT_HEADER_DEFAULT_VALUE",
                          "$BENEFIT_REPORT_HEADER_DISCOUNT_VALUE"]],
                        self.header_table_column_definitions),
        ]
        header.extend([Part(None, [RepeatCommand(self.columns, "="), NewLineCommand()])])
        return header

    def _build_footer_table(self, totals):
        # type: (List) -> List

        return [TableReport([["$TOTAL", totals[0], totals[1], totals[2]]], self.items_table_column_definitions)]
