from rest_framework import status
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from django.contrib.auth import login, logout
from users.models import User
from .serializers import UserSerializer, UserRegistrationSerializer, UserLoginSerializer
from follows.models import FollowUser
from users.utils import generate_verification_code
from users.emails import send_verification_email, send_password_reset_email, send_account_update_email, send_password_change_notice_email, send_email_change_verification, send_email_changed_notifications
from users.models import VerificationCode
from django.utils import timezone
from datetime import timedelta
import random
from django.conf import settings



@api_view(['POST'])
@permission_classes([AllowAny])
@authentication_classes([])
def register(request):
    serializer = UserRegistrationSerializer(data=request.data)
    if serializer.is_valid():
        user = serializer.save(is_verified=False)

        # Generate and send verification code (inactive by default in a real scenario, but keeping active for now per existing flow)
        # Assuming we want to keep the user active initially for simplicity unless specified otherwise.
        # But per request "A mail in the account creation with a verfication code", usually implies email verification flow.
        # For now, we'll just send the code.

        code = generate_verification_code()
        VerificationCode.objects.create(
            user=user,
            code=code,
            type='register',
            expires_at=timezone.now() + timedelta(hours=24)
        )
        send_verification_email(user, code)

        token, created = Token.objects.get_or_create(user=user)
        response = Response({
            'user': UserSerializer(user, context={'request': request}).data,
            'token': token.key
        }, status=status.HTTP_201_CREATED)
        response.set_cookie(
            'auth_token',
            token.key,
            httponly=True,
            samesite='Lax',
            secure=settings.AUTH_COOKIE_SECURE
        )
        return response
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['POST'])
@permission_classes([AllowAny])
@authentication_classes([])
def login_view(request):
    serializer = UserLoginSerializer(data=request.data)
    if serializer.is_valid():
        user = serializer.validated_data['user']
        login(request, user)
        token, created = Token.objects.get_or_create(user=user)
        response = Response({
            'user': UserSerializer(user, context={'request': request}).data,
            'token': token.key
        }, status=status.HTTP_200_OK)
        response.set_cookie(
            'auth_token',
            token.key,
            httponly=True,
            samesite='Lax',
            secure=settings.AUTH_COOKIE_SECURE
        )
        return response
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def logout_view(request):
    try:
        request.user.auth_token.delete()
    except:
        pass
    logout(request)
    response = Response(status=status.HTTP_200_OK)
    response.delete_cookie('auth_token')
    return response


@api_view(['GET', 'PUT'])
@permission_classes([IsAuthenticated])
def profile(request):
    if request.method == 'GET':
        serializer = UserSerializer(request.user, context={'request': request})
        data = serializer.data

        # Add counts
        from posts.models import Post
        from follows.models import FollowUser, FollowCategory

        data['posts_count'] = Post.objects.filter(created_by=request.user, is_active=True).count()
        data['followers_count'] = FollowUser.objects.filter(followed=request.user).count()
        data['following_count'] = FollowUser.objects.filter(follower=request.user).count()
        data['categories_count'] = FollowCategory.objects.filter(user=request.user).count()

        from saved.models import SavedUser
        data['is_saved'] = SavedUser.objects.filter(user=request.user, saved_user=request.user).exists() # Always false for self usually but for consistency

        return Response(data)

    elif request.method == 'PUT':
        # Handle banner removal
        if request.data.get('remove_banner') == 'true' or request.data.get('remove_banner') is True:
            request.user.banner.delete(save=False)
            request.user.banner = None
            request.user.save()

        serializer = UserSerializer(request.user, data=request.data, partial=True, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def delete_account(request):
    user = request.user

    # Optional: Bulk anonymize existing messages sent by this user
    # This sets the snapshots to generic "Deleted Account" values if we want immediate anonymization
    from chat.models import Message
    Message.objects.filter(sender=user).update(
        sender_name_snapshot="Deleted Account",
        sender_avatar_snapshot="/default_user_avatar.png"
    )

    # Hard delete the user
    user.delete()

    return Response(status=status.HTTP_204_NO_CONTENT)


def _get_profile_response(request, user):
    from users.models import BlockedUser

    # Check blocking status
    is_blocked = BlockedUser.objects.filter(blocker=request.user, blocked=user).exists()
    is_blocked_by = BlockedUser.objects.filter(blocker=user, blocked=request.user).exists()

    # If the user being viewed has blocked the visitor, return 404 (as if they don't exist)
    if is_blocked_by:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

    serializer = UserSerializer(user, context={'request': request})
    data = serializer.data

    from posts.models import Post
    from follows.models import FollowUser, FollowCategory
    from notifications.models import FollowRequest

    # Ajouter les informations de follow et les counts
    is_following = FollowUser.objects.filter(
        follower=request.user,
        followed=user
    ).exists()

    # Check if there's a pending follow request sent by the visitor to this user
    follow_request = FollowRequest.objects.filter(
        requester=request.user,
        target=user,
        status='pending'
    ).first()

    # Check if this user has requested to follow the visitor
    has_requested_to_follow_visitor = FollowRequest.objects.filter(
        requester=user,
        target=request.user,
        status='pending'
    ).exists()

    data['is_following'] = is_following
    data['has_pending_request'] = follow_request is not None
    data['pending_request_id'] = follow_request.id if follow_request else None
    data['has_requested_to_follow_visitor'] = has_requested_to_follow_visitor
    data['posts_count'] = Post.objects.filter(created_by=user, is_active=True).count()
    data['followers_count'] = FollowUser.objects.filter(followed=user).count()
    data['following_count'] = FollowUser.objects.filter(follower=user).count()
    data['categories_count'] = FollowCategory.objects.filter(user=user).count()

    from saved.models import SavedUser
    data['is_saved'] = SavedUser.objects.filter(user=request.user, saved_user=user).exists()

    # Check if the user being visited is following the current visitor
    is_following_visitor = FollowUser.objects.filter(
        follower=user,
        followed=request.user
    ).exists()
    data['is_following_visitor'] = is_following_visitor

    # Add blocking status
    data['is_blocked'] = is_blocked
    data['is_blocked_by'] = is_blocked_by

    # Add Close Friends and Restricted status
    from users.models import CloseFriend, RestrictedUser
    data['is_close_friend'] = CloseFriend.objects.filter(user=request.user, friend=user).exists()
    data['is_restricted'] = RestrictedUser.objects.filter(user=request.user, restricted=user).exists()

    return Response(data)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def user_profile(request, user_id):
    try:
        user = User.objects.get(id=user_id)
        return _get_profile_response(request, user)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def user_profile_by_username(request, username):
    try:
        user = User.objects.get(username=username)
        return _get_profile_response(request, user)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)



@api_view(['POST'])
@permission_classes([IsAuthenticated])
def follow_user(request, user_id):
    try:
        user_to_follow = User.objects.get(id=user_id)

        # Vérifier que l'utilisateur ne suit pas déjà cette personne
        if FollowUser.objects.filter(follower=request.user, followed=user_to_follow).exists():
            return Response({'error': 'You are already following this user'}, status=status.HTTP_400_BAD_REQUEST)

        # Vérifier que l'utilisateur ne suit pas lui-même
        if request.user == user_to_follow:
            return Response({'error': 'You cannot follow yourself'}, status=status.HTTP_400_BAD_REQUEST)

        # Check if the user is private
        if user_to_follow.is_private:
            # Check if there's already a pending request
            from notifications.models import FollowRequest
            existing_request = FollowRequest.objects.filter(
                requester=request.user,
                target=user_to_follow,
                status='pending'
            ).exists()

            if existing_request:
                return Response({'error': 'You already have a pending request'}, status=status.HTTP_400_BAD_REQUEST)

            # Create a follow request instead of direct follow
            follow_request = FollowRequest.objects.create(
                requester=request.user,
                target=user_to_follow
            )

            # Create notification for the target user
            from notifications.utils import create_notification
            create_notification(
                recipient=user_to_follow,
                sender=request.user,
                notification_type='follow_request',
                content=f'{request.user.first_name} {request.user.last_name} requested to follow you'
            )

            return Response({'message': 'Follow request sent', 'is_pending': True}, status=status.HTTP_201_CREATED)
        else:
            # Create direct follow for public users
            FollowUser.objects.create(follower=request.user, followed=user_to_follow)

            # Create notification
            from notifications.utils import create_notification
            create_notification(
                recipient=user_to_follow,
                sender=request.user,
                notification_type='follow',
                content=f'{request.user.first_name} {request.user.last_name} started following you'
            )

            return Response({'message': 'User followed successfully', 'is_pending': False}, status=status.HTTP_201_CREATED)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def unfollow_user(request, user_id):
    try:
        user_to_unfollow = User.objects.get(id=user_id)
        follow = FollowUser.objects.filter(follower=request.user, followed=user_to_unfollow)

        if not follow.exists():
            return Response({'error': 'You are not following this user'}, status=status.HTTP_400_BAD_REQUEST)

        follow.delete()

        # Delete follow notification
        from notifications.utils import delete_related_notifications
        delete_related_notifications(
            notification_type='follow',
            sender=request.user,
            recipient=user_to_unfollow
        )

        return Response({'message': 'User unfollowed successfully'}, status=status.HTTP_200_OK)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def suggested_users(request):
    # Get some users that the current user is not following
    following_ids = FollowUser.objects.filter(follower=request.user).values_list('followed_id', flat=True)

    # Exclude blocked users
    from users.models import BlockedUser
    blocked_ids = BlockedUser.objects.filter(blocker=request.user).values_list('blocked_id', flat=True)
    blocked_by_ids = BlockedUser.objects.filter(blocked=request.user).values_list('blocker_id', flat=True)

    users = User.objects.exclude(id=request.user.id).exclude(id__in=following_ids).exclude(
        id__in=blocked_ids
    ).exclude(
        id__in=blocked_by_ids
    ).order_by('?')[:5]

    serializer = UserSerializer(users, many=True)
    return Response(serializer.data)


@api_view(['POST'])
@permission_classes([AllowAny])
@authentication_classes([])
def check_availability(request):
    username = request.data.get('username')
    email = request.data.get('email')

    response = {
        'username': True,
        'email': True
    }

    if username:
        response['username'] = not User.objects.filter(username=username).exclude(id=request.user.id if request.user.is_authenticated else None).exists()

    if email:
        response['email'] = not User.objects.filter(email=email).exclude(id=request.user.id if request.user.is_authenticated else None).exists()

    return Response(response)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def change_password(request):
    old_password = request.data.get('old_password')
    new_password = request.data.get('new_password')

    if not request.user.check_password(old_password):
        return Response({'error': 'Incorrect old password'}, status=status.HTTP_400_BAD_REQUEST)

    request.user.set_password(new_password)
    request.user.save()

    send_password_change_notice_email(request.user)

    return Response({'message': 'Password updated successfully'})


@api_view(['PUT'])
@permission_classes([IsAuthenticated])
def update_account(request):
    password = request.data.get('password')
    if not request.user.check_password(password):
        return Response({'error': 'Incorrect password'}, status=status.HTTP_400_BAD_REQUEST)

    serializer = UserSerializer(request.user, data=request.data, partial=True)
    if serializer.is_valid():
        old_username = request.user.username
        new_username = serializer.validated_data.get('username')

        # Track changes for notification
        changes = []
        if new_username and new_username != old_username:
            changes.append(f"Username changed from '{old_username}' to '{new_username}'")

        if password: # Assuming password change logic might be handled separately or here.
            # Note: The existing update_account view checks password for verification but doesn't seem to update it?
            # 'change_password' is a separate view.
            # If this view IS for general updates protecting by password:
            pass

        serializer.save()

        if changes:
             send_account_update_email(request.user, changes)

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


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def remove_follower(request, user_id):
    """
    Remove a user from following the current user (force unfollow)
    """
    try:
        follower_user = User.objects.get(id=user_id)
        follow = FollowUser.objects.filter(follower=follower_user, followed=request.user)

        if not follow.exists():
            return Response({'error': 'This user is not following you'}, status=status.HTTP_400_BAD_REQUEST)

        follow.delete()

        # Delete follow notification for the current user (since they were the recipient)
        from notifications.utils import delete_related_notifications
        delete_related_notifications(
            notification_type='follow',
            sender=follower_user,
            recipient=request.user
        )

        return Response({'message': 'Follower removed successfully'}, status=status.HTTP_200_OK)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def block_user(request, user_id):
    """
    Block a user. This will:
    - Prevent blocked user from seeing blocker's content
    - Prevent blocked user's content from appearing to blocker
    - Prevent messaging between them
    """
    from users.models import BlockedUser

    try:
        user_to_block = User.objects.get(id=user_id)

        if request.user == user_to_block:
            return Response({'error': 'You cannot block yourself'}, status=status.HTTP_400_BAD_REQUEST)

        # Check if already blocked
        if BlockedUser.objects.filter(blocker=request.user, blocked=user_to_block).exists():
            return Response({'error': 'This user is already blocked'}, status=status.HTTP_400_BAD_REQUEST)

        # Create block relationship
        BlockedUser.objects.create(blocker=request.user, blocked=user_to_block)

        # Remove any existing follow relationships in both directions
        FollowUser.objects.filter(follower=request.user, followed=user_to_block).delete()
        FollowUser.objects.filter(follower=user_to_block, followed=request.user).delete()

        # Remove any pending follow requests in both directions
        from notifications.models import FollowRequest
        FollowRequest.objects.filter(requester=request.user, target=user_to_block).delete()
        FollowRequest.objects.filter(requester=user_to_block, target=request.user).delete()

        return Response({'message': 'User blocked successfully'}, status=status.HTTP_201_CREATED)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def unblock_user(request, user_id):
    """
    Unblock a previously blocked user.
    """
    from users.models import BlockedUser

    try:
        user_to_unblock = User.objects.get(id=user_id)

        block = BlockedUser.objects.filter(blocker=request.user, blocked=user_to_unblock)
        if not block.exists():
            return Response({'error': 'This user is not blocked'}, status=status.HTTP_400_BAD_REQUEST)

        block.delete()

        return Response({'message': 'User unblocked successfully'}, status=status.HTTP_200_OK)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def blocked_list(request):
    """
    Get list of users blocked by the current user.
    """
    from users.models import BlockedUser

    blocked_users = BlockedUser.objects.filter(blocker=request.user).select_related('blocked')

    data = []
    for block in blocked_users:
        user = block.blocked
        data.append({
            'id': user.id,
            'username': user.username,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'avatar': user.avatar.url if user.avatar else None,
            'blocked_at': block.created_at.isoformat()
        })

    return Response({'results': data})


# =============================================================================
# Close Friends Management
# =============================================================================

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def add_close_friend(request, user_id):
    """Add a user to close friends list."""
    from users.models import CloseFriend

    try:
        user_to_add = User.objects.get(id=user_id)

        if request.user == user_to_add:
            return Response({'error': 'You cannot add yourself as a close friend'}, status=status.HTTP_400_BAD_REQUEST)

        if CloseFriend.objects.filter(user=request.user, friend=user_to_add).exists():
            return Response({'error': 'This user is already in your close friends'}, status=status.HTTP_400_BAD_REQUEST)

        CloseFriend.objects.create(user=request.user, friend=user_to_add)
        return Response({'message': 'User added to close friends'}, status=status.HTTP_201_CREATED)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def remove_close_friend(request, user_id):
    """Remove a user from close friends list."""
    from users.models import CloseFriend

    try:
        user_to_remove = User.objects.get(id=user_id)
        close_friend = CloseFriend.objects.filter(user=request.user, friend=user_to_remove)

        if not close_friend.exists():
            return Response({'error': 'This user is not in your close friends'}, status=status.HTTP_400_BAD_REQUEST)

        close_friend.delete()
        return Response({'message': 'User removed from close friends'}, status=status.HTTP_200_OK)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def close_friends_list(request):
    """Get list of close friends for the current user."""
    from users.models import CloseFriend

    close_friends = CloseFriend.objects.filter(user=request.user).select_related('friend')

    data = []
    for cf in close_friends:
        user = cf.friend
        data.append({
            'id': user.id,
            'username': user.username,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'avatar': user.avatar.url if user.avatar else None,
            'added_at': cf.created_at.isoformat()
        })

    return Response({'results': data})


# =============================================================================
# Restricted Users Management
# =============================================================================

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def add_restricted_user(request, user_id):
    """Add a user to restricted list (they won't see your posts)."""
    from users.models import RestrictedUser

    try:
        user_to_add = User.objects.get(id=user_id)

        if request.user == user_to_add:
            return Response({'error': 'You cannot add yourself to restricted list'}, status=status.HTTP_400_BAD_REQUEST)

        if RestrictedUser.objects.filter(user=request.user, restricted=user_to_add).exists():
            return Response({'error': 'This user is already in your restricted list'}, status=status.HTTP_400_BAD_REQUEST)

        RestrictedUser.objects.create(user=request.user, restricted=user_to_add)
        return Response({'message': 'User added to restricted list'}, status=status.HTTP_201_CREATED)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def remove_restricted_user(request, user_id):
    """Remove a user from restricted list."""
    from users.models import RestrictedUser

    try:
        user_to_remove = User.objects.get(id=user_id)
        restricted = RestrictedUser.objects.filter(user=request.user, restricted=user_to_remove)

        if not restricted.exists():
            return Response({'error': 'This user is not in your restricted list'}, status=status.HTTP_400_BAD_REQUEST)

        restricted.delete()
        return Response({'message': 'User removed from restricted list'}, status=status.HTTP_200_OK)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def restricted_users_list(request):
    """Get list of restricted users for the current user."""
    from users.models import RestrictedUser

    restricted_users = RestrictedUser.objects.filter(user=request.user).select_related('restricted')

    data = []
    for ru in restricted_users:
        user = ru.restricted
        data.append({
            'id': user.id,
            'username': user.username,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'avatar': user.avatar.url if user.avatar else None,
            'added_at': ru.created_at.isoformat()
        })

    return Response({'results': data})

@api_view(['POST'])
@permission_classes([AllowAny])
@authentication_classes([])
def google_login(request):
    print("Google Login Request Data:", request.data) # DEBUG
    token = request.data.get('token')
    is_code = request.data.get('is_code', False)

    if not token:
        return Response({'error': 'Missing token'}, status=status.HTTP_400_BAD_REQUEST)

    try:
        from google.oauth2 import id_token
        from google.auth.transport import requests as google_requests
        import uuid
        import requests
        from decouple import config

        CLIENT_ID = config('GOOGLE_CLIENT_ID')
        CLIENT_SECRET = config('GOOGLE_CLIENT_SECRET')

        if is_code:
            # Exchange code for token
            # Note: redirect_uri must match the one sent by the frontend (postmessage for many libraries)
            res = requests.post('https://oauth2.googleapis.com/token', data={
                'code': token,
                'client_id': CLIENT_ID,
                'client_secret': CLIENT_SECRET,
                'redirect_uri': 'postmessage',
                'grant_type': 'authorization_code'
            })
            res_data = res.json()
            if 'error' in res_data:
                return Response({'error': f"Code exchange failed: {res_data.get('error_description', res_data['error'])}"}, status=status.HTTP_400_BAD_REQUEST)
            token = res_data.get('id_token')

        # Verify the token
        try:
            idinfo = id_token.verify_oauth2_token(token, google_requests.Request(), CLIENT_ID)
        except ValueError:
             return Response({'error': 'Invalid Google token or incorrect audience'}, status=status.HTTP_400_BAD_REQUEST)

        email = idinfo['email']

        user, created = User.objects.get_or_create(email=email, defaults={
            'username': email.split('@')[0],
            'first_name': idinfo.get('given_name', ''),
            'last_name': idinfo.get('family_name', '')
        })

        # Auto-verify user since Google has already verified the email
        if not user.is_verified:
            user.is_verified = True
            user.save()

        # Save avatar if it doesn't exist
        picture_url = idinfo.get('picture')
        if picture_url and not user.avatar:
            try:
                from django.core.files.base import ContentFile
                response = requests.get(picture_url)
                if response.status_code == 200:
                    user.avatar.save(f"avatar_{user.id}.jpg", ContentFile(response.content), save=True)
            except Exception as e:
                print(f"Error saving avatar: {e}")

        # Handle username conflict if created
        if created and User.objects.filter(username=user.username).count() > 1:
            user.username = f"{user.username}_{uuid.uuid4().hex[:8]}"
            user.save()

        login(request, user)
        token_obj, _ = Token.objects.get_or_create(user=user)

        response = Response({
            'user': UserSerializer(user, context={'request': request}).data
        }, status=status.HTTP_200_OK)
        response.set_cookie(
            'auth_token',
            token_obj.key,
            httponly=True,
            samesite='Lax',
            secure=settings.AUTH_COOKIE_SECURE
        )
        return response

    except Exception as e:
        return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)


@api_view(['POST'])
@permission_classes([AllowAny])
@authentication_classes([])
def request_password_reset(request):
    email = request.data.get('email')
    if not email:
        return Response({'error': 'Email required'}, status=status.HTTP_400_BAD_REQUEST)

    try:
        user = User.objects.get(email=email)

        # Verify if there is already a valid code? For now just create a new one.
        code = generate_verification_code()
        VerificationCode.objects.create(
            user=user,
            code=code,
            type='reset',
            expires_at=timezone.now() + timedelta(minutes=15)
        )

        send_password_reset_email(user, code)

        return Response({'message': 'Reset code sent'})

    except User.DoesNotExist:
        # Don't reveal user existence? Or maybe yes for UX?
        # For security usually we say "If the account exists..." but typically for this level of app exact feedback is fine/easier.
        return Response({'error': 'No account associated with this email'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['POST'])
@permission_classes([AllowAny])
@authentication_classes([])
def reset_password_confirm(request):
    email = request.data.get('email')
    code = request.data.get('code')
    new_password = request.data.get('new_password')

    if not all([email, code, new_password]):
        return Response({'error': 'Missing data'}, status=status.HTTP_400_BAD_REQUEST)

    try:
        user = User.objects.get(email=email)

        verification = VerificationCode.objects.filter(
            user=user,
            code=code,
            type='reset',
            expires_at__gt=timezone.now()
        ).order_by('-created_at').first()

        if not verification:
            return Response({'error': 'Invalid or expired code'}, status=status.HTTP_400_BAD_REQUEST)

        user.set_password(new_password)
        user.save()

        # Invalidate code
        verification.delete()

        send_password_change_notice_email(user)

        return Response({'message': 'Password reset successfully'})

    except User.DoesNotExist:
         return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def verify_email(request):
    code = request.data.get('code')
    if not code:
        return Response({'error': 'Code required'}, status=status.HTTP_400_BAD_REQUEST)

    # Allow re-verification if needed, or check if already verified?
    # Usually if logged in and not verified

    verification = VerificationCode.objects.filter(
        user=request.user,
        code=code,
        type='register',
        expires_at__gt=timezone.now()
    ).order_by('-created_at').first()

    if not verification:
        return Response({'error': 'Invalid or expired code'}, status=status.HTTP_400_BAD_REQUEST)

    request.user.is_verified = True
    request.user.save()

    # Clean up register codes
    VerificationCode.objects.filter(user=request.user, type='register').delete()

    return Response({
        'message': 'Email verified successfully',
        'user': UserSerializer(request.user, context={'request': request}).data
    })


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def resend_verification_email_view(request):
    if request.user.is_verified:
        return Response({'message': 'Account already verified'}, status=status.HTTP_200_OK)

    code = generate_verification_code()
    VerificationCode.objects.create(
        user=request.user,
        code=code,
        type='register',
        expires_at=timezone.now() + timedelta(hours=24)
    )
    send_verification_email(request.user, code)

    return Response({'message': 'Verification code resent'})


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def request_email_change(request):
    new_email = request.data.get('new_email')
    if not new_email:
        return Response({'error': 'New email required'}, status=status.HTTP_400_BAD_REQUEST)

    if User.objects.filter(email=new_email).exists():
        return Response({'error': 'This email is already in use by another account'}, status=status.HTTP_400_BAD_REQUEST)

    code = generate_verification_code()
    # Expire any existing email change codes for this user
    VerificationCode.objects.filter(user=request.user, type='email_change').delete()

    VerificationCode.objects.create(
        user=request.user,
        code=code,
        type='email_change',
        pending_email=new_email,
        expires_at=timezone.now() + timedelta(minutes=15)
    )

    send_email_change_verification(request.user, code, new_email)

    return Response({'message': 'Verification code sent to your new email'})


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def confirm_email_change(request):
    code = request.data.get('code')
    if not code:
        return Response({'error': 'Code required'}, status=status.HTTP_400_BAD_REQUEST)

    verification = VerificationCode.objects.filter(
        user=request.user,
        code=code,
        type='email_change',
        expires_at__gt=timezone.now()
    ).order_by('-created_at').first()

    if not verification:
        return Response({'error': 'Invalid or expired code'}, status=status.HTTP_400_BAD_REQUEST)

    old_email = request.user.email
    new_email = verification.pending_email

    # Check if new_email is still available
    if User.objects.filter(email=new_email).exclude(id=request.user.id).exists():
        return Response({'error': 'This email is already taken'}, status=status.HTTP_400_BAD_REQUEST)

    request.user.email = new_email
    request.user.save()

    # Invalidate code
    verification.delete()

    # Send notifications
    send_email_changed_notifications(request.user, old_email, new_email)

    return Response({
        'message': 'Email updated successfully',
        'user': UserSerializer(request.user, context={'request': request}).data
    })


# Close Friends endpoints
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def close_friends_list(request):
    """Get list of user's close friends"""
    from users.models import CloseFriend
    close_friends = CloseFriend.objects.filter(user=request.user).select_related('friend')
    friends_data = [
        {
            'id': cf.friend.id,
            'username': cf.friend.username,
            'first_name': cf.friend.first_name,
            'last_name': cf.friend.last_name,
            'avatar': cf.friend.avatar.url if cf.friend.avatar else None
        }
        for cf in close_friends
    ]
    return Response(friends_data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def add_close_friend(request, user_id):
    """Add a user to close friends list"""
    from users.models import CloseFriend
    try:
        friend = User.objects.get(id=user_id)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

    if friend == request.user:
        return Response({'error': 'Cannot add yourself'}, status=status.HTTP_400_BAD_REQUEST)

    close_friend, created = CloseFriend.objects.get_or_create(user=request.user, friend=friend)
    if not created:
        return Response({'message': 'Already in close friends'}, status=status.HTTP_200_OK)

    return Response({'message': 'Added to close friends'}, status=status.HTTP_201_CREATED)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def remove_close_friend(request, user_id):
    """Remove a user from close friends list"""
    from users.models import CloseFriend
    try:
        friend = User.objects.get(id=user_id)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

    deleted, _ = CloseFriend.objects.filter(user=request.user, friend=friend).delete()
    if deleted:
        return Response({'message': 'Removed from close friends'}, status=status.HTTP_200_OK)
    return Response({'error': 'User not in close friends'}, status=status.HTTP_404_NOT_FOUND)


# Restricted Users endpoints
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def restricted_users_list(request):
    """Get list of restricted users"""
    from users.models import RestrictedUser
    restricted = RestrictedUser.objects.filter(user=request.user).select_related('restricted')
    users_data = [
        {
            'id': ru.restricted.id,
            'username': ru.restricted.username,
            'first_name': ru.restricted.first_name,
            'last_name': ru.restricted.last_name,
            'avatar': ru.restricted.avatar.url if ru.restricted.avatar else None
        }
        for ru in restricted
    ]
    return Response(users_data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def add_restricted_user(request, user_id):
    """Add a user to restricted list"""
    from users.models import RestrictedUser
    try:
        restricted_user = User.objects.get(id=user_id)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

    if restricted_user == request.user:
        return Response({'error': 'Cannot restrict yourself'}, status=status.HTTP_400_BAD_REQUEST)

    restricted, created = RestrictedUser.objects.get_or_create(user=request.user, restricted=restricted_user)
    if not created:
        return Response({'message': 'Already restricted'}, status=status.HTTP_200_OK)

    return Response({'message': 'User restricted'}, status=status.HTTP_201_CREATED)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def remove_restricted_user(request, user_id):
    """Remove a user from restricted list"""
    from users.models import RestrictedUser
    try:
        restricted_user = User.objects.get(id=user_id)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

    deleted, _ = RestrictedUser.objects.filter(user=request.user, restricted=restricted_user).delete()
    if deleted:
        return Response({'message': 'User unrestricted'}, status=status.HTTP_200_OK)
    return Response({'error': 'User not in restricted list'}, status=status.HTTP_404_NOT_FOUND)


# =============================================================================
# Profile Links Management
# =============================================================================

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def profile_links_list(request):
    """Get all profile links for the authenticated user"""
    from users.models import ProfileLink
    from users.serializers import ProfileLinkSerializer

    print(f"[PROFILE LINKS] User: {request.user}, Authenticated: {request.user.is_authenticated}")

    links = ProfileLink.objects.filter(user=request.user).order_by('order', 'created_at')
    print(f"[PROFILE LINKS] Found {links.count()} links for user {request.user.username}")

    serializer = ProfileLinkSerializer(links, many=True)
    return Response(serializer.data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def profile_link_create(request):
    """Create a new profile link"""
    from users.models import ProfileLink
    from users.serializers import ProfileLinkSerializer

    # Check if user already has this link type (except custom which can have multiple)
    link_type = request.data.get('link_type')
    if link_type != 'custom':
        if ProfileLink.objects.filter(user=request.user, link_type=link_type).exists():
            return Response(
                {'error': f'You already have a {link_type} link. Please update the existing one.'},
                status=status.HTTP_400_BAD_REQUEST
            )

    serializer = ProfileLinkSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save(user=request.user)
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['PUT', 'PATCH'])
@permission_classes([IsAuthenticated])
def profile_link_update(request, link_id):
    """Update an existing profile link"""
    from users.models import ProfileLink
    from users.serializers import ProfileLinkSerializer

    try:
        link = ProfileLink.objects.get(id=link_id, user=request.user)
    except ProfileLink.DoesNotExist:
        return Response({'error': 'Link not found'}, status=status.HTTP_404_NOT_FOUND)

    serializer = ProfileLinkSerializer(link, data=request.data, partial=True)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def profile_link_delete(request, link_id):
    """Delete a profile link"""
    from users.models import ProfileLink

    try:
        link = ProfileLink.objects.get(id=link_id, user=request.user)
    except ProfileLink.DoesNotExist:
        return Response({'error': 'Link not found'}, status=status.HTTP_404_NOT_FOUND)

    link.delete()
    return Response({'message': 'Link deleted successfully'}, status=status.HTTP_200_OK)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def profile_links_bulk_update(request):
    """
    Bulk update profile links (for reordering or batch updates)
    Expected format: {'links': [{'id': 1, 'order': 0, 'is_enabled': True}, ...]}
    """
    from users.models import ProfileLink

    links_data = request.data.get('links', [])

    if not isinstance(links_data, list):
        return Response({'error': 'Invalid data format'}, status=status.HTTP_400_BAD_REQUEST)

    updated_count = 0
    for link_data in links_data:
        link_id = link_data.get('id')
        if not link_id:
            continue

        try:
            link = ProfileLink.objects.get(id=link_id, user=request.user)

            # Update order if provided
            if 'order' in link_data:
                link.order = link_data['order']

            # Update is_enabled if provided
            if 'is_enabled' in link_data:
                link.is_enabled = link_data['is_enabled']

            link.save()
            updated_count += 1
        except ProfileLink.DoesNotExist:
            continue

    return Response({
        'message': f'Updated {updated_count} links successfully',
        'updated_count': updated_count
    }, status=status.HTTP_200_OK)
