from rest_framework import status
from rest_framework.decorators import api_view, permission_classes, parser_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from django.utils import timezone
from django.core.cache import cache as redis_cache
from datetime import timedelta

from .models import Story, StoryView
from .serializers import StorySerializer, StoryCreateSerializer, MyStorySerializer
from accounts.models import Follow


@api_view(['GET'])
@permission_classes([AllowAny])
def list_stories(request):
    """List all active stories (within 24 hours), personalized ordering for authenticated users"""
    cached = redis_cache.get('active_stories_data')
    if cached is None:
        cutoff = timezone.now() - timedelta(hours=24)
        stories = Story.objects.filter(created_at__gte=cutoff).select_related(
            'vendor', 'vendor__vendor_profile'
        ).order_by('-created_at')
        serializer = StorySerializer(stories, many=True, context={'request': request})
        cached = serializer.data
        redis_cache.set('active_stories_data', cached, 60)

    if not request.user.is_authenticated:
        return Response(cached)

    followed_vendor_ids = set(
        Follow.objects.filter(buyer=request.user).values_list('vendor_id', flat=True)
    )
    user_county = getattr(request.user, 'county', None)

    def sort_key(story):
        if story['vendor_id'] in followed_vendor_ids:
            return 0
        if user_county and story.get('vendor_county') == user_county:
            return 1
        return 2

    sorted_stories = sorted(cached, key=sort_key)
    return Response(sorted_stories)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
@parser_classes([MultiPartParser, FormParser])
def create_story(request):
    """Create a new story (vendor only)"""
    if request.user.user_type != 'vendor':
        return Response(
            {'error': 'Only vendors can create stories'},
            status=status.HTTP_403_FORBIDDEN,
        )

    # Check if vendor is upgraded
    try:
        profile = request.user.vendor_profile
        if not profile.is_upgraded:
            return Response(
                {'error': 'Upgrade to Pro to create stories'},
                status=status.HTTP_403_FORBIDDEN,
            )
    except Exception:
        return Response(
            {'error': 'Vendor profile not found'},
            status=status.HTTP_400_BAD_REQUEST,
        )

    serializer = StoryCreateSerializer(data=request.data)
    if serializer.is_valid():
        story = serializer.save(vendor=request.user)
        redis_cache.delete('active_stories_data')
        return Response(
            StorySerializer(story, context={'request': request}).data,
            status=status.HTTP_201_CREATED,
        )
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def my_stories(request):
    """List the current vendor's own stories"""
    if request.user.user_type != 'vendor':
        return Response(
            {'error': 'Only vendors can view their stories'},
            status=status.HTTP_403_FORBIDDEN,
        )

    cutoff = timezone.now() - timedelta(hours=24)
    stories = Story.objects.filter(vendor=request.user, created_at__gte=cutoff)
    serializer = MyStorySerializer(stories, many=True, context={'request': request})
    return Response(serializer.data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def track_view(request, story_id):
    """Track a story view"""
    try:
        story = Story.objects.get(id=story_id)
    except Story.DoesNotExist:
        return Response(
            {'error': 'Story not found'},
            status=status.HTTP_404_NOT_FOUND,
        )

    # Don't count vendor viewing their own story
    if story.vendor == request.user:
        return Response({'status': 'ok'})

    _, created = StoryView.objects.get_or_create(
        story=story,
        viewer=request.user,
    )
    if created:
        story.views_count += 1
        story.save(update_fields=['views_count'])

    return Response({'status': 'ok'})


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def following_stories(request):
    """Get one latest story per followed vendor (for home page)"""
    followed_vendor_ids = list(
        Follow.objects.filter(buyer=request.user).values_list('vendor_id', flat=True)
    )
    if not followed_vendor_ids:
        return Response([])

    cutoff = timezone.now() - timedelta(hours=24)
    stories = Story.objects.filter(
        vendor_id__in=followed_vendor_ids,
        created_at__gte=cutoff,
    ).select_related('vendor', 'vendor__vendor_profile').order_by('-created_at')

    # One latest story per vendor
    seen_vendors = set()
    unique_stories = []
    for story in stories:
        if story.vendor_id not in seen_vendors:
            seen_vendors.add(story.vendor_id)
            unique_stories.append(story)

    serializer = StorySerializer(unique_stories, many=True, context={'request': request})
    return Response(serializer.data)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def delete_story(request, story_id):
    """Delete own story"""
    try:
        story = Story.objects.get(id=story_id, vendor=request.user)
    except Story.DoesNotExist:
        return Response(
            {'error': 'Story not found'},
            status=status.HTTP_404_NOT_FOUND,
        )

    story.delete()
    redis_cache.delete('active_stories_data')
    return Response(status=status.HTTP_204_NO_CONTENT)
