# Create your views here.
import glob
from pathlib import Path

import requests
import structlog
from django.conf import settings
from django.contrib.auth import authenticate, login, logout
from django.core.management import call_command
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
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, *args):
    if settings.IT_SERVE_VUE:
        try:
            res = requests.get(f"{settings.IT_SERVE_VUE_URL}{request.get_full_path()}")
            content = res.text
            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)
    return HttpResponse(content)


@api_view(["POST"])
@ensure_csrf_cookie
def vue_login(request):
    if settings.ALLOW_LOCAL_LOGIN:
        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)
    else:
        return Response(
            {"success": False, "message": "ALLOW_LOCAL_LOGIN=false"}, status=403
        )


@api_view(["GET", "PUT"])
def me_user_view(request):
    if not request.user.is_authenticated:
        return Response(status=403)

    if request.method == "GET":
        return Response(UserSerializer(request.user).data)

    if request.method == "PUT":
        serializer = UserSerializer(
            request.user,
            data={"language": request.data.get("language", "de")},
            partial=True,
        )
        if serializer.is_valid():
            serializer.save()
            return Response(UserSerializer(request.user).data)

    return Response(status=400)


@api_view(["POST"])
def vue_logout(request):
    logout(request)
    return Response({"success": True}, 200)


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("/server/admin/")


@django_view_authentication_exempt
def generate_web_component_icons(request):
    svg_files = []
    for filepath in glob.iglob(f"{settings.APPS_DIR}/static/icons/*.svg"):
        with open(filepath, "r") as f:
            filename = Path(filepath).stem
            elementname = "it-" + filename
            svg_files.append(
                {
                    "filepath": filepath,
                    "content": f.read(),
                    "filename": filename,
                    "elementname": elementname,
                    "classname": filename.replace("-", "_"),
                }
            )
    return render(
        request,
        "core/icons.html",
        context={"svg_files": svg_files},
        content_type="application/javascript",
    )
