# -*- coding: utf-8 -*-
from __future__ import annotations

from django.contrib.auth import logout as auth_logout
from django.contrib.auth.views import LoginView as BaseLoginView
from django.core.exceptions import PermissionDenied
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from django.urls import reverse
from django.utils.http import url_has_allowed_host_and_scheme
from django.views.generic import RedirectView

from hotpocket_backend.apps.core.conf import settings as django_settings
from hotpocket_backend.apps.ui.forms.accounts.auth import LoginForm


class LoginView(BaseLoginView):
    template_name = 'ui/accounts/login.html'
    form_class = LoginForm

    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        request.session['post_login_next_url'] = request.GET.get('next', None)
        request.session.save()

        return super().get(request, *args, **kwargs)

    def get_success_url(self) -> str:
        return reverse('ui.accounts.post_login')


class PostLoginView(RedirectView):
    def get_redirect_url(self, *args, **kwargs) -> str:
        next_url = self.request.session.pop('post_login_next_url', None)
        self.request.session.save()

        allowed_hosts = None
        if len(django_settings.ALLOWED_HOSTS) > 0:
            allowed_hosts = set(filter(
                lambda value: value != '*',
                django_settings.ALLOWED_HOSTS,
            ))

        if next_url is not None:
            next_url_is_safe = url_has_allowed_host_and_scheme(
                url=next_url,
                allowed_hosts=allowed_hosts,
                require_https=self.request.is_secure(),
            )

            if next_url_is_safe is False:
                next_url = None

        return next_url or reverse('ui.index.index')

    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        if request.user.is_anonymous is True:
            raise PermissionDenied('NOPE')

        return super().get(request, *args, **kwargs)


def logout(request: HttpRequest) -> HttpResponse:
    if request.user.is_authenticated is True:
        auth_logout(request)

    return render(request, 'ui/accounts/logout.html')
