# coding: utf-8

from django.core import mail
from django.http import Http404
from django.utils.translation import gettext as _
from rest_framework import permissions, response

from procu.api import models
from procu.api.auth import auth_login
from procu.api.push.external import notify_reset
from procu.rest import generics
from procu.rest.metadata.mixins import CreateMetaMixin
from .permissions import RestorePermission
from .serializers import (
    GetRestoreTokenSerializer,
    RestoreParams,
    RestoreSerializer,
)


class GetRestoreEmail(CreateMetaMixin, generics.GenericAPIView):
    authentication_classes = ()
    serializer_class = GetRestoreTokenSerializer
    permission_classes = (permissions.AllowAny,)
    queryset = models.User.objects.filter(
        is_staff=False, is_deleted=False, is_cold=False
    )

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data

        messages = []

        try:
            user = generics.get_object_or_404(
                self.get_queryset(), username__iexact=data['email']
            )
            messages.extend(notify_reset(user))

        except Http404:
            pass

        with mail.get_connection(fail_silently=True) as conn:
            conn.send_messages(messages)

        return response.Response({'result': _('RESTORE::EMAIL_SENT')})

    def meta_post(self, components):
        meta = super().meta_post(components)

        try:
            meta['responses']['default'] = {'type': 'string'}
        except KeyError:
            pass

        return meta


class Restore(CreateMetaMixin, generics.GenericAPIView):
    authentication_classes = ()
    query_params_serializer_class = RestoreParams
    permission_classes = (RestorePermission,)
    serializer_class = RestoreSerializer
    queryset = models.User.objects.filter(
        is_staff=False, is_deleted=False, is_cold=False
    )

    def get_object(self):
        obj = generics.get_object_or_404(
            self.get_queryset(), id=self.query_params['user']
        )
        # May raise a permission denied
        self.check_object_permissions(self.request, obj)
        return obj

    def post(self, request):

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data

        user = self.object
        user.set_password(data['password'])
        user.save(update_fields=['password'])

        auth_login(request, user.username, data['password'])

        return response.Response({'result': _('RESTORE::PASSWORD_CHANGED')})

    def meta_post(self, components):
        meta = super().meta_post(components)

        try:
            meta['responses']['default'] = {'type': 'string'}
        except KeyError:
            pass

        return meta
