from bittrade_client.client.client import BittradeClient
from vault_client.client.client_definition import VaultClient
from vault_client.client.conio_user import ConioUser

from conio_sdk.common import exceptions
from conio_sdk.logging.factory import LOGGING_FACTORY
from conio_sdk.services.conio import UserLevel
from conio_sdk.services.conio.explicit_fees.explicit_fees_service import ExplicitFeesService


class BittradeVaultExplicitFeesService(ExplicitFeesService):
    def __init__(self, bittrade_client: BittradeClient, vault_client: VaultClient):
        self._bittrade_client = bittrade_client
        self._vault_client = vault_client

    def associate_explicit_fees(self, user: ConioUser, user_level: UserLevel) -> None:
        explicit_fees_ids = sorted(
            list(
                map(
                    lambda d: d.explicit_fees_id,
                    filter(
                        lambda d2: d2.description == user_level,
                        self._bittrade_client.get_explicit_fees()
                    )
                )
            )
        )

        if not explicit_fees_ids:
            LOGGING_FACTORY.onboarding.error('Could not find explicit fees for user level %s', user_level)
            raise exceptions.CouldNotFindExplicitFeesExceptionForUserLevel

        # We expect no more than 2 explicit fees, one for each currency (EUR, USD).
        # TODO revise multiple currencies thoroughly
        if len(explicit_fees_ids) > 2:
            raise ValueError(str(explicit_fees_ids))
        current_explicit_fees_ids = sorted(list(user.explicit_fees_ids)) \
            if user.explicit_fees_ids else None
        if explicit_fees_ids == current_explicit_fees_ids:
            return

        LOGGING_FACTORY.onboarding.info(
            'Updating user %s with explicit fees %s, old explicit fees: %s',
            user.reference_key_id, explicit_fees_ids, current_explicit_fees_ids
        )
        self._vault_client.save_user_info_v2(
            {
                'explicit_fees_ids': explicit_fees_ids
            },
            user.reference_key_id)
