from django.contrib.auth.models import User
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.conf import settings
from django.utils.http import urlencode

from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status

from ..models import Member
from ..serializers import MemberDetailSerializer, InviteSerializer
from .permissions import get_permission


class CanInvitePermission(permissions.BasePermission):

    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False

        if request.method != "POST":
            return False

        return request.user.has_perm(get_permission(Member, "invite"))


class InviteUserView(APIView):

    permission_classes = [CanInvitePermission]
    serializer_class = InviteSerializer

    def post(self, request, *args, **kwargs):

        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        email = serializer.validated_data["user_email"]

        if Member.objects.filter(email=email).count() > 0:
            return Response(
                {"error": "User already exists"}, status=status.HTTP_400_BAD_REQUEST
            )

        email_split = email.split("@")
        if len(email_split) != 2:
            return Response(
                {"error": "User email not in expected format"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        user = User.objects.create_user(
            username=email_split[0],
            first_name=serializer.validated_data["user_first_name"],
            last_name=serializer.validated_data["user_last_name"],
            email=email,
        )

        if settings.EMAIL_HOST_USER:
            self.send_email(
                request, user, email, action_url=serializer.validated_data["action_url"]
            )

        # Send Email
        member = Member.objects.get(id=user.id)
        data = MemberDetailSerializer(member, context={"request": request}).data
        return Response(
            data,
            status=status.HTTP_201_CREATED,
            headers={"Location": str(data["url"])},
        )

    def send_email(self, request, user, email, action_url):

        login_url = "oidc/authenticate" if settings.WITH_OIDC else "accounts/login"
        base_url = request.scheme + "://" + request.get_host() + "/" + login_url
        if action_url:
            full_url = base_url + "/?" + urlencode({"next": action_url})
        else:
            full_url = base_url

        context = {
            "action_url": full_url,
        }

        # Email applicant and facility
        emails_dir = "ichec_django_core/emails"

        template = emails_dir + "/invite_user"
        text = render_to_string(template + ".txt", context=context)
        html = render_to_string(template + ".html", context=context)

        msg = EmailMultiAlternatives(
            subject="User Management Portal Invitation",
            body=text,
            from_email=settings.DEFAULT_EMAIL_SENDER,
            to=[email],
            headers={"List-Unsubscribe": f"<mailto:{settings.DEFAULT_EMAIL_UNSUB}"},
        )

        msg.attach_alternative(html, "text/html")
        msg.send()
