from django.core.paginator import Paginator
from rest_framework import status, permissions
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from .models import SavedPost, SavedUser, SavedCategory
from .serializers import SavedPostSerializer, SavedUserSerializer, SavedCategorySerializer
from posts.models import Post
from categories.models import Category
from django.contrib.auth import get_user_model

User = get_user_model()

@api_view(['POST', 'DELETE'])
@permission_classes([permissions.IsAuthenticated])
def toggle_save_post(request, post_id):
    try:
        post = Post.objects.get(id=post_id, is_active=True)
    except Post.DoesNotExist:
        return Response({'error': 'Post not found'}, status=status.HTTP_404_NOT_FOUND)

    saved_item = SavedPost.objects.filter(user=request.user, post=post)

    if request.method == 'POST':
        if saved_item.exists():
            return Response({'message': 'Post already saved'}, status=status.HTTP_400_BAD_REQUEST)

        # Check if author allows saving
        if not post.allow_saving:
             return Response({'error': 'The author has disabled saving for this post.'}, status=status.HTTP_403_FORBIDDEN)

        SavedPost.objects.create(user=request.user, post=post)
        return Response({'message': 'Post saved successfully', 'is_saved': True}, status=status.HTTP_201_CREATED)

    elif request.method == 'DELETE':
        if not saved_item.exists():
            return Response({'error': 'Post not saved'}, status=status.HTTP_400_BAD_REQUEST)
        saved_item.delete()
        return Response({'message': 'Post removed from saved', 'is_saved': False}, status=status.HTTP_200_OK)

@api_view(['POST', 'DELETE'])
@permission_classes([permissions.IsAuthenticated])
def toggle_save_user(request, user_id):
    try:
        target_user = User.objects.get(id=user_id)
    except User.DoesNotExist:
        return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

    if target_user == request.user:
        return Response({'error': 'You cannot save your own profile'}, status=status.HTTP_400_BAD_REQUEST)

    saved_item = SavedUser.objects.filter(user=request.user, saved_user=target_user)

    if request.method == 'POST':
        if saved_item.exists():
            return Response({'message': 'Profile already saved'}, status=status.HTTP_400_BAD_REQUEST)
        SavedUser.objects.create(user=request.user, saved_user=target_user)
        return Response({'message': 'Profile saved successfully', 'is_saved': True}, status=status.HTTP_201_CREATED)

    elif request.method == 'DELETE':
        if not saved_item.exists():
            return Response({'error': 'Profile not saved'}, status=status.HTTP_400_BAD_REQUEST)
        saved_item.delete()
        return Response({'message': 'Profile removed from saved', 'is_saved': False}, status=status.HTTP_200_OK)

@api_view(['POST', 'DELETE'])
@permission_classes([permissions.IsAuthenticated])
def toggle_save_category(request, category_id):
    try:
        category = Category.objects.get(id=category_id)
    except Category.DoesNotExist:
        return Response({'error': 'Category not found'}, status=status.HTTP_404_NOT_FOUND)

    saved_item = SavedCategory.objects.filter(user=request.user, category=category)

    if request.method == 'POST':
        if saved_item.exists():
            return Response({'message': 'Category already saved'}, status=status.HTTP_400_BAD_REQUEST)
        SavedCategory.objects.create(user=request.user, category=category)
        return Response({'message': 'Category saved successfully', 'is_saved': True}, status=status.HTTP_201_CREATED)

    elif request.method == 'DELETE':
        if not saved_item.exists():
            return Response({'error': 'Category not saved'}, status=status.HTTP_400_BAD_REQUEST)
        saved_item.delete()
        return Response({'message': 'Category removed from saved', 'is_saved': False}, status=status.HTTP_200_OK)

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def list_saved_posts(request):
    saved_posts = SavedPost.objects.filter(user=request.user, post__is_active=True).order_by('-created_at')
    # Pagination
    paginator = Paginator(saved_posts, 12)
    page_number = request.query_params.get('page', 1)
    page_obj = paginator.get_page(page_number)

    serializer = SavedPostSerializer(page_obj, many=True, context={'request': request})
    return Response({
        'results': serializer.data,
        'next': f"?page={page_obj.next_page_number()}" if page_obj.has_next() else None,
        'previous': f"?page={page_obj.previous_page_number()}" if page_obj.has_previous() else None,
        'count': paginator.count
    })

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def list_saved_users(request):
    saved_users = SavedUser.objects.filter(user=request.user).order_by('-created_at')
    paginator = Paginator(saved_users, 12)
    page_number = request.query_params.get('page', 1)
    page_obj = paginator.get_page(page_number)

    serializer = SavedUserSerializer(page_obj, many=True, context={'request': request})
    return Response({
        'results': serializer.data,
        'next': f"?page={page_obj.next_page_number()}" if page_obj.has_next() else None,
        'previous': f"?page={page_obj.previous_page_number()}" if page_obj.has_previous() else None,
        'count': paginator.count
    })

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def list_saved_categories(request):
    saved_categories = SavedCategory.objects.filter(user=request.user).order_by('-created_at')
    paginator = Paginator(saved_categories, 12)
    page_number = request.query_params.get('page', 1)
    page_obj = paginator.get_page(page_number)
    serializer = SavedCategorySerializer(page_obj, many=True, context={'request': request})
    return Response({
        'results': serializer.data,
        'next': f"?page={page_obj.next_page_number()}" if page_obj.has_next() else None,
        'previous': f"?page={page_obj.previous_page_number()}" if page_obj.has_previous() else None,
        'count': paginator.count
    })
