import textwrap
from typing import final

from django import forms
from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse
from django.shortcuts import render
from typing_extensions import override

from vuln_demo.apps.vulnerabilities.levels.abc import LevelABC
from vuln_demo.apps.vulnerabilities.models import CompletedLevel
from vuln_demo.util.auth import cast_user
from vuln_demo.util.pw_entries import ADMIN_EMAIL, USER_EMAIL


class PasswordResetForm(forms.Form):
    """Form class passed to level 2 view."""

    email = forms.EmailField(widget=forms.HiddenInput())
    new_password = forms.CharField(label="New Password", widget=forms.PasswordInput(attrs={"autofocus": "autofocus"}))


@final
class Level2(LevelABC):
    """Scenario with sensitive data in hidden HTML form fields."""

    @override
    @classmethod
    def _get_hint(cls, request: WSGIRequest, hint_num: int) -> str:
        if hint_num == 1:
            return textwrap.dedent(
                """
                <p>
                    Each journey through the web is a path taken anew; the digital world forgets each step once it's
                    made. In a world without memory, every request must carry all of the information.
                </p>
                <p>
                    Look closely at what requests you're making, and what information they carry. Think of what
                    triggers this request, and how the data it contains make their way into that request. Can you
                    adjust this data to your benefit?
                </p>
            """
            )
        raise

    @override
    def get(self, request: WSGIRequest) -> HttpResponse:
        assert cast_user(request.user, cast=True)
        already_completed = CompletedLevel.check_completed(request.user, 2)

        form = PasswordResetForm()
        form.fields["email"].initial = USER_EMAIL
        return render(
            request,
            "vulnerabilities/levels/level2.html",
            {
                "form": form,
                "completed": already_completed,
            },
        )

    def post(self, request: WSGIRequest) -> HttpResponse:
        """Handle password form submission."""
        assert cast_user(request.user, cast=True)
        already_completed = CompletedLevel.check_completed(request.user, 2)

        form = PasswordResetForm(request.POST)
        if not form.is_valid():
            return render(
                request,
                "vulnerabilities/levels/level2.html",
                {"form": form, "completed": already_completed},
            )

        email = form.cleaned_data["email"]

        if email == USER_EMAIL:
            return render(
                request,
                "vulnerabilities/levels/level2.html",
                {
                    "form": form,
                    "completed": already_completed,
                    "note_msg": "Your CyberVault password was changed (but you still can't reach the admin account)",
                },
            )

        if email != ADMIN_EMAIL:
            return render(
                request,
                "vulnerabilities/levels/level2.html",
                {
                    "form": form,
                    "completed": already_completed,
                    "error_msg": "No such user (you're close though)",
                },
            )

        return self.completed_redirect(request, 2, skip_db=already_completed)
