import graphene
from django.contrib.auth import logout
from django.utils.timezone import now
from graphene import relay
from core.logger import get_logger

from oauth.hep_client import HepClient, HepClientException
from oauth.models import OAuth2Token
from oauth.types import InvalidCouponFailure, RedeemCouponResult, RedeemCouponSuccess
from oauth.user_signup_login_handler import create_role_for_user
from users.models import License

logger = get_logger(__name__)


class Coupon(relay.ClientIDMutation):
    class Input:
        coupon_code = graphene.String()

    result = RedeemCouponResult()

    @classmethod
    def mutate_and_get_payload(cls, root, info, **kwargs):
        coupon_code = kwargs.get("coupon_code").strip()
        hep_client = HepClient()
        logger.info("redeeming coupon")

        try:
            hep_id = info.context.user.hep_id
        except AttributeError:
            raise Exception("not_authenticated")

        try:
            # todo: differenciate between invalid_coupon and other errors like "delivery_address_not_set"
            response = hep_client.redeem_coupon(
                coupon_code, hep_id, request=info.context
            )
        except HepClientException as e:
            logger.warning(e)
            raise Exception("unknown_error")

        if not response:
            return cls(result=InvalidCouponFailure)

        product = hep_client.entry_to_product(response["data"], now(), "coupon")

        if not product:
            logger.info("no myskillbox-product found")
            raise Exception("non_myskillbox_product")

        logger.info("creating license")
        license = License.objects.create_license_for_role(
            info.context.user,
            product["activated"],
            product["raw"],
            product["license"]["edition"],
            product["order_id"],
            product["isbn"],
        )

        logger.info("creating role for user")
        create_role_for_user(info.context.user, license.for_role.key)

        return cls(result=RedeemCouponSuccess)


class CouponMutations:
    redeem_coupon = Coupon.Field()


class Logout(graphene.Mutation):
    success = graphene.Boolean()

    def mutate(self, info):
        # log user out from myskillbox even if hep logout fails
        try:
            token = OAuth2Token.objects.get(user=info.context.user)
            hep_client = HepClient()
            try:
                hep_client.logout(request=info.context)
            except Exception as e:
                pass

            token.delete()

        except OAuth2Token.DoesNotExist:
            pass

        logout(info.context)
        return Logout(success=True)


class OauthMutations(object):
    logout = Logout.Field()
    coupon = Coupon.Field()
