import datetime
from xml.etree import cElementTree as eTree

import sysactions

from printerconstants import (
    TXT_ALIGN_CT,
    CTL_LF,
    TXT_ALIGN_LT,
    SEPARATOR,
    TXT_BOLD_OFF,
    TXT_BOLD_ON,
    TXT_SIZE,
    TXT_WIDTH,
    TXT_HEIGHT,
    TXT_NORMAL,
    HW_INIT,
    TXT_FONT_A,
    COLS,
)


class CashPaymentReport(object):

    def __init__(
        self,
        pos_id,      # type: int
    ):
        # type: (...) -> None

        self.pos_id = pos_id

    def generate(
        self,
        model,              # type: eTree
        current_order,      # type: eTree

    ):
        # type: (...) -> str

        header = self._get_header(
            model=model,
        )

        body = self._get_body(
            model=model,
            current_order=current_order,
        )

        footer = self._get_footer(
            model=model,
        )

        report = "{}{}{}".format(
            header,
            body,
            footer,
        )

        return report.encode(
            encoding="utf-8",
        )

    @staticmethod
    def _get_header(
        model,      # type: eTree
    ):
        # type: (...) -> str

        store_name = sysactions.get_storewide_config(
            parameter="Store.RazaoSocial",
        )

        text = "{}{}{}{}{}".format(
            TXT_FONT_A,
            TXT_ALIGN_CT,
            store_name,
            CTL_LF,
            TXT_FONT_A,
        )

        current_date = datetime.datetime.now().strftime(
            "%d/%m/%Y %H:%M:%S",
        )

        label_date = sysactions.translate_message(
            model=model,
            message_key="DATE_TIME",
        )

        text += "{0}: {1}".format(
            label_date,
            current_date,
        )

        text += "{}{}{}{}".format(
            CTL_LF,
            SEPARATOR,
            CTL_LF,
            TXT_ALIGN_LT,
        )

        return text

    def _get_body(
        self,
        model,              # type: eTree
        current_order,      # type: eTree
    ):
        # type: (...) -> str

        label_totem = self._get_terminal_value(
            model=model,
        )

        label_value = self._get_order_value(
            model=model,
            current_order=current_order,
        )

        size_space_between = COLS - (len(label_totem) + len(label_value))

        text = label_totem
        text += (" " * size_space_between)
        text += label_value

        text += "{}{}{}{}{}{}".format(
            CTL_LF,
            CTL_LF,
            TXT_ALIGN_LT,
            TXT_ALIGN_CT,
            TXT_BOLD_ON,
            TXT_SIZE + chr(TXT_WIDTH[2] + TXT_HEIGHT[2]),
        )

        label_order_number = sysactions.translate_message(
            model=model,
            message_key="ORDER",
        )
        order_number = current_order.get("orderId").zfill(3)
        order_number = order_number[3:] if len(order_number) > 3 else order_number

        text += "{0}: {1}".format(
            label_order_number,
            order_number,
        )

        return text

    def _get_terminal_value(
        self,
        model,      # type: eTree
    ):
        # type: (...) -> str

        label_totem = sysactions.translate_message(
            model=model,
            message_key="TOTEM_TERMINAL",
        )

        return "{0}: {1}".format(
            label_totem,
            self.pos_id,
        )

    @staticmethod
    def _get_order_value(
        model,              # type: eTree
        current_order,      # type: eTree
    ):
        # type: (...) -> str

        label_value = sysactions.translate_message(
            model=model,
            message_key="VALUE",
        )

        return "{0:>6}: R${1:>8}".format(
            label_value,
            current_order.get("totalGross"),
        )

    @staticmethod
    def _get_footer(
        model,      # type: eTree
    ):
        # type: (...) -> str

        label_message = sysactions.translate_message(
            model=model,
            message_key="GO_TO_THE_CASHIER",
        )
        label_message = label_message.replace(
            "\\n",
            CTL_LF,
        )
        text = u"{}{}{}{}{}".format(
            TXT_BOLD_OFF,
            CTL_LF,
            CTL_LF,
            TXT_NORMAL,
            label_message,
        )

        return text

    @staticmethod
    def _rollback_printer_default_font(
    ):
        # type: (...) -> str

        return "{}{}{}{}".format(
            HW_INIT,
            TXT_NORMAL,
            TXT_BOLD_OFF,
            TXT_ALIGN_LT,
        )
