# Create your views here.

import requests
import structlog
from django.conf import settings
from django.contrib.auth import authenticate, login
from django.core.management import call_command
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.template import loader
from django.views.decorators.csrf import ensure_csrf_cookie
from ratelimit.decorators import ratelimit
from rest_framework import authentication
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response

from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
from vbv_lernwelt.core.serializers import UserSerializer

logger = structlog.get_logger(__name__)


@django_view_authentication_exempt
@ensure_csrf_cookie
def vue_home(request):
    if settings.IT_SERVE_VUE:
        try:
            res = requests.get(f'{settings.IT_SERVE_VUE_URL}{request.get_full_path()}')
            content = res.text
            content = content.replace('https://vbv-lernwelt.control.iterativ.ch/static/', '/static/')
            headers = res.headers
            content_type = headers.get('content-type', 'text/html')
            return HttpResponse(content, content_type=content_type)
        except Exception as e:
            return HttpResponse(
                f'Can not connect to vue dev server at {settings.IT_SERVE_VUE_URL}: {e}'
            )

    # render index.html from `npm run build`
    content = loader.render_to_string('vue/index.html', context={}, request=request)
    content = content.replace('https://vbv-lernwelt.control.iterativ.ch/static/', '/static/')
    return HttpResponse(content)


@api_view(['POST'])
@ensure_csrf_cookie
def vue_login(request):
    try:
        username = request.data.get('username')
        password = request.data.get('password')
        if username and password:
            user = authenticate(request, username=username, password=password)
            if user:
                login(request, user)
                logger.debug('login successful', username=username, email=user.email, label='login')
                return Response(UserSerializer(user).data)
    except Exception as e:
        logger.exception(e)

    logger.debug('login failed', username=username, label='login')
    return Response({'success': False}, status=401)


@api_view(['GET'])
def me_user_view(request):
    if request.user.is_authenticated:
        return Response(UserSerializer(request.user).data)
    return Response(status=403)


def permission_denied_view(request, exception):
    return render(request, "403.html", status=403)


def rate_limit_exceeded_view(request, exception):
    return render(request, "429.html", status=429)


@django_view_authentication_exempt
def server_json_error(request, *args, **kwargs):
    """
    Generic 500 error handler.
    """
    data = {
        "detail": "Server Error (500)",
        "status_code": 500,
    }
    return JsonResponse(data, status=500)


@ratelimit(key="ip", rate="5/m", block=True)
@django_view_authentication_exempt
def check_rate_limit(request):
    return HttpResponse(content=b"Hello")


@api_view(['POST'])
@authentication_classes((authentication.SessionAuthentication,))
@permission_classes((IsAdminUser,))
def cypress_reset_view(request):
    if settings.APP_ENVIRONMENT != 'production':
        call_command('cypress_reset')

    return HttpResponseRedirect('/admin/')
