from distutils.version import StrictVersion

from chatter_client.client.service import ChatterMessageService
from conio_sdk_generated.openapi.v2.serde.models.signup import Signup

from conio_sdk.logging.factory import LOGGING_FACTORY
from conio_sdk.services.conio.fiat_limits.fiat_limits_service import FiatLimitsService
from conio_sdk.services.conio.trading.trading_service import TradingService
from conio_sdk.services.conio.user.user_service import UserService, AuthenticationData


class SignupVOService:
    def __init__(
            self, user_service: UserService,
            fiat_limits_service: FiatLimitsService,
            trading_service: TradingService,
            push_notification_service: ChatterMessageService
    ):
        self._user_service = user_service
        self._fiat_limits_service = fiat_limits_service
        self._trading_service = trading_service
        self._push_notification_service = push_notification_service

    def signup(
            self, msg: Signup, app_version: StrictVersion,
            user_agent: str,
            device_language: str) -> AuthenticationData:
        email = msg.conio_credentials.user_id
        password = msg.conio_credentials.password
        from conio_domain.acceptancies import AcceptanceType
        from conio_domain.acceptancies import AcceptanceChoiceType
        from vault_client.client import exceptions as vault_exceptions
        acceptances = {
            getattr(AcceptanceType, x.acceptance_type.upper()):
                getattr(AcceptanceChoiceType, x.acceptance_choice.upper())
            for x in msg.acceptances
        }
        try:
            user = self._user_service.create_user(
                email,
                password,
                msg.device_id,
                app_version, user_agent,
                device_language,
                acceptances,
                self._trading_service.get_default_explicit_fees()
            )

        except vault_exceptions.DuplicateEntryException:
            LOGGING_FACTORY.security.warning('Signup failed for DuplicateEntry, MsgSignupCredentials: %s', msg)
            return

        LOGGING_FACTORY.security.info(
            'SIGNUP | Signup Done for user with email %s: (%s)', email, user.reference_key_id
        )

        LOGGING_FACTORY.security.info('Signup successful: {}'.format(user.reference_key_id))
        # TODO verify that this call is unnecessary
        # self._push_notification_service.fcm_create_or_update_channel(
        #     user_info_reference_id=user.reference_key_id
        # )
        self._fiat_limits_service.associate_payer_and_seller(user)
        self._push_notification_service.fcm_create_or_update_channel(
            user_info_reference_id=user.reference_key_id,
            cards_integration_id=user.cards_integration_id,
            seller_id=user.seller_id
        )
        return self._user_service.user_login(
            msg.conio_credentials.user_id,
            msg.conio_credentials.password,
            msg.device_id,
            user_language=device_language
        )


