"""
Business Views - API Endpoints
"""

from rest_framework import status
from rest_framework.decorators import api_view, permission_classes, throttle_classes
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from django.db.models import Q, Count
from django.conf import settings
from .throttles import ReviewCreateRateThrottle, LeadEventRateThrottle
from django.shortcuts import render, get_object_or_404

from django.utils import timezone
from datetime import timedelta
from collections import Counter

from .models import Business, Category, SubCategory, Review, BusinessImage, BusinessHours, BusinessView, Feedback, Service, Offer, NewsletterSubscriber, PlatformSettings, SearchQuery, Campaign, SlugRedirect
from .serializers import (
    BusinessListSerializer, BusinessDetailSerializer, BusinessCreateSerializer,
    CategorySerializer, SubCategorySerializer, ReviewSerializer, ReviewCreateSerializer,
    DashboardSectionSerializer, BusinessImageSerializer, BusinessHoursSerializer,
    FeedbackSerializer, FeedbackCreateSerializer, LeadEventCreateSerializer,
    ContactRequestCreateSerializer, ListingDetailSerializer, OfferListSerializer,
    NewsletterSubscriberSerializer, ReportCreateSerializer
)
from .utils import (
    add_distance_to_businesses, get_nearby_businesses,
    get_top_rated_businesses, get_home_service_businesses,
    create_notification, send_push_notification, get_suggested_businesses,
    log_campaign_event,
)
from authentication.utils import send_business_live_email, send_new_review_email


class BusinessPagination(PageNumberPagination):
    """Custom pagination for business listings"""
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100


def get_client_ip(request):
    """Get client IP address from request"""
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0].strip()
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip


def record_unique_view(business, request):
    """
    Record a unique view for a business.
    Returns True if this is a new view (and count was incremented), False otherwise.
    """
    user = request.user if request.user.is_authenticated else None
    ip_address = get_client_ip(request)

    # Check if this user/IP has already viewed this business
    if user:
        # For logged-in users, check by user
        view_exists = BusinessView.objects.filter(business=business, user=user).exists()
    else:
        # For anonymous users, check by IP address
        view_exists = BusinessView.objects.filter(business=business, ip_address=ip_address, user__isnull=True).exists()

    if not view_exists:
        # Record the new view
        BusinessView.objects.create(
            business=business,
            user=user,
            ip_address=ip_address
        )
        # Increment the view count
        business.view_count += 1
        business.save(update_fields=['view_count'])
        return True

    return False


@api_view(['GET', 'POST'])
@permission_classes([AllowAny])
def dashboard_view(request):
    """
    Dashboard API - Returns multiple sections

    GET /api/business/dashboard/?latitude=31.5204&longitude=74.3587
    POST /api/business/dashboard/
    Body:
    {
        "latitude": 31.5204,
        "longitude": 74.3587
    }

    Returns:
    - Top Rated businesses (based on rating)
    - Nearby businesses (based on user location)
    - Home Services (businesses providing home service)
    - Categories (list of available categories)
    """
    # Get latitude/longitude from query params (GET) or body (POST)
    if request.method == 'GET':
        user_lat = request.query_params.get('latitude')
        user_lon = request.query_params.get('longitude')
    else:
        user_lat = request.data.get('latitude')
        user_lon = request.data.get('longitude')

    if not user_lat or not user_lon:
        return Response({
            'error': 'Latitude and longitude are required'
        }, status=status.HTTP_400_BAD_REQUEST)

    try:
        user_lat = float(user_lat)
        user_lon = float(user_lon)
    except (ValueError, TypeError):
        return Response({
            'error': 'Invalid latitude or longitude format'
        }, status=status.HTTP_400_BAD_REQUEST)

    # Get Top Rated Businesses (minimum 5 reviews, top 5 businesses)
    top_rated = get_top_rated_businesses(limit=5, min_reviews=3)
    top_rated_with_distance = add_distance_to_businesses(top_rated, user_lat, user_lon)

    # Get Nearby Businesses (within 50km, top 5)
    nearby = get_nearby_businesses(user_lat, user_lon, max_distance_km=50, limit=5)

    # Get Home Service Businesses (within 30km, top 5)
    home_services = get_home_service_businesses(user_lat, user_lon, max_distance_km=30, limit=5)

    # Get All Categories
    categories = Category.objects.filter(is_active=True)

    # Get Recently Added Businesses (top 5)
    recent = Business.objects.filter(is_active=True).order_by('-created_at')[:5]
    recent_with_distance = add_distance_to_businesses(recent, user_lat, user_lon)

    # Prepare response
    response_data = {
        'sections': [
            {
                'section_name': 'Top Rated',
                'section_type': 'top_rated',
                'businesses': BusinessListSerializer(top_rated_with_distance, many=True, context={'request': request}).data,
                'total_count': Business.objects.filter(is_active=True, total_reviews__gte=3).count()
            },
            {
                'section_name': 'Nearby',
                'section_type': 'nearby',
                'businesses': BusinessListSerializer(nearby, many=True, context={'request': request}).data,
                'total_count': len(nearby)
            },
            {
                'section_name': 'Home Services',
                'section_type': 'home_services',
                'businesses': BusinessListSerializer(home_services, many=True, context={'request': request}).data,
                'total_count': Business.objects.filter(is_active=True, provides_home_service=True).count()
            },
            {
                'section_name': 'Recently Added',
                'section_type': 'recent',
                'businesses': BusinessListSerializer(recent_with_distance, many=True, context={'request': request}).data,
                'total_count': Business.objects.filter(is_active=True).count()
            }
        ],
        'categories': CategorySerializer(categories, many=True, context={'request': request}).data
    }

    return Response(response_data, status=status.HTTP_200_OK)


@api_view(['GET', 'POST'])
@permission_classes([AllowAny])
def section_detail_view(request, section_type):
    """
    View More - Get all businesses for a specific section

    GET /api/business/section/{section_type}/?latitude=31.5204&longitude=74.3587
    POST /api/business/section/{section_type}/
    section_type: top_rated, nearby, home_services, recent

    Body:
    {
        "latitude": 31.5204,
        "longitude": 74.3587,
        "page": 1
    }
    """
    # Get latitude/longitude from query params (GET) or body (POST)
    if request.method == 'GET':
        user_lat = request.query_params.get('latitude')
        user_lon = request.query_params.get('longitude')
    else:
        user_lat = request.data.get('latitude')
        user_lon = request.data.get('longitude')

    if not user_lat or not user_lon:
        return Response({
            'error': 'Latitude and longitude are required'
        }, status=status.HTTP_400_BAD_REQUEST)

    try:
        user_lat = float(user_lat)
        user_lon = float(user_lon)
    except (ValueError, TypeError):
        return Response({
            'error': 'Invalid latitude or longitude format'
        }, status=status.HTTP_400_BAD_REQUEST)

    # Get businesses based on section type
    if section_type == 'top_rated':
        businesses = get_top_rated_businesses(min_reviews=3)
        businesses = add_distance_to_businesses(businesses, user_lat, user_lon)
        section_name = 'Top Rated'

    elif section_type == 'nearby':
        businesses = get_nearby_businesses(user_lat, user_lon, max_distance_km=50)
        section_name = 'Nearby'

    elif section_type == 'home_services':
        businesses = get_home_service_businesses(user_lat, user_lon, max_distance_km=30)
        section_name = 'Home Services'

    elif section_type == 'recent':
        recent_businesses = Business.objects.filter(is_active=True).order_by('-created_at')
        businesses = add_distance_to_businesses(recent_businesses, user_lat, user_lon)
        section_name = 'Recently Added'

    else:
        return Response({
            'error': 'Invalid section type'
        }, status=status.HTTP_400_BAD_REQUEST)

    # Paginate results
    paginator = BusinessPagination()
    paginated_businesses = paginator.paginate_queryset(businesses, request)
    serializer = BusinessListSerializer(paginated_businesses, many=True, context={'request': request})

    return paginator.get_paginated_response({
        'section_name': section_name,
        'section_type': section_type,
        'businesses': serializer.data
    })


@api_view(['GET', 'POST'])
@permission_classes([AllowAny])
def category_businesses_view(request, category_id):
    """
    Get all businesses for a specific category

    GET /api/business/category/{category_id}/?latitude=31.5204&longitude=74.3587
    POST /api/business/category/{category_id}/
    Body:
    {
        "latitude": 31.5204,
        "longitude": 74.3587,
        "page": 1
    }
    """
    # Get latitude/longitude from query params (GET) or body (POST)
    if request.method == 'GET':
        user_lat = request.query_params.get('latitude')
        user_lon = request.query_params.get('longitude')
    else:
        user_lat = request.data.get('latitude')
        user_lon = request.data.get('longitude')

    if not user_lat or not user_lon:
        return Response({
            'error': 'Latitude and longitude are required'
        }, status=status.HTTP_400_BAD_REQUEST)

    try:
        user_lat = float(user_lat)
        user_lon = float(user_lon)
    except (ValueError, TypeError):
        return Response({
            'error': 'Invalid latitude or longitude format'
        }, status=status.HTTP_400_BAD_REQUEST)

    try:
        category = Category.objects.get(id=category_id, is_active=True)
    except Category.DoesNotExist:
        return Response({
            'error': 'Category not found'
        }, status=status.HTTP_404_NOT_FOUND)

    # Get businesses in this category (directly linked or through sub-categories)
    from django.db.models import Q
    businesses = Business.objects.filter(
        Q(categories=category) | Q(sub_categories__category=category),
        is_active=True
    ).distinct().order_by('-average_rating', '-created_at')

    # Add distance
    businesses_with_distance = add_distance_to_businesses(businesses, user_lat, user_lon)

    # Paginate
    paginator = BusinessPagination()
    paginated_businesses = paginator.paginate_queryset(businesses_with_distance, request)
    serializer = BusinessListSerializer(paginated_businesses, many=True, context={'request': request})

    return paginator.get_paginated_response({
        'category': CategorySerializer(category, context={'request': request}).data,
        'businesses': serializer.data
    })


@api_view(['GET', 'POST', 'DELETE'])
@permission_classes([AllowAny])
def business_detail_view(request, business_id):
    """
    Get, update, or delete business details

    GET /api/business/{business_id}/
    View business details (anyone can view)

    POST /api/business/{business_id}/
    Update business (only owner can update)

    DELETE /api/business/{business_id}/
    Delete business (only owner can delete)
    """
    try:
        business = Business.objects.get(id=business_id)
    except Business.DoesNotExist:
        return Response({
            'error': 'Business not found'
        }, status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        # Record unique view (only counts once per user/IP)
        record_unique_view(business, request)

        # Add distance if user provides location
        user_lat = request.query_params.get('latitude')
        user_lon = request.query_params.get('longitude')

        if user_lat and user_lon:
            try:
                businesses_with_distance = add_distance_to_businesses(
                    [business],
                    float(user_lat),
                    float(user_lon)
                )
                business = businesses_with_distance[0]
            except (ValueError, TypeError):
                pass

        serializer = BusinessDetailSerializer(business, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)

    # DELETE - Delete business (only owner)
    if request.method == 'DELETE':
        if not request.user.is_authenticated:
            return Response({
                'error': 'Authentication required'
            }, status=status.HTTP_401_UNAUTHORIZED)

        if business.owner != request.user:
            return Response({
                'error': 'You do not have permission to delete this business'
            }, status=status.HTTP_403_FORBIDDEN)

        business_title = business.title
        business.delete()

        return Response({
            'message': f'Business "{business_title}" has been deleted successfully'
        }, status=status.HTTP_200_OK)

    # POST - Update business (owner or a manager-level team member)
    if not request.user.is_authenticated:
        return Response({
            'error': 'Authentication required'
        }, status=status.HTTP_401_UNAUTHORIZED)

    is_manager = business.memberships.filter(
        user=request.user, status='active', role__in=['owner', 'manager']
    ).exists()
    if business.owner != request.user and not is_manager:
        return Response({
            'error': 'You do not have permission to update this business'
        }, status=status.HTTP_403_FORBIDDEN)

    import json

    serializer = BusinessCreateSerializer(business, data=request.data, partial=True)
    if serializer.is_valid():
        serializer.save()

        # When the client switches the parent category but doesn't pick a
        # sub-category, multipart-form-data drops the empty `sub_categories=[]`
        # and `partial=True` leaves the old sub-categories attached — making
        # the category appear "stuck". Detect that case and clear explicitly.
        sent_categories = request.data.getlist('categories') if hasattr(request.data, 'getlist') else request.data.get('categories')
        sent_sub_categories = request.data.getlist('sub_categories') if hasattr(request.data, 'getlist') else request.data.get('sub_categories')
        if sent_categories and not sent_sub_categories:
            business.sub_categories.clear()

        # Handle operating hours update if present
        operating_hours_data = request.data.get('operating_hours')
        if operating_hours_data:
            # Parse JSON if it's a string (multipart form data)
            if isinstance(operating_hours_data, str):
                try:
                    operating_hours_data = json.loads(operating_hours_data)
                except json.JSONDecodeError:
                    operating_hours_data = None

            if operating_hours_data and isinstance(operating_hours_data, list):
                # Delete existing hours and recreate
                business.operating_hours.all().delete()
                for hours in operating_hours_data:
                    day_of_week = hours.get('day_of_week')
                    if day_of_week is not None and 0 <= day_of_week <= 6:
                        BusinessHours.objects.create(
                            business=business,
                            day_of_week=day_of_week,
                            opening_time=hours.get('opening_time'),
                            closing_time=hours.get('closing_time'),
                            is_closed=hours.get('is_closed', False),
                            is_24_hours=hours.get('is_24_hours', False)
                        )

        return Response(
            BusinessDetailSerializer(business, context={'request': request}).data,
            status=status.HTTP_200_OK
        )

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


@api_view(['GET'])
@permission_classes([AllowAny])
def business_detail_by_slug(request, slug):
    """
    Get business details by slug (SEO-friendly shareable link)

    GET /api/business/share/{slug}/
    Public endpoint - anyone can view

    Example: /api/business/share/marios-italian-kitchen/
    """
    redirected_from = None
    try:
        business = Business.objects.get(slug=slug, is_active=True)
    except Business.DoesNotExist:
        # The slug might be stale — e.g. changed via Django admin since this
        # link was shared/indexed (see SlugRedirect / Appendix B). Follow it
        # to the business's current slug rather than 404ing.
        redirect_row = SlugRedirect.objects.filter(model_name='business', old_slug=slug).first()
        if not redirect_row:
            return Response({'error': 'Business not found'}, status=status.HTTP_404_NOT_FOUND)
        try:
            business = Business.objects.get(pk=redirect_row.object_id, is_active=True)
        except Business.DoesNotExist:
            return Response({'error': 'Business not found'}, status=status.HTTP_404_NOT_FOUND)
        redirected_from = slug

    # Record unique view (only counts once per user/IP)
    record_unique_view(business, request)

    # Add distance if user provides location
    user_lat = request.query_params.get('latitude')
    user_lon = request.query_params.get('longitude')

    if user_lat and user_lon:
        try:
            businesses_with_distance = add_distance_to_businesses(
                [business],
                float(user_lat),
                float(user_lon)
            )
            business = businesses_with_distance[0]
        except (ValueError, TypeError):
            pass

    serializer = BusinessDetailSerializer(business, context={'request': request})
    data = serializer.data
    if redirected_from:
        data['redirected_from'] = redirected_from
    return Response(data, status=status.HTTP_200_OK)


@api_view(['GET'])
@permission_classes([AllowAny])
def get_listing_by_slug(request, slug):
    """
    Get a single product/service listing with its business context —
    backs the public /product/:slug page, which has no business slug of
    its own in the URL.

    GET /api/business/listing/{slug}/
    """
    redirected_from = None
    try:
        listing = Service.objects.select_related('business', 'category').get(slug=slug, is_active=True)
    except Service.DoesNotExist:
        # See business_detail_by_slug — same stale-slug fallback (Appendix B).
        redirect_row = SlugRedirect.objects.filter(model_name='service', old_slug=slug).first()
        if not redirect_row:
            return Response({'error': 'Listing not found'}, status=status.HTTP_404_NOT_FOUND)
        try:
            listing = Service.objects.select_related('business', 'category').get(pk=redirect_row.object_id, is_active=True)
        except Service.DoesNotExist:
            return Response({'error': 'Listing not found'}, status=status.HTTP_404_NOT_FOUND)
        redirected_from = slug

    data = ListingDetailSerializer(listing, context={'request': request}).data
    if redirected_from:
        data['redirected_from'] = redirected_from
    return Response(data, status=status.HTTP_200_OK)


@api_view(['GET'])
@permission_classes([AllowAny])
def list_offers(request):
    """
    List currently-live offers, paginated. Backs the public Offers page.

    GET /api/business/offers/
    Query params:
      - q: search offer title / business title
      - category_slug: filter by the business's category
    """
    now = timezone.now()
    offers = Offer.objects.select_related('business', 'listing').filter(
        is_active=True, start_at__lte=now, end_at__gte=now, business__is_active=True
    )

    query = request.GET.get('q', '').strip()
    if query:
        offers = offers.filter(
            Q(title__icontains=query) | Q(business__title__icontains=query)
        )

    category_slug = request.GET.get('category_slug', '').strip()
    if category_slug:
        offers = offers.filter(
            Q(business__categories__slug=category_slug) | Q(business__sub_categories__category__slug=category_slug)
        ).distinct()

    offers = offers.order_by('-is_featured', 'end_at')

    paginator = BusinessPagination()
    paginated_offers = paginator.paginate_queryset(offers, request)
    serializer = OfferListSerializer(paginated_offers, many=True, context={'request': request})

    # Every offer in this response is genuinely rendered on the public
    # Offers page — log a real impression for the featured ones against
    # whichever active featured_offer campaign explains it.
    client_ip = get_client_ip(request)
    for o in paginated_offers:
        if o.is_featured:
            log_campaign_event(offer=o, event_type='impression', session_id=client_ip, placement_type='featured_offer')

    return paginator.get_paginated_response({'offers': serializer.data})


@api_view(['GET'])
@permission_classes([AllowAny])
def suggested_businesses(request):
    """
    "Businesses you might like" — powers both the Business Profile page's
    "Similar businesses" widget and Home's "Suggested for you" section.

    GET /api/business/suggested/?business=<id>   — category-based, works for anyone
    GET /api/business/suggested/                 — for a logged-in user, personalized
                                                     from their LeadEvent history (the
                                                     businesses they've actually called,
                                                     messaged, or clicked through to);
                                                     for a guest, falls back to featured.
    """
    ref_business = None
    ref_business_id = request.GET.get('business')
    if ref_business_id:
        ref_business = Business.objects.filter(pk=ref_business_id).first()

    businesses, basis = get_suggested_businesses(user=request.user, reference_business=ref_business, limit=12)
    serializer = BusinessListSerializer(businesses, many=True, context={'request': request})
    return Response({'basis': basis, 'businesses': serializer.data})


@api_view(['POST'])
@permission_classes([AllowAny])
def newsletter_subscribe(request):
    """
    Footer newsletter signup — works for guests and logged-in users alike.

    POST /api/business/newsletter/subscribe/
    Body: { "email": "ada@example.com" }
    """
    serializer = NewsletterSubscriberSerializer(data=request.data)
    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    email = serializer.validated_data['email']
    user = request.user if request.user.is_authenticated else None

    subscriber, created = NewsletterSubscriber.objects.get_or_create(
        email=email, defaults={'user': user, 'is_active': True}
    )
    if not created and not subscriber.is_active:
        subscriber.is_active = True
        subscriber.unsubscribed_at = None
        if user:
            subscriber.user = user
        subscriber.save(update_fields=['is_active', 'unsubscribed_at', 'user'])
    elif not created and subscriber.is_active:
        return Response({'message': "You're already subscribed."}, status=status.HTTP_200_OK)

    return Response({'message': "You're subscribed! Look out for weekly picks in your inbox."}, status=status.HTTP_201_CREATED)


@api_view(['GET'])
@permission_classes([AllowAny])
def newsletter_unsubscribe(request, token):
    """
    One-click unsubscribe link, embedded in every digest email.

    GET /api/business/newsletter/unsubscribe/<token>/
    """
    subscriber = NewsletterSubscriber.objects.filter(unsubscribe_token=token).first()
    if not subscriber:
        return Response({'error': 'Invalid or expired unsubscribe link.'}, status=status.HTTP_404_NOT_FOUND)

    if subscriber.is_active:
        subscriber.is_active = False
        subscriber.unsubscribed_at = timezone.now()
        subscriber.save(update_fields=['is_active', 'unsubscribed_at'])

    return Response({'message': "You've been unsubscribed from the Discovr newsletter."}, status=status.HTTP_200_OK)


@api_view(['GET'])
@permission_classes([AllowAny])
def platform_status(request):
    """
    GET /api/business/platform-status/
    Public — every frontend (consumer, business, and their unauthenticated
    visitors) needs to check maintenance mode and signup/business-creation
    availability before a user even logs in, so this can't sit behind
    IsAdminUser like the rest of PlatformSettings. support_email/phone are
    included too since those are meant to be shown to end users as the
    platform's public support contact, not admin-only detail.
    """
    settings_obj = PlatformSettings.load()
    return Response({
        'maintenance_mode': settings_obj.maintenance_mode,
        'maintenance_message': settings_obj.maintenance_message,
        'allow_new_signups': settings_obj.allow_new_signups,
        'allow_new_businesses': settings_obj.allow_new_businesses,
        'support_email': settings_obj.support_email,
        'support_phone': settings_obj.support_phone,
    }, status=status.HTTP_200_OK)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def report_business(request, business_id):
    """
    "Report business" — flags a business for admin review (spam, closed,
    inappropriate, duplicate, other). Backs the flag icon on Business Profile.

    POST /api/business/<business_id>/report/
    Body: { "reason": "spam", "message": "..." (optional) }
    """
    try:
        business = Business.objects.get(id=business_id)
    except Business.DoesNotExist:
        return Response({'error': 'Business not found'}, status=status.HTTP_404_NOT_FOUND)

    serializer = ReportCreateSerializer(data=request.data)
    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    serializer.save(business=business, reporter=request.user)
    return Response({'message': "Thanks — we've received your report and will take a look."}, status=status.HTTP_201_CREATED)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_business(request):
    """
    Create a new business listing with optional images and operating hours

    POST /api/business/create/
    Headers: Authorization: Bearer <token>
    Body: Business data (multipart/form-data supported for images)

    Fields:
        - title, description, sub_categories, address, phone_number, etc.
        - images: Multiple image files (optional)
        - operating_hours: Array of operating hours (optional)
          Format: [
            {
              "day_of_week": 0,  # 0=Monday, 6=Sunday
              "opening_time": "09:00",
              "closing_time": "18:00",
              "is_closed": false,
              "is_24_hours": false
            },
            ...
          ]
    """
    import json

    if not PlatformSettings.load().allow_new_businesses:
        return Response({
            'error': 'New business registrations are temporarily disabled. Please check back shortly.'
        }, status=status.HTTP_403_FORBIDDEN)

    # Check if user has already created 2 businesses
    user_business_count = Business.objects.filter(owner=request.user).count()
    if user_business_count >= 2:
        return Response({
            'error': 'You can only create a maximum of 2 businesses per account.'
        }, status=status.HTTP_400_BAD_REQUEST)

    # A business with no photo at all falls back to a generic stock image on
    # the public profile — require at least one on creation so that never
    # happens. Owners can still add/replace photos freely after creation.
    if not (request.FILES.get('logo') or request.FILES.get('profile_image') or request.FILES.getlist('images')):
        return Response({
            'error': 'Add at least one photo of your business to continue.'
        }, status=status.HTTP_400_BAD_REQUEST)

    serializer = BusinessCreateSerializer(data=request.data)

    if serializer.is_valid():
        business = serializer.save(owner=request.user)

        # Auto-verify business on creation (no admin approval needed)
        business.is_verified = True
        business.save()

        # Handle profile image upload if present
        profile_image = request.FILES.get('profile_image')
        if profile_image:
            business.profile_image = profile_image
            business.save()

        # Handle image uploads if present
        images = request.FILES.getlist('images')
        for i, image in enumerate(images):
            BusinessImage.objects.create(
                business=business,
                image=image,
                is_main=(i == 0)  # First image is main
            )

        # Handle operating hours if present
        operating_hours_data = request.data.get('operating_hours')
        if operating_hours_data:
            # Parse JSON if it's a string (multipart form data)
            if isinstance(operating_hours_data, str):
                try:
                    operating_hours_data = json.loads(operating_hours_data)
                except json.JSONDecodeError:
                    operating_hours_data = None

            if operating_hours_data and isinstance(operating_hours_data, list):
                for hours in operating_hours_data:
                    day_of_week = hours.get('day_of_week')
                    if day_of_week is not None and 0 <= day_of_week <= 6:
                        BusinessHours.objects.create(
                            business=business,
                            day_of_week=day_of_week,
                            opening_time=hours.get('opening_time'),
                            closing_time=hours.get('closing_time'),
                            is_closed=hours.get('is_closed', False),
                            is_24_hours=hours.get('is_24_hours', False)
                        )

        # Send email notification to the business owner
        send_business_live_email(
            email=request.user.email,
            first_name=request.user.first_name or 'User',
            business_title=business.title
        )

        # Create in-app notification
        notification = create_notification(
            user=request.user,
            notification_type='business_update',
            title='Your Business is Live!',
            message=f'Congratulations! Your business "{business.title}" is now live on our platform.',
            business=business,
            action_url=f'/business/{business.slug}'
        )

        # Send push notification
        send_push_notification(
            user=request.user,
            title='Your Business is Live!',
            body=f'"{business.title}" is now visible to customers.',
            data={
                'notification_type': 'business_update',
                'business_id': str(business.id),
                'action': 'business_created'
            }
        )

        return Response(
            BusinessDetailSerializer(business, context={'request': request}).data,
            status=status.HTTP_201_CREATED
        )

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


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def add_business_images(request, business_id):
    """
    Add images to an existing business

    POST /api/business/{business_id}/images/
    Headers: Authorization: Bearer <token>
    Body: multipart/form-data with 'images' field
    """
    try:
        business = Business.objects.get(id=business_id)
    except Business.DoesNotExist:
        return Response({
            'error': 'Business not found'
        }, status=status.HTTP_404_NOT_FOUND)

    # Check ownership
    if business.owner != request.user:
        return Response({
            'error': 'You do not have permission to modify this business'
        }, status=status.HTTP_403_FORBIDDEN)

    images = request.FILES.getlist('images')
    if not images:
        # Also check for single 'image' field
        image = request.FILES.get('image')
        if image:
            images = [image]

    if not images:
        return Response({
            'error': 'No images provided'
        }, status=status.HTTP_400_BAD_REQUEST)

    created_images = []
    has_main = business.images.filter(is_main=True).exists()

    for i, image in enumerate(images):
        img = BusinessImage.objects.create(
            business=business,
            image=image,
            is_main=(not has_main and i == 0)  # First image is main if no main exists
        )
        created_images.append(img)

    return Response({
        'message': f'{len(created_images)} image(s) uploaded successfully',
        'images': BusinessImageSerializer(created_images, many=True, context={'request': request}).data
    }, status=status.HTTP_201_CREATED)


@api_view(['GET', 'POST'])
@permission_classes([AllowAny])
def search_businesses(request):
    """
    Search businesses with multiple filters
    User can search by business name, category name, section type, or general query
    Supports multiple filters at once

    GET /api/business/search/?query=carpenter&latitude=31.5204&longitude=74.3587
    GET /api/business/search/?category=9&sub_category=1
    POST /api/business/search/
    Body:
    {
        "query": "carpenter",              # General search (optional)
        "business_name": "Ahmad",          # Business name search (optional)
        "category_name": "Carpenter",      # Category name search (optional)
        "category": 9,                     # Category ID filter (optional)
        "sub_category": 1,                 # Sub-category ID filter (optional)
        "section": "home_services",        # Section: top_rated, nearby, home_services, recent (optional)
        "latitude": 31.5204,               # Optional for distance
        "longitude": 74.3587,              # Optional for distance
        "page": 1                          # Optional
    }
    """
    # Get all search parameters from query params (GET) or body (POST)
    if request.method == 'GET':
        query = request.query_params.get('query', '').strip()
        business_name = request.query_params.get('business_name', '').strip()
        category_name = request.query_params.get('category_name', '').strip()
        category_id = request.query_params.get('category')
        category_slug = request.query_params.get('category_slug', '').strip()
        sub_category_id = request.query_params.get('sub_category')
        section = request.query_params.get('section', '').strip().lower()
        user_lat = request.query_params.get('latitude')
        user_lon = request.query_params.get('longitude')
    else:
        query = request.data.get('query', '').strip()
        business_name = request.data.get('business_name', '').strip()
        category_name = request.data.get('category_name', '').strip()
        category_id = request.data.get('category')
        category_slug = (request.data.get('category_slug') or '').strip()
        sub_category_id = request.data.get('sub_category')
        section = request.data.get('section', '').strip().lower()
        user_lat = request.data.get('latitude')
        user_lon = request.data.get('longitude')

    # At least one search/filter parameter is required
    if not any([query, business_name, category_name, category_id, category_slug, sub_category_id, section]):
        return Response({
            'error': 'At least one search parameter is required (query, business_name, category_name, category, category_slug, sub_category, or section)'
        }, status=status.HTTP_400_BAD_REQUEST)

    # Start with all active businesses
    businesses = Business.objects.filter(is_active=True)

    # Filter by category ID (directly linked or through sub-categories)
    if category_id:
        try:
            cat_id = int(category_id)
            businesses = businesses.filter(
                Q(categories__id=cat_id) | Q(sub_categories__category_id=cat_id)
            ).distinct()
        except (ValueError, TypeError):
            pass
    elif category_slug:
        businesses = businesses.filter(
            Q(categories__slug=category_slug) | Q(sub_categories__category__slug=category_slug)
        ).distinct()

    # Filter by sub-category ID
    if sub_category_id:
        try:
            businesses = businesses.filter(sub_categories__id=int(sub_category_id)).distinct()
        except (ValueError, TypeError):
            pass

    # Apply text search filters based on provided parameters
    search_filters = Q()

    # General query - search across title, description, and categories
    if query:
        search_filters |= (
            Q(title__icontains=query) |
            Q(description__icontains=query) |
            Q(categories__name__icontains=query) |
            Q(sub_categories__category__name__icontains=query) |
            Q(sub_categories__name__icontains=query)
        )

    # Business name filter
    if business_name:
        search_filters |= Q(title__icontains=business_name)

    # Category name filter
    if category_name:
        search_filters |= (
            Q(categories__name__icontains=category_name) |
            Q(sub_categories__category__name__icontains=category_name) |
            Q(sub_categories__name__icontains=category_name)
        )

    # Apply search filters if any
    if search_filters:
        businesses = businesses.filter(search_filters).distinct()

    # Apply section filter
    if section:
        if section == 'top_rated':
            # Top rated businesses (minimum 3 reviews)
            businesses = businesses.annotate(
                review_count=Count('reviews')
            ).filter(review_count__gte=3).order_by('-average_rating')

        elif section == 'home_services':
            # Businesses providing home service
            businesses = businesses.filter(provides_home_service=True)

        elif section == 'recent':
            # Recently added businesses
            businesses = businesses.order_by('-created_at')

        elif section == 'nearby':
            # Will be sorted by distance after adding distance
            pass

        else:
            return Response({
                'error': 'Invalid section. Valid options: top_rated, nearby, home_services, recent'
            }, status=status.HTTP_400_BAD_REQUEST)

    # Order by rating if not already ordered by section
    if section not in ['top_rated', 'recent']:
        businesses = businesses.order_by('-average_rating')

    # Add distance to all businesses if coordinates provided
    if user_lat and user_lon:
        try:
            user_lat = float(user_lat)
            user_lon = float(user_lon)
            businesses_with_distance = add_distance_to_businesses(businesses, user_lat, user_lon)
            # Sort by distance if section is 'nearby'
            if section == 'nearby':
                businesses_with_distance.sort(key=lambda x: x.distance if hasattr(x, 'distance') else float('inf'))
        except (ValueError, TypeError):
            businesses_with_distance = list(businesses)
    else:
        businesses_with_distance = list(businesses)

    # Sponsored Search — an active Campaign boosts its business to the top
    # of results that already match this search (PRD: "paid visibility for
    # relevant searches", admin-priced via the existing Campaign approval
    # flow rather than a real-time auction — there's no bidding system).
    # Capped at 2 slots so paid placement can't drown organic results, and
    # only ever reorders businesses already in this result set — sponsorship
    # never fabricates a match that wouldn't otherwise be relevant.
    sponsored_ids = set(
        Campaign.objects.filter(
            status='active', business_id__in=[b.id for b in businesses_with_distance]
        ).values_list('business_id', flat=True)
    )
    if sponsored_ids:
        sponsored = [b for b in businesses_with_distance if b.id in sponsored_ids][:2]
        promoted_ids = {b.id for b in sponsored}
        for b in sponsored:
            b.is_sponsored = True
        businesses_with_distance = sponsored + [b for b in businesses_with_distance if b.id not in promoted_ids]

    # Paginate
    paginator = BusinessPagination()
    paginated_businesses = paginator.paginate_queryset(businesses_with_distance, request)
    serializer = BusinessListSerializer(paginated_businesses, many=True, context={'request': request})

    # Log a real impression for each sponsored result that actually made it
    # onto the page being returned (not just tagged pre-pagination) — see
    # log_campaign_event.
    client_ip = get_client_ip(request)
    for b in paginated_businesses:
        if getattr(b, 'is_sponsored', False):
            log_campaign_event(business=b, event_type='impression', session_id=client_ip)

    # Build response with applied filters info
    applied_filters = {}
    if query:
        applied_filters['query'] = query
    if business_name:
        applied_filters['business_name'] = business_name
    if category_name:
        applied_filters['category_name'] = category_name
    if category_id:
        applied_filters['category'] = category_id
    if sub_category_id:
        applied_filters['sub_category'] = sub_category_id
    if section:
        applied_filters['section'] = section

    if query:
        SearchQuery.objects.create(
            query=query,
            result_count=len(businesses_with_distance),
            user=request.user if request.user.is_authenticated else None,
        )

    return paginator.get_paginated_response({
        'applied_filters': applied_filters,
        'businesses': serializer.data
    })


@api_view(['GET'])
@permission_classes([AllowAny])
def explore_home(request):
    """
    GET /api/business/explore/?city=<optional>
    Real data for the homepage's "Explore searches in popular cities" section
    (previously fully hardcoded mock data). Everything here is derived from
    actual activity, not fabricated:
      - cities: distinct Business.city values, case-normalized and ranked by
        how many businesses list that city (city is free-text with no
        dedicated model, so this also filters obviously-garbage long values
        like a full street address someone typed into the city field).
      - top_searches / trending_searches: real terms from SearchQuery (see
        search_businesses above, which is what populates it) — "top" is
        all-time by volume, "trending" is the last 14 days, falling back to
        all-time if too little recent activity exists to be meaningful.
        There's no per-city tie on SearchQuery today, so these are
        site-wide rather than scoped to the selected city tab.
      - top_categories: real categories ranked by business count, scoped to
        `city` when provided — this is what the frontend re-fetches when the
        active city tab changes, replacing the old fabricated "seasonal
        searches" column (there's no seasonal signal anywhere to build that
        from honestly).
    """
    raw_cities = Business.objects.exclude(city='').values_list('city', flat=True)
    city_counts = Counter()
    for raw in raw_cities:
        name = raw.strip()
        if not name or len(name) > 24:
            continue
        city_counts[name.title()] += 1
    cities = [{'name': name, 'count': count} for name, count in city_counts.most_common(12)]

    top_searches = list(
        SearchQuery.objects.values('query').annotate(n=Count('id')).order_by('-n')[:6]
    )
    recent_cutoff = timezone.now() - timedelta(days=14)
    trending_searches = list(
        SearchQuery.objects.filter(created_at__gte=recent_cutoff)
        .values('query').annotate(n=Count('id')).order_by('-n')[:6]
    )
    if len(trending_searches) < 3:
        trending_searches = top_searches

    city_param = request.query_params.get('city', '').strip()
    category_qs = Business.objects.filter(is_active=True)
    if city_param:
        category_qs = category_qs.filter(city__icontains=city_param)
    top_categories = list(
        category_qs.filter(categories__isnull=False)
        .values('categories__name', 'categories__slug').annotate(n=Count('id', distinct=True)).order_by('-n')[:6]
    )

    return Response({
        'cities': cities,
        'top_searches': [row['query'] for row in top_searches],
        'trending_searches': [row['query'] for row in trending_searches],
        'top_categories': [{'name': row['categories__name'], 'slug': row['categories__slug']} for row in top_categories],
    })


@api_view(['POST'])
@permission_classes([IsAuthenticated])
@throttle_classes([ReviewCreateRateThrottle])
def create_review(request):
    """
    Create a review for a business

    POST /api/business/review/create/
    Headers: Authorization: Bearer <token>
    Body:
    {
        "business": 1,
        "rating": 5,
        "message": "Excellent service!"
    }
    """
    serializer = ReviewCreateSerializer(data=request.data, context={'request': request})

    if serializer.is_valid():
        review = serializer.save(user=request.user)

        # Get the business and its owner
        business = review.business
        business_owner = business.owner

        # Don't send notification if user is reviewing their own business
        if business_owner != request.user:
            # Get reviewer's name
            reviewer_name = request.user.get_full_name() or request.user.email

            # Send email notification to business owner
            send_new_review_email(
                email=business_owner.email,
                first_name=business_owner.first_name or 'Business Owner',
                business_title=business.title,
                reviewer_name=reviewer_name,
                rating=review.rating,
                review_message=review.message[:200] + '...' if len(review.message) > 200 else review.message
            )

            # Create in-app notification for business owner
            create_notification(
                user=business_owner,
                notification_type='review',
                title='New Review Received!',
                message=f'{reviewer_name} left a {review.rating}-star review on "{business.title}"',
                business=business,
                action_url=f'/business/{business.slug}'
            )

            # Send push notification to business owner
            send_push_notification(
                user=business_owner,
                title='New Review Received!',
                body=f'{reviewer_name} left a {review.rating}-star review on "{business.title}"',
                data={
                    'notification_type': 'review',
                    'business_id': str(business.id),
                    'review_id': str(review.id),
                    'action': 'new_review'
                }
            )

        return Response(
            ReviewSerializer(review).data,
            status=status.HTTP_201_CREATED
        )

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


@api_view(['POST'])
@permission_classes([AllowAny])
@throttle_classes([LeadEventRateThrottle])
def track_lead_event(request, business_id):
    """
    Record a tracked customer-contact action (WhatsApp/call/website/
    directions/booking/buy click) — works for guests as well as logged-in
    users, matching how BusinessView tracks anonymous page views.

    POST /api/business/<business_id>/lead/
    Body:
    {
        "event_type": "whatsapp_click",
        "source": "profile",
        "listing": 12,       # optional
        "post": 7,           # optional
        "session_id": "..."  # optional, for anonymous attribution
    }
    """
    business = get_object_or_404(Business, id=business_id, is_active=True)

    serializer = LeadEventCreateSerializer(data=request.data, context={'business': business})
    if serializer.is_valid():
        lead_event = serializer.save(
            business=business,
            user=request.user if request.user.is_authenticated else None,
            ip_address=get_client_ip(request),
        )
        log_campaign_event(
            business=business, event_type='click',
            session_id=lead_event.session_id or get_client_ip(request),
        )
        create_notification(
            user=business.owner,
            notification_type='new_lead',
            title='New Lead',
            message=f'{lead_event.get_event_type_display()} on "{business.title}".',
            business=business,
            action_url='/leads',
        )
        return Response({'success': True}, status=status.HTTP_201_CREATED)

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


@api_view(['GET'])
@permission_classes([AllowAny])
def get_categories(request):
    """
    Get all active categories with their sub-categories

    GET /api/business/categories/
    """
    categories = Category.objects.filter(is_active=True).prefetch_related('sub_categories')
    serializer = CategorySerializer(categories, many=True, context={'request': request})
    return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(['GET'])
@permission_classes([AllowAny])
def list_businesses(request):
    """
    List all businesses with optional filters

    GET /api/business/businesses/
    Query Parameters:
        - is_featured: true/false - Filter featured businesses
        - is_verified: true/false - Filter verified businesses
        - provides_home_service: true/false - Filter home service businesses
        - category_id: int - Filter by category
        - sub_category_id: int - Filter by sub-category
        - city: string - Filter by city
        - min_rating: float - Minimum average rating
        - latitude: float - User latitude for distance calculation
        - longitude: float - User longitude for distance calculation
        - page: int - Page number
        - page_size: int - Items per page (default 20, max 100)
        - ordering: string - Order by field (e.g., -average_rating, -created_at, title)
    """
    businesses = Business.objects.filter(is_active=True).select_related(
        'owner'
    ).prefetch_related(
        'categories',
        'sub_categories',
        'sub_categories__category',
        'images',
        'operating_hours',
    )

    # Filter by is_featured
    is_featured = request.query_params.get('is_featured')
    if is_featured is not None:
        businesses = businesses.filter(
            is_featured=is_featured.lower() in ('true', '1', 'yes')
        )

    # Filter by is_verified
    is_verified = request.query_params.get('is_verified')
    if is_verified is not None:
        businesses = businesses.filter(is_verified=is_verified.lower() == 'true')

    # Filter by provides_home_service
    provides_home_service = request.query_params.get('provides_home_service')
    if provides_home_service is not None:
        businesses = businesses.filter(provides_home_service=provides_home_service.lower() == 'true')

    # Filter by category (accept 'category_id', 'category', or 'category_slug')
    category_id = request.query_params.get('category_id') or request.query_params.get('category')
    category_slug = request.query_params.get('category_slug')
    if category_id:
        try:
            cat_id = int(category_id)
            businesses = businesses.filter(
                Q(categories__id=cat_id) | Q(sub_categories__category_id=cat_id)
            ).distinct()
        except (ValueError, TypeError):
            pass
    elif category_slug:
        businesses = businesses.filter(
            Q(categories__slug=category_slug) | Q(sub_categories__category__slug=category_slug)
        ).distinct()

    # Filter by sub-category (accept 'sub_category_id', 'sub_category', or 'sub_category_slug')
    sub_category_id = request.query_params.get('sub_category_id') or request.query_params.get('sub_category')
    sub_category_slug = request.query_params.get('sub_category_slug')
    if sub_category_id:
        try:
            businesses = businesses.filter(sub_categories__id=int(sub_category_id)).distinct()
        except (ValueError, TypeError):
            pass
    elif sub_category_slug:
        businesses = businesses.filter(sub_categories__slug=sub_category_slug).distinct()

    # Filter by city
    city = request.query_params.get('city')
    if city:
        businesses = businesses.filter(city__icontains=city)

    # Filter by minimum rating
    min_rating = request.query_params.get('min_rating')
    if min_rating:
        try:
            businesses = businesses.filter(average_rating__gte=float(min_rating))
        except ValueError:
            pass

    # Ordering
    ordering = request.query_params.get('ordering', '-created_at')
    valid_orderings = ['title', '-title', 'average_rating', '-average_rating',
                       'created_at', '-created_at', 'total_reviews', '-total_reviews']
    if ordering in valid_orderings:
        businesses = businesses.order_by(ordering)
    else:
        businesses = businesses.order_by('-created_at')

    # Paginate FIRST (before distance calculation to avoid loading all businesses into memory)
    paginator = BusinessPagination()
    paginated_businesses = paginator.paginate_queryset(businesses, request)

    # Add distance only to paginated results (much faster - only 10-20 items)
    user_lat = request.query_params.get('latitude')
    user_lon = request.query_params.get('longitude')
    if user_lat and user_lon:
        try:
            paginated_businesses = add_distance_to_businesses(paginated_businesses, float(user_lat), float(user_lon))
        except (ValueError, TypeError):
            pass

    serializer = BusinessListSerializer(paginated_businesses, many=True, context={'request': request})

    # A featured-only query is genuinely showing these businesses in a
    # "Featured" placement (e.g. Home's featured section) — log a real
    # impression against whichever active featured_business campaign
    # explains it. Only when the caller actually asked for featured results,
    # not on every generic list call.
    if is_featured is not None and is_featured.lower() in ('true', '1', 'yes'):
        client_ip = get_client_ip(request)
        for b in paginated_businesses:
            log_campaign_event(business=b, event_type='impression', session_id=client_ip, placement_type='featured_business')

    return paginator.get_paginated_response({
        'businesses': serializer.data
    })


@api_view(['GET'])
@permission_classes([AllowAny])
def get_sub_categories(request, category_id=None):
    """
    Get all active sub-categories, optionally filtered by category

    GET /api/business/sub-categories/
    GET /api/business/sub-categories/?category_id=1
    GET /api/business/sub-categories/?category=1
    """
    if category_id:
        sub_categories = SubCategory.objects.filter(is_active=True, category_id=category_id)
    else:
        # Accept both 'category_id' and 'category' query params
        category_id_param = request.GET.get('category_id') or request.GET.get('category')
        if category_id_param:
            sub_categories = SubCategory.objects.filter(is_active=True, category_id=category_id_param)
        else:
            sub_categories = SubCategory.objects.filter(is_active=True)

    serializer = SubCategorySerializer(sub_categories, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(['GET', 'POST'])
@permission_classes([AllowAny])
def sub_category_businesses_view(request, sub_category_id):
    """
    Get all businesses for a specific sub-category

    GET /api/business/sub-category/{sub_category_id}/?latitude=31.5204&longitude=74.3587
    POST /api/business/sub-category/{sub_category_id}/
    Body:
    {
        "latitude": 31.5204,
        "longitude": 74.3587,
        "page": 1
    }
    """
    # Get latitude/longitude from query params (GET) or body (POST)
    if request.method == 'GET':
        user_lat = request.query_params.get('latitude')
        user_lon = request.query_params.get('longitude')
    else:
        user_lat = request.data.get('latitude')
        user_lon = request.data.get('longitude')

    # Check if sub-category exists first
    try:
        sub_category = SubCategory.objects.get(id=sub_category_id, is_active=True)
    except SubCategory.DoesNotExist:
        return Response({
            'error': 'Sub-category not found'
        }, status=status.HTTP_404_NOT_FOUND)

    # Get businesses in this sub-category
    businesses = Business.objects.filter(
        sub_categories__id=sub_category_id,
        is_active=True
    ).distinct()

    # Add distance if coordinates provided
    if user_lat and user_lon:
        try:
            user_lat = float(user_lat)
            user_lon = float(user_lon)
            businesses = add_distance_to_businesses(businesses, user_lat, user_lon)
        except (ValueError, TypeError):
            pass  # If invalid, just skip distance calculation

    # Paginate results
    paginator = BusinessPagination()
    paginated_businesses = paginator.paginate_queryset(businesses, request)
    serializer = BusinessListSerializer(paginated_businesses, many=True, context={'request': request})

    return paginator.get_paginated_response({
        'sub_category': SubCategorySerializer(sub_category).data,
        'businesses': serializer.data
    })


def business_detail_html(request, slug):
    """
    Render business detail page as HTML (for direct hosting)

    GET /business/{slug}
    Public page - anyone can view

    Example: /business/marios-italian-kitchen
    """
    business = get_object_or_404(Business, slug=slug, is_active=True)

    # Record unique view (only counts once per user/IP)
    record_unique_view(business, request)

    return render(request, 'business/detail.html', {
        'business': business,
        # The canonical, human-facing URL — this template is served to bots
        # (see user-app's vite.config.js bot-detection proxy) as a crawlable
        # snapshot, not the page a person is meant to browse, so every
        # outbound link/share action/canonical tag points back at the real
        # SPA rather than this backend URL.
        'frontend_url': settings.FRONTEND_URL.rstrip('/'),
    })


def product_detail_html(request, slug):
    """
    Server-rendered snapshot of a product/service listing for crawlers and
    link-preview bots (WhatsApp, Facebook, Twitter, Googlebot, ...) — see
    business_detail_html's docstring for why this exists. Routed to by
    user-app's Vite bot-detection middleware for /product/:slug.
    """
    listing = get_object_or_404(Service, slug=slug, is_active=True)
    return render(request, 'business/product_detail.html', {
        'listing': listing,
        'business': listing.business,
        'frontend_url': settings.FRONTEND_URL.rstrip('/'),
    })


def category_detail_html(request, slug):
    """Server-rendered snapshot of a category's business listing — see business_detail_html's docstring."""
    category = get_object_or_404(Category, slug=slug, is_active=True)
    businesses = Business.objects.filter(
        Q(categories=category) | Q(sub_categories__category=category),
        is_active=True,
    ).distinct().order_by('-average_rating', '-total_reviews')[:24]
    return render(request, 'business/category_detail.html', {
        'category': category,
        'businesses': businesses,
        'frontend_url': settings.FRONTEND_URL.rstrip('/'),
    })


# ==================== Feedback API ====================

@api_view(['POST'])
@permission_classes([AllowAny])
def submit_feedback(request):
    """
    Submit user feedback

    POST /api/business/feedback/
    Body:
    {
        "title": "Feedback title",
        "message": "Detailed feedback message",
        "category": "general",  # general, bug_report, feature_request, improvement, other
        "rating": 5,  # Optional, 1-5
        "device_info": "App version 1.0.0, Android 12"  # Optional
    }
    """
    serializer = FeedbackCreateSerializer(data=request.data)

    if serializer.is_valid():
        # Set user if authenticated
        user = request.user if request.user.is_authenticated else None
        feedback = serializer.save(user=user)

        return Response({
            'success': True,
            'message': 'Thank you! Your feedback has been submitted successfully.',
            'data': FeedbackSerializer(feedback).data
        }, status=status.HTTP_201_CREATED)

    return Response({
        'success': False,
        'message': 'Failed to submit feedback',
        'errors': serializer.errors
    }, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def feedback_history(request):
    """
    Get feedback history for the current user

    GET /api/business/feedback/history/
    Headers: Authorization: Bearer <token>
    """
    feedbacks = Feedback.objects.filter(user=request.user).order_by('-created_at')

    return Response({
        'success': True,
        'data': FeedbackSerializer(feedbacks, many=True).data
    }, status=status.HTTP_200_OK)


# ==================== Contact / Sales Inquiry API ====================

@api_view(['POST'])
@permission_classes([AllowAny])
def submit_contact_request(request):
    """
    Submit a sales/support inquiry — public (pricing page "Talk to us") or
    from a logged-in business owner requesting a plan upgrade.

    POST /api/business/contact/
    Body:
    {
        "full_name": "Ada Obi",
        "email": "ada@example.com",
        "phone_number": "+234...",   # optional
        "message": "...",
        "source": "pricing_enterprise",  # pricing_enterprise, pricing_upgrade, other
        "business": 12  # optional — the business this inquiry is about
    }
    """
    serializer = ContactRequestCreateSerializer(data=request.data)

    if serializer.is_valid():
        serializer.save()
        return Response({
            'message': "Thanks — we've received your message and will be in touch shortly."
        }, status=status.HTTP_201_CREATED)

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