from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.core.mail import send_mail
from django.conf import settings
from accounts.api.serializers import (
    CustomUserCreateSerializer, 
    CustomUserSerializer,
    EmailVerificationSerializer,
    ForgotPasswordSerializer,
    ResetPasswordSerializer,
    UserProfileSerializer
)
from accounts.models import EmailVerification, PasswordReset, UserProfile


class RegisterView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = CustomUserCreateSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            
            # Get the email verification token
            email_verification = EmailVerification.objects.get(user=user)
            
            # Send verification email
            subject = "Verify your email address"
            message = f"""
Hi {user.username},

Thank you for registering with Stafflyn!

To verify your email address, use this token:
{email_verification.token}

Then send a POST request to:
http://localhost:8000/api/auth/verify-email/

With this JSON body:
{{
    "token": "{email_verification.token}"
}}

This token will expire in 24 hours.

Best regards,
Stafflyn Team
            """
            
            try:
                send_mail(
                    subject,
                    message,
                    settings.DEFAULT_FROM_EMAIL,  # noreply@stafflyn.com - no-reply emails
                    [user.email],
                    fail_silently=False,
                )
                return Response(
                    {
                        'message': 'Registration successful. Please check your email to verify your account.',
                        'email': user.email,
                        'verification_token': email_verification.token  # For testing purposes
                    },
                    status=status.HTTP_201_CREATED
                )
            except Exception as e:
                # If email fails, delete the user and return error
                user.delete()
                return Response(
                    {'error': f'Failed to send verification email: {str(e)}'},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR
                )
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class VerifyEmailView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = EmailVerificationSerializer(data=request.data)
        if serializer.is_valid():
            token = serializer.validated_data['token']
            
            try:
                email_verification = EmailVerification.objects.get(token=token)
                
                # Mark email as verified
                email_verification.is_verified = True
                email_verification.save()
                
                # Activate user
                user = email_verification.user
                user.is_active = True
                user.save()
                
                # Create token for the user
                token_obj, created = Token.objects.get_or_create(user=user)
                
                return Response(
                    {
                        'message': 'Email verified successfully. You can now login.',
                        'user': CustomUserSerializer(user).data,
                        'token': token_obj.key
                    },
                    status=status.HTTP_200_OK
                )
            except EmailVerification.DoesNotExist:
                return Response(
                    {'error': 'Invalid verification token.'},
                    status=status.HTTP_400_BAD_REQUEST
                )
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class LoginView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        email = request.data.get('email')
        password = request.data.get('password')

        if not email or not password:
            return Response(
                {'error': 'Email and password are required'},
                status=status.HTTP_400_BAD_REQUEST
            )

        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return Response(
                {'error': 'Invalid email or password'},
                status=status.HTTP_401_UNAUTHORIZED
            )

        # Check if email is verified
        try:
            if not user.email_verification.is_verified:
                return Response(
                    {'error': 'Please verify your email before logging in.'},
                    status=status.HTTP_403_FORBIDDEN
                )
        except:
            return Response(
                {'error': 'Email verification record not found.'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

        user = authenticate(username=user.username, password=password)
        if user is not None:
            token, created = Token.objects.get_or_create(user=user)
            return Response(
                {
                    'user': CustomUserSerializer(user).data,
                    'token': token.key,
                    'message': 'Login successful'
                },
                status=status.HTTP_200_OK
            )
        return Response(
            {'error': 'Invalid email or password'},
            status=status.HTTP_401_UNAUTHORIZED
        )


class LogoutView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        request.user.auth_token.delete()
        return Response(
            {'message': 'Logout successful'},
            status=status.HTTP_200_OK
        )


class UpdateProfileView(APIView):
    permission_classes = [IsAuthenticated]

    def put(self, request):
        # Get or create profile for the logged-in user
        profile, created = UserProfile.objects.get_or_create(user=request.user)
        
        serializer = UserProfileSerializer(profile, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(
                {
                    'message': 'Profile updated successfully',
                    'profile': serializer.data
                },
                status=status.HTTP_200_OK
            )
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def get(self, request):
        # Get or create profile for the logged-in user
        profile, created = UserProfile.objects.get_or_create(user=request.user)
        
        serializer = UserProfileSerializer(profile)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ForgotPasswordView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = ForgotPasswordSerializer(data=request.data)
        if serializer.is_valid():
            email = serializer.validated_data['email']
            user = User.objects.get(email=email)
            
            # Delete existing password reset tokens
            PasswordReset.objects.filter(user=user).delete()
            
            # Create new password reset token
            password_reset = PasswordReset.objects.create(user=user)
            
            # Send password reset email
            subject = "Reset your password"
            message = f"""
Hi {user.username},

You requested to reset your password. Use this token to reset your password:
{password_reset.token}

Send a POST request to:
http://localhost:8000/api/auth/reset-password/

With this JSON body:
{{
    "token": "{password_reset.token}",
    "new_password": "your-new-password",
    "confirm_password": "your-new-password"
}}

This token will expire in 1 hour.

If you didn't request this, please ignore this email.

Best regards,
Stafflyn Team
            """
            
            try:
                send_mail(
                    subject,
                    message,
                    settings.DEFAULT_FROM_EMAIL,  # noreply@stafflyn.com - no-reply emails
                    [user.email],
                    fail_silently=False,
                )
                return Response(
                    {
                        'message': 'Password reset email sent. Please check your email.',
                        'email': user.email
                    },
                    status=status.HTTP_200_OK
                )
            except Exception as e:
                return Response(
                    {'error': f'Failed to send password reset email: {str(e)}'},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR
                )
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ResetPasswordView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = ResetPasswordSerializer(data=request.data)
        if serializer.is_valid():
            token = serializer.validated_data['token']
            new_password = serializer.validated_data['new_password']
            
            try:
                password_reset = PasswordReset.objects.get(token=token)
                
                # Update user password
                user = password_reset.user
                user.set_password(new_password)
                user.save()
                
                # Mark token as used
                password_reset.is_used = True
                password_reset.save()
                
                return Response(
                    {
                        'message': 'Password reset successfully. You can now login with your new password.',
                        'email': user.email
                    },
                    status=status.HTTP_200_OK
                )
            except PasswordReset.DoesNotExist:
                return Response(
                    {'error': 'Invalid password reset token.'},
                    status=status.HTTP_400_BAD_REQUEST
                )
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
