from typing import (
    Any,
    Dict,
    Optional,
)
from xml.etree import cElementTree as eTree

from nreports.builders import DataBuilder
from nreports_api.shared import JSON


class CustomerCallCouponBuilder(DataBuilder):

    def build_data(
        self,
        data_to_build: Dict[str, JSON],
        **kwargs: Any,
    ) -> Dict[str, JSON]:

        pos_id = int(kwargs["posId"])
        order_xml = kwargs["orderPicture"]

        call_id = self._get_customer_call_id(
            data_to_build=data_to_build,
            order_xml=order_xml,
        )

        customer_call_message = self.constants.get("CUSTOMER_CALL_MESSAGE")
        if not customer_call_message:
            labels = ["$CALL_PANEL", "$YOU_WILL_BE_CALLED"]
            translated_labels = self.i18n_repository.translate_labels(
                pos_id=pos_id,
                labels=labels,
            )
            customer_call_message = f"{translated_labels['$CALL_PANEL']} - {translated_labels['$YOU_WILL_BE_CALLED']}"

        data_to_build["CUSTOMER_CALL_MESSAGE"] = customer_call_message
        data_to_build["CUSTOMER_CALL_ID"] = call_id

        customer_call_before_danfe = self.constants.get("CUSTOMER_CALL_DANFE_POSITION", "before").lower() == "before"
        data_to_build["CUSTOMER_CALL_BEFORE_DANFE"] = customer_call_before_danfe
        data_to_build["CUSTOMER_CALL_AFTER_DANFE"] = not customer_call_before_danfe

        return data_to_build

    def _get_customer_call_id(
        self,
        data_to_build: Dict[str, JSON],
        order_xml: eTree.Element,
    ) -> Optional[str]:

        is_order_table = order_xml.find(".//OrderProperty[@key='TABLE_ID']") is not None
        customer_call_type = self.constants.get("CUSTOMER_CALL_TYPE", "HIDE").lower()
        call_priority = customer_call_type.split("|")
        call_id = None
        for call_type in call_priority:
            if call_type == "hide" or is_order_table:
                data_to_build["PRINT_CUSTOMER_CALL_COUPON"] = False
                break

            call_id = self._get_call_id(
                data_to_build=data_to_build,
                order_xml=order_xml,
                call_type=call_type,
            )
            if call_id is not None:
                data_to_build["PRINT_CUSTOMER_CALL_COUPON"] = True
                break

        return call_id

    def _get_call_id(
        self,
        data_to_build: Dict[str, JSON],
        order_xml: eTree.Element,
        call_type: str,
    ) -> Optional[str]:

        if call_type == "order_id":
            data_to_build["CUSTOMER_CALL_ID_BY_ORDER_ID"] = True
            return order_xml.get("orderId")[-3:]

        if call_type == "page_number":
            pager_number = self._get_value_from_custom_property(
                key="PAGER_NUMBER",
                order_xml=order_xml,
            )
            if pager_number:
                data_to_build["CUSTOMER_CALL_ID_BY_PAGE_NUMBER"] = True
                return pager_number

        if call_type == "customer_name":
            customer_name = self._get_value_from_custom_property(
                key="CUSTOMER_NAME",
                order_xml=order_xml,
            )
            if customer_name:
                data_to_build["CUSTOMER_CALL_ID_BY_CUSTOMER_NAME"] = True
                return customer_name

        return None

    @staticmethod
    def _get_value_from_custom_property(
        key: str,
        order_xml: eTree.Element,
    ) -> Optional[str]:

        custom_property = order_xml.find(f"CustomOrderProperties/OrderProperty[@key='{key}']")
        if custom_property is None:
            return None

        return custom_property.get("value", None)
