from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from datetime import timedelta
from django.utils import timezone
from rest_framework.authtoken.models import Token
from .serializers import RegisterSerializer, LoginSerializer, LoginAttemptSerializer
from subscriptions.models import Profile
from .models import User, LoginAttempt


class RegisterView(APIView):
    def post(self, request):
        serializer = RegisterSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            token, _ = Token.objects.get_or_create(user=user)

            return Response({
                'token': token.key,
                'role': user.role,
                'username': user.username,
                'email': user.email,
                'first_name': user.first_name,
                'last_name': user.last_name,
                'user': {
                    'id': str(user.id),
                    'username': user.username,
                    'email': user.email,
                    'first_name': user.first_name,
                    'last_name': user.last_name,
                }
            }, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class LoginView(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')

        attempt, _ = LoginAttempt.objects.get_or_create(username=username)

        if attempt.is_blocked():
            wait_time = 0
            if attempt.blocked_until:
                delta = attempt.blocked_until - timezone.now()
                wait_time = max(0, int(delta.total_seconds() // 60))
            return Response(
                {"detail": f"Too many failed attempts. Try again in {wait_time} minutes."},
                status=status.HTTP_429_TOO_MANY_REQUESTS
            )

        serializer = LoginSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']

            # Check profile verification: only allow login if is_verified is True
            try:
                profile = Profile.objects.get(user=user)
                if hasattr(profile, "is_verified"):
                    if not profile.is_verified:
                        return Response(
                            {"detail": "Please contact dev team, your profile is not verified."},
                            status=status.HTTP_403_FORBIDDEN
                        )
                # If is_verified is True, allow login
            except Profile.DoesNotExist:
                # If no profile, do not allow login
                return Response(
                    {"detail": "Please contact dev team, your profile is not verified."},
                    status=status.HTTP_403_FORBIDDEN
                )

            attempt.attempts = 0
            attempt.blocked_until = None
            attempt.save()

            token, _ = Token.objects.get_or_create(user=user)
            profile_data = {
                "id": profile.id,
                "name": getattr(profile, "name", None),
                "profiles": {
                    "id": profile.id,
                    "name": getattr(profile, "name", None),
                    "secret_code": getattr(profile, "secret_code", None),
                }
            }

            return Response({
                'token': token.key,
                'role': user.role,
                'user': user.username,
                'id': user.id,
                'email': user.email,
                'first_name': user.first_name,
                'last_name': user.last_name,
                "profile": profile_data
            })

        attempt.attempts += 1
        if attempt.attempts >= 3:
            attempt.blocked_until = timezone.now() + timedelta(minutes=2)
            attempt.attempts = 0
        attempt.save()

        return Response({"detail": "Invalid username or password"}, status=status.HTTP_400_BAD_REQUEST)


class LogoutView(APIView):
    def post(self, request):
        request.user.auth_token.delete()
        return Response({'message': 'Logged out successfully.'}, status=status.HTTP_200_OK)


class UserView(APIView):
    def get(self, request):
        users = User.objects.all()
        userserializer = RegisterSerializer(users, many=True)
        return Response(userserializer.data)


class LoginAttemptView(APIView):
    def get(self, request):
        login_attempts = LoginAttempt.objects.all()
        attempts_serializer = LoginAttemptSerializer(login_attempts, many=True)
        return Response(attempts_serializer.data)


class UserSecretCodeView(APIView):
    def post(self, request):
        username = request.data.get('username')
        secret_code = request.data.get('secret_code')
        new_password = request.data.get('new_password')

        print(username, secret_code, new_password)

        if not all([username, secret_code, new_password]):
            return Response({"detail": "Username, secret code, and new password are required"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            profile = Profile.objects.get(
                user__username=username, secret_code=secret_code)
            user = profile.user
            user.set_password(new_password)
            user.save()
            return Response({"detail": "Password reset successfully"}, status=status.HTTP_200_OK)
        except Profile.DoesNotExist:
            return Response({"detail": "Invalid username or secret code"}, status=status.HTTP_400_BAD_REQUEST)


class VerifySecretCodeView(APIView):
    def post(self, request):
        username = request.data.get('username')
        secret_code = request.data.get('secret_code')

        if not all([username, secret_code]):
            return Response({"detail": "Username and secret code are required"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            profile = Profile.objects.get(
                user__username=username, secret_code=secret_code)
            return Response({"detail": "Secret code is valid"}, status=status.HTTP_200_OK)
        except Profile.DoesNotExist:
            return Response({"detail": "Invalid username or secret code"}, status=status.HTTP_400_BAD_REQUEST)
