from abc import ABCMeta

from _AposA8Align import AposA8Align
from _AposA8CommandType import AposA8CommandType
from _AposA8PrintLine import AposA8PrintLine
from _AposA8Helpers import APOS_HASH, append_items_header, append_and_count_sale_items, APOS_DASH, add_loyalty_custom_text, \
    append_whopper_wifi_code, append_garena_coupons
from _AposA8Constants import AposA8Constants
from printer import FiscalPrinter


AMOUNT_TEMPLATE = "%-36s   R$%7.2f"


class AposA8FiscalPrinter(FiscalPrinter):
    __metaclass__ = ABCMeta

    def __init__(self, mbcontext, print_customer_name, cliche_helper, customer_text_field):

        super(AposA8FiscalPrinter, self).__init__(mbcontext, print_customer_name, cliche_helper)
        self.customer_text_field = customer_text_field

    def print_cancel(self, posid, data):
        # not implemented
        pass

    def _append_total(self, report, order, tenders, items_amount):
        qty_total = "%-36s         %3d" % ("QTD. TOTAL DE ITENS", items_amount)
        report.append(AposA8PrintLine(AposA8Align.CENTER, qty_total, AposA8CommandType.PRINT_TEXT))

        total_amount_value = float(order.get("totalAmount")) + float(order.get("taxTotal"))

        total_amount_text = AMOUNT_TEMPLATE % ("VALOR TOTAL R$", total_amount_value)
        report.append(AposA8PrintLine(AposA8Align.CENTER, total_amount_text, AposA8CommandType.PRINT_TEXT))

        discount_amount_value = float(order.get("discountAmount"))
        discount = AMOUNT_TEMPLATE % ("DESCONTO", discount_amount_value)
        report.append(AposA8PrintLine(AposA8Align.CENTER, discount, AposA8CommandType.PRINT_TEXT))

        total_payable = AMOUNT_TEMPLATE % ("VALOR A PAGAR", total_amount_value - discount_amount_value)
        report.append(AposA8PrintLine(AposA8Align.CENTER, total_payable, AposA8CommandType.PRINT_TEXT))

        payment = "%-36s  %s" % ("FORMA DE PAGAMENTO", "Valor Pago")
        report.append(AposA8PrintLine(AposA8Align.CENTER, payment, AposA8CommandType.PRINT_TEXT))
        for tender in tenders:
            tender_descr = self.get_payment_description(self.mb_context, tender)
            tender_amount = tender.amount + tender.change
            tender_text = AMOUNT_TEMPLATE % (tender_descr, tender_amount)
            report.append(AposA8PrintLine(AposA8Align.CENTER, tender_text, AposA8CommandType.PRINT_TEXT))

        # Get "Change" (sixth value of tender tuple) from last tender in tenders
        change = tenders[len(tenders) - 1].change
        if change > 0:
            order_voided = order.get("state") == "VOIDED"
            factor = -1 if order_voided else 1

            change_text = AMOUNT_TEMPLATE % ("Troco", change * factor)
            report.append(AposA8PrintLine(AposA8Align.CENTER, change_text, AposA8CommandType.PRINT_TEXT))

    def _append_customer_name(self, report, order, customer_name):
        if not self.print_customer_name:
            return

        char_amount = 21
        content = (customer_name or '')[:(char_amount - 2)] or order.get('orderId')[-3:]
        panel_call_text = "PAINEL DE RETIRADA - VOCE SERA CHAMADO POR:"
        report.append(AposA8PrintLine(AposA8Align.CENTER, panel_call_text, AposA8CommandType.PRINT_TEXT))

        report.append(APOS_HASH)
        report.append(AposA8PrintLine(AposA8Align.CENTER, content.upper(), AposA8CommandType.PRINT_TEXT))
        report.append(APOS_HASH)

    def _append_customer_text_field(self, report):
        if self.customer_text_field != "":
            for customer_text in self.customer_text_field.split('\\n'):
                report.append(
                    AposA8PrintLine(AposA8Align.CENTER, customer_text.replace("\\n", ""), AposA8CommandType.PRINT_TEXT))
            report.append(
                AposA8PrintLine(AposA8Align.CENTER, AposA8Constants.SEPARATOR_DASH, AposA8CommandType.PRINT_TEXT))

    @staticmethod
    def _append_satisfaction_survey(report, model, satisfaction_survey_code):
        if satisfaction_survey_code is not None and model is not None:
            report.append(APOS_DASH)
            ssc = satisfaction_survey_code
            satisfaction_survey_code = '-'.join(ssc[i:i + 3] for i in range(0, len(ssc), 3))
            report.append(AposA8PrintLine(AposA8Align.CENTER, satisfaction_survey_code, AposA8CommandType.PRINT_TEXT))
            report.append(APOS_DASH)

    def _append_coupon_body(self, customer_name, model, order, report, tenders, whopper_wifi_code, tip_config):
        append_items_header(report)
        items_amount = append_and_count_sale_items(report, order, model, tip_config)
        report.append(APOS_DASH)
        self._append_total(report, order, tenders, items_amount)
        report.append(APOS_DASH)
        self._append_customer_name(report, order, customer_name)
        append_whopper_wifi_code(report, model, whopper_wifi_code)
        self._append_satisfaction_survey(report, model, self.get_satisfaction_survey_code(order))
        append_garena_coupons(self.mb_context, order, report)

    def _append_cliche(self, report):
        for line in self.cliche_helper.get_cliche():
            report.append(AposA8PrintLine(AposA8Align.CENTER, line, AposA8CommandType.PRINT_TEXT))
        report.append(APOS_DASH)



