from typing import (
    Any,
    Union,
    Optional,
)

from modelcommon.model import SitefResponse
from model import (
    CancelPaymentOrderData,
    ConfirmFinishPaymentData,
    TestConnectionData,
    StartPaymentData,
    FinishPaymentData,
)
from paymentprocessor import PaymentProcessor
from ._SitefPaymentProcessor import SitefPaymentProcessor


class SitefGiftCardPaymentProcessor(PaymentProcessor):

    def __init__(
        self,               # type: SitefGiftCardPaymentProcessor
        message_bus,        # type: MbContextMessageBus
        dialog_manager,     # type: DialogManager
        config,             # type: Group
        logger,             # type: Logger
        cache,              # type: Cache
    ):
        # type: (...) -> None

        super(SitefGiftCardPaymentProcessor, self).__init__(message_bus, dialog_manager, config, logger, cache)

        self.sitef_processor = SitefPaymentProcessor(
            message_bus=message_bus,
            dialog_manager=dialog_manager,
            config=config,
            logger=logger,
            cache=cache,
        )

        self.allowed_payments = config.find_values("AllowedPayments") or []
        self.enabled_additional_transactions = config.find_values("EnabledAdditionalTransactions") or []

        key_cancel_additional_transactions = "CancelEnabledAdditionalTransactions"
        self.cancel_enabled_additional_transactions = config.find_values(key_cancel_additional_transactions) or []

        default_disabled_payments = ["10", "17", "18", "19", "27", "28", "29", "34", "35", "36", "42", "3988"]
        self.disabled_payments = config.find_values("DisabledPayments") or default_disabled_payments

        self.additional_data = self._get_additional_data()
        self.cancel_additional_data = self._get_cancel_additional_data()

    def connection_status(
        self,                   # type: SitefGiftCardPaymentProcessor
        test_connection_data,   # type: TestConnectionData
    ):
        # type: (...) -> bool

        return self.sitef_processor.connection_status(test_connection_data=test_connection_data)

    def add_payment(
        self,                   # type: SitefGiftCardPaymentProcessor
        start_payment_data,     # type: StartPaymentData
    ):
        # type: (...) -> Any[Union[SitefResponse, str]]

        return self.sitef_processor.add_payment(
            start_payment_data=start_payment_data,
            additional_params=self.additional_data,
        )

    def cancel_payment_order(
        self,                           # type: SitefGiftCardPaymentProcessor
        cancel_payment_order_data,      # type: CancelPaymentOrderData
        additional_params="",           # type: Optional[str]
    ):
        # type: (...) -> Any[Union[SitefResponse, str]]

        return self.sitef_processor.cancel_payment_order(
            cancel_payment_order_data=cancel_payment_order_data,
            additional_params=self.cancel_additional_data,
        )

    def cancel_payment(
        self,  # type: SitefGiftCardPaymentProcessor
    ):
        # type: (...) -> str

        return self.sitef_processor.cancel_payment()

    def finish_payment(
        self,                   # type: SitefGiftCardPaymentProcessor
        finish_payment_data,    # type: FinishPaymentData
    ):
        # type: (...) -> bool

        return self.sitef_processor.finish_payment(finish_payment_data=finish_payment_data)

    def confirm_finish_payment(
        self,                           # type: SitefGiftCardPaymentProcessor
        confirm_finish_payment_data,    # type: ConfirmFinishPaymentData
    ):
        # type: (...) -> None

        pass

    def get_name(
        self,   # type: SitefGiftCardPaymentProcessor
    ):
        # type: (...) -> str

        return self.sitef_processor.get_name()

    def get_document(
        self,       # type: SitefGiftCardPaymentProcessor
        pos_id,     # type: str
    ):
        # type: (...) -> str

        return self.sitef_processor.get_document(pos_id=pos_id)

    def stop(
        self,   # type: SitefGiftCardPaymentProcessor
    ):
        # type: (...) -> None

        self.sitef_processor.stop()

    def get_last_receipt(
        self,           # type: SitefGiftCardPaymentProcessor
        eft_processor,  # type: str
    ):
        # type: (...) -> Optional[str]

        return self.sitef_processor.get_last_receipt(eft_processor=eft_processor)

    def _get_additional_data(
        self,   # type: SitefGiftCardPaymentProcessor
    ):
        # type: (...) -> str

        additional_data_list = []

        if self.disabled_payments:
            additional_data_list.append("[{}]".format(';'.join(self.disabled_payments)))

        if self.allowed_payments:
            additional_data_list.append("{{TransacoesHabilitadas={}}}".format(';'.join(self.allowed_payments)))

        if self.enabled_additional_transactions:
            additional_transactions = ';'.join(self.enabled_additional_transactions)
            additional_data_list.append("{{TransacoesAdicionaisHabilitadas={}}}".format(additional_transactions))

        return ';'.join(additional_data_list)

    def _get_cancel_additional_data(
        self,   # type: SitefGiftCardPaymentProcessor
    ):
        # type: (...) -> str

        cancel_additional_data_list = []

        if self.cancel_enabled_additional_transactions:
            additional_transactions = ';'.join(self.cancel_enabled_additional_transactions)
            cancel_additional_data_list.append("{{TransacoesAdicionaisHabilitadas={}}}".format(additional_transactions))

        return ';'.join(cancel_additional_data_list)
