import urllib.parse

from django.urls import reverse
from django.views.generic import DetailView, ListView, RedirectView, UpdateView
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages

# from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.conf import settings
from rest_framework import status

# from rest_framework import viewsets
from rest_framework.response import Response
from rest_auth.views import PasswordResetView
from allauth.account import views as allauth_views

from .models import User
from bm.users.utils import get_cache, set_cache, days_to_secs


@csrf_exempt
def redirect_password_rest_done(request, uidb64, token):
    """This function is to redirect the to  the
    client side for password resting.

    :param request: request object from the djagno.
    :param string uidb64: A string to which is encode of users's in base 64.
    :param string token: Tempural token generated by django allauth package.
    :return: redirecting to client-side using the django `redirect`.
    """

    return redirect(
        urllib.parse.urljoin(
            settings.CLIENT_REDIRECT_DOMAIN,
            "%s/%s/%s" % (settings.CLIENT_REDIRECT_URL, uidb64, token),
        )
    )


@csrf_exempt
def handling_mail_confirm(request, key):
    """
    1. May deprecate
    .. notes::
        Redirect directly done in adapter of user.
    """
    url = urllib.parse.urljoin(
        settings.CLIENT_REDIRECT_DOMAIN, "%s/%s" % ("confirm-email", key)
    )
    return redirect(url)


def handling_user():
    temp = "Forbiden access"
    return Response({"detail": temp}, status=status.HTTP_403_FORBIDDEN)


def display_home_page(request):
    """
    An index function to show the home.
    """
    msg = settings.BM_TO_USER_MESSAGE_WARNING
    messages.warning(request, msg)
    return render(request, "pages/home.html")


def redirect_after_email_confirm(request):
    """
    Allow for redirection in server side from email.
    Need Review:
    1. may be deprecated soon.
    """
    return render(request, "account/after_email_validation_confirm.html")


class LoginAfterPasswordChangeView(allauth_views.PasswordChangeView):
    template_name = "account/password_rest_done.html"

    @property
    def success_url(self):
        return reverse_lazy("change_password_done")


login_after_password_change = LoginAfterPasswordChangeView.as_view()


class UserDetailView(LoginRequiredMixin, DetailView):
    """
    .. deprecated::
       This class may deprecated after review as it not useful in production
    """
    model = User
    # These next two lines tell the view to index lookups by username
    slug_field = "username"
    slug_url_kwarg = "username"

    def get_redirect_url(self):
        return handling_user


class UserRedirectView(LoginRequiredMixin, RedirectView):
    """
    .. deprecated::
       This class may deprecated after review as it not useful in production
    """
    permanent = False

    def get_redirect_url(self):
        return reverse("users:detail", kwargs={"username": self.request.user.username})

    def get_object(self):
        return None


class UserUpdateView(LoginRequiredMixin, UpdateView):

    fields = ["name"]

    # we already imported User in the view code above, remember?
    model = User

    # send the user back to their own page after a successful update
    def get_success_url(self):
        return reverse("users:detail", kwargs={"username": self.request.user.username})

    def get_object(self):
        # Only get the User record for the user making the request
        # return User.objects.get(username=self.request.user.username)
        return None


class UserListView(LoginRequiredMixin, ListView):
    """
    .. deprecated::
       This class may deprecated after review as it not useful in production
    """
    model = User
    # These next two lines tell the view to index lookups by username
    slug_field = "username"
    slug_url_kwarg = "username"

    def get_object(self):
        return None


class BMPasswordResetView(PasswordResetView):

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

        cache_name = "confirm_mail_send_for_%s" % (request.data["email"])

        if get_cache(cache_name):
            return Response(
                {
                    "detail": (
                        "please wait till the",
                        " mail reach you Or check",
                        " your mail inbox.",
                    )
                }
            )
        timeout = settings.ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS

        if timeout > 1:
            timeout = timeout - 1

        timeout = days_to_secs(timeout)

        set_cache(cache_name, True, timeout)

        return super(BMPasswordResetView, self).post(request, *args, **kwargs)


def password_reset_done(request):
    """
    Display nessary html after reset is done.
    .. deprecated::  0.1.0
    """
    return Response({"password has been changes"}, status=204)


def change_password(request, uidb64, token):
    """
    Display nessary html after reset is done.
    .. deprecated:: 0.1.0
    """
    return render(request, "account/password_rest_confirm_form.html")


def change_password_done(requests):
    """
    Display nessary html after reset is done.
    .. deprecated:: 0.1.0
    """
    return render(requests, "account/password_rest_done.html")

import urllib.parse

from django.urls import reverse
from django.views.generic import DetailView, ListView, RedirectView, UpdateView
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages

# from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.conf import settings
from rest_framework import status

# from rest_framework import viewsets
from rest_framework.response import Response
from rest_auth.views import PasswordResetView
from allauth.account import views as allauth_views

from .models import User
from bm.users.utils import get_cache, set_cache, days_to_secs


@csrf_exempt
def redirect_password_rest_done(request, uidb64, token):
    """This function is to redirect the to  the
    client side for password resting.

    :param request: request object from the djagno.
    :param string uidb64: A string to which is encode of users's in base 64.
    :param string token: Tempural token generated by django allauth package.
    :return: redirecting to client-side using the django `redirect`.
    """

    return redirect(
        urllib.parse.urljoin(
            settings.CLIENT_REDIRECT_DOMAIN,
            "%s/%s/%s" % (settings.CLIENT_REDIRECT_URL, uidb64, token),
        )
    )


@csrf_exempt
def handling_mail_confirm(request, key):
    """
    1. May deprecate
    .. notes::
        Redirect directly done in adapter of user.
    """
    url = urllib.parse.urljoin(
        settings.CLIENT_REDIRECT_DOMAIN, "%s/%s" % ("confirm-email", key)
    )
    return redirect(url)


def handling_user():
    temp = "Forbiden access"
    return Response({"detail": temp}, status=status.HTTP_403_FORBIDDEN)


def display_home_page(request):
    """
    An index function to show the home.
    """
    msg = settings.BM_TO_USER_MESSAGE_WARNING
    messages.warning(request, msg)
    return render(request, "pages/home.html")


def redirect_after_email_confirm(request):
    """
    Allow for redirection in server side from email.
    Need Review:
    1. may be deprecated soon.
    """
    return render(request, "account/after_email_validation_confirm.html")


class LoginAfterPasswordChangeView(allauth_views.PasswordChangeView):
    template_name = "account/password_rest_done.html"

    @property
    def success_url(self):
        return reverse_lazy("change_password_done")


login_after_password_change = LoginAfterPasswordChangeView.as_view()


class UserDetailView(LoginRequiredMixin, DetailView):
    """
    .. deprecated::
       This class may deprecated after review as it not useful in production
    """
    model = User
    # These next two lines tell the view to index lookups by username
    slug_field = "username"
    slug_url_kwarg = "username"

    def get_redirect_url(self):
        return handling_user


class UserRedirectView(LoginRequiredMixin, RedirectView):
    """
    .. deprecated::
       This class may deprecated after review as it not useful in production
    """
    permanent = False

    def get_redirect_url(self):
        return reverse("users:detail", kwargs={"username": self.request.user.username})

    def get_object(self):
        return None


class UserUpdateView(LoginRequiredMixin, UpdateView):

    fields = ["name"]

    # we already imported User in the view code above, remember?
    model = User

    # send the user back to their own page after a successful update
    def get_success_url(self):
        return reverse("users:detail", kwargs={"username": self.request.user.username})

    def get_object(self):
        # Only get the User record for the user making the request
        # return User.objects.get(username=self.request.user.username)
        return None


class UserListView(LoginRequiredMixin, ListView):
    """
    .. deprecated::
       This class may deprecated after review as it not useful in production
    """
    model = User
    # These next two lines tell the view to index lookups by username
    slug_field = "username"
    slug_url_kwarg = "username"

    def get_object(self):
        return None


class BMPasswordResetView(PasswordResetView):

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

        cache_name = "confirm_mail_send_for_%s" % (request.data["email"])

        if get_cache(cache_name):
            return Response(
                {
                    "detail": (
                        "please wait till the",
                        " mail reach you Or check",
                        " your mail inbox.",
                    )
                }
            )
        timeout = settings.ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS

        if timeout > 1:
            timeout = timeout - 1

        timeout = days_to_secs(timeout)

        set_cache(cache_name, True, timeout)

        return super(BMPasswordResetView, self).post(request, *args, **kwargs)


def password_reset_done(request):
    """
    Display nessary html after reset is done.
    .. deprecated::  0.1.0
    """
    return Response({"password has been changes"}, status=204)


def change_password(request, uidb64, token):
    """
    Display nessary html after reset is done.
    .. deprecated:: 0.1.0
    """
    return render(request, "account/password_rest_confirm_form.html")


def change_password_done(requests):
    """
    Display nessary html after reset is done.
    .. deprecated:: 0.1.0
    """
    return render(requests, "account/password_rest_done.html")

# from django.http import HttpResponse # from rest_framework import viewsets This function is to redirect the to  the     client side for password resting.      :param request: request object from the djagno.     :param string uidb64: A string to which is encode of users's in base 64.     :param string token: Tempural token generated by django allauth package.     :return: redirecting to client-side using the django `redirect`. 1. May deprecate     .. notes::         Redirect directly done in adapter of user. An index function to show the home. Allow for redirection in server side from email.     Need Review:     1. may be deprecated soon. .. deprecated::        This class may deprecated after review as it not useful in production # These next two lines tell the view to index lookups by username .. deprecated::        This class may deprecated after review as it not useful in production # we already imported User in the view code above, remember? # send the user back to their own page after a successful update # Only get the User record for the user making the request # return User.objects.get(username=self.request.user.username) .. deprecated::        This class may deprecated after review as it not useful in production # These next two lines tell the view to index lookups by username Display nessary html after reset is done.     .. deprecated::  0.1.0 Display nessary html after reset is done.     .. deprecated:: 0.1.0 Display nessary html after reset is done.     .. deprecated:: 0.1.0