from typing import (
    Any,
    Dict,
    List,
)

from model import FiscalType
from .._DataBuilder import DataBuilder
from .._Util import build_util_variables
from nreports.utils import get_fiscal_type
from nreports_api.shared import JSON
from .customer_call_coupon import CustomerCallCouponBuilder
from nreports.builders.fiscal_coupon import (
    FiscalCouponNfceBuilder,
    FiscalCouponSatBuilder,
)
from .fiscal_coupon_mobile import (
    BaseFiscalCouponMobileNfce,
    BaseFiscalCouponMobileSat,
)
from .loyalty_coupon import (
    LoyaltyCouponNfceBuilder,
    LoyaltyCouponSatBuilder,
)


class EndOfSaleBuilder(DataBuilder):

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

        pos_id = int(kwargs["posId"])
        order_id = int(kwargs["orderId"])
        is_mobile = str(kwargs.get("isMobile", "false")).lower() == "true"
        fiscal_coupon = str(kwargs.get("fiscalCoupon", "true")).lower() == "true"

        order_service = self.order_api_repository.get_order_service(pos_id=pos_id)
        kwargs["orderPicture"] = order_xml = order_service.get_order_picture(order_id=order_id)
        kwargs["fiscalXml"] = fiscal_xml = self.order_api_repository.get_fiscal_xml(
            pos_id=pos_id,
            order_id=order_id,
            order_xml=order_xml,
        )
        data_to_build = build_util_variables(
            constants=self.constants,
            data_to_build=data_to_build,
            **kwargs,
        )
        fiscal_type = get_fiscal_type(fiscal_xml=fiscal_xml)
        data_to_build["IS_NFCE"] = fiscal_type == FiscalType.NFCE
        data_to_build["IS_SAT"] = fiscal_type == FiscalType.SAT
        data_to_build["ORDER_ID"] = kwargs["orderId"]
        data_to_build["PRINT_FISCAL_COUPON"] = fiscal_coupon

        builders = self._get_builders(
            fiscal_type=fiscal_type,
            is_mobile=is_mobile,
            fiscal_coupon=fiscal_coupon,
        )

        for builder in builders:
            data_to_build = builder(*self.get_builder_init()).build_data(
                data_to_build=data_to_build,
                **kwargs,
            )

        print_customer = data_to_build["PRINT_CUSTOMER_CALL_COUPON"]
        print_loyalty = data_to_build["PRINT_LOYALTY_COUPON"]
        data_to_build["PRINT_FISCAL_OR_LOYALTY"] = fiscal_coupon or print_loyalty
        data_to_build["PRINT_FISCAL_OR_CUSTOMER"] = fiscal_coupon or print_customer
        data_to_build["PRINT_LOYALTY_OR_CUSTOMER"] = print_loyalty or print_customer

        return data_to_build

    @staticmethod
    def _get_builders(
        fiscal_type: str,
        is_mobile: bool,
        fiscal_coupon: bool,
    ) -> List[JSON]:
        is_nfce = fiscal_type == FiscalType.NFCE
        loyalty_builder = LoyaltyCouponNfceBuilder if is_nfce else LoyaltyCouponSatBuilder
        builders = [CustomerCallCouponBuilder, loyalty_builder]

        if fiscal_coupon:
            fiscal_coupon_builder = FiscalCouponNfceBuilder if is_nfce else FiscalCouponSatBuilder
            if is_mobile:
                fiscal_coupon_builder = BaseFiscalCouponMobileNfce if is_nfce else BaseFiscalCouponMobileSat

            builders.append(fiscal_coupon_builder)

        return builders
