"""
Business Views

This module contains all API views for business-related functionality:
1. Business profile management
2. Influencer matching
3. Search history
"""

from rest_framework import viewsets, status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
import logging

from .models import BusinessProfile, BusinessSearch, CollaborationRequest
from .serializers import (
    BusinessProfileSerializer,
    BusinessMatchingRequestSerializer,
    InfluencerMatchSerializer,
    BusinessSearchSerializer,
    BusinessSearchListSerializer,
    CollaborationRequestSerializer,
    CollaborationRequestCreateSerializer,
)
from .services import MatchingService
from core.services import MLClient
from influencers.models import InfluencerProfile
from influencers.serializers import InfluencerProfileListSerializer

logger = logging.getLogger(__name__)


class BusinessProfileViewSet(viewsets.ModelViewSet):
    """
    ViewSet for managing business profiles

    Endpoints:
    - GET /api/businesses/profiles/ - List all business profiles
    - POST /api/businesses/profiles/ - Create business profile
    - GET /api/businesses/profiles/{id}/ - Get specific profile
    - PUT /api/businesses/profiles/{id}/ - Update profile
    - DELETE /api/businesses/profiles/{id}/ - Delete profile
    """
    queryset = BusinessProfile.objects.all()
    serializer_class = BusinessProfileSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        """Filter to only show current user's profile"""
        if self.request.user.is_business:
            return BusinessProfile.objects.filter(user=self.request.user)
        return BusinessProfile.objects.none()

    def perform_create(self, serializer):
        """Automatically set user when creating profile"""
        serializer.save(user=self.request.user)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def match_influencers(request):
    """
    Match influencers to business requirements using ML service.

    POST /api/businesses/match/

    Request body:
        {
            "business_description": "We sell organic skincare products...",
            "budget_min": 1000,
            "budget_max": 5000,
            "top_k": 10,  # optional, default 10
            "audience_countries": ["Pakistan"],  # optional
            "audience_cities": ["Karachi", "Lahore"]  # optional
        }

    Returns:
        {
            "matches": [
                {
                    "profile": {...},
                    "match_score": 0.95,
                    "niche_similarity": 0.92,
                    "budget_fit": 0.98,
                    "location_match_score": 0.85,
                    "price_info": {...}
                },
                ...
            ],
            "business_requirements": {
                "niche_probabilities": {...},
                "top_niche": "Beauty"
            }
        }
    """
    # Validate request
    serializer = BusinessMatchingRequestSerializer(data=request.data)
    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    data = serializer.validated_data

    # Step 1: Get business requirements from ML service
    ml_client = MLClient()
    business_prediction = ml_client.predict_business_requirements(
        business_description=data['business_description'],
        budget_min=data['budget_min'],
        budget_max=data['budget_max']
    )

    if not business_prediction:
        return Response(
            {'error': 'ML service unavailable. Please try again later.'},
            status=status.HTTP_503_SERVICE_UNAVAILABLE
        )

    # Step 2: Get influencers with ML predictions
    influencers = InfluencerProfile.objects.filter(
        niche_probabilities__isnull=False,
        popularity_probabilities__isnull=False,
        data_processing_status='COMPLETED'
    )

    if not influencers.exists():
        return Response(
            {'error': 'No influencers with ML predictions found. Please wait for data processing.'},
            status=status.HTTP_404_NOT_FOUND
        )

    audience_countries = data.get('audience_countries') or []
    audience_cities = data.get('audience_cities') or []

    # Step 3: Use MatchingService to find best matches
    matches = MatchingService.find_best_matches(
        business_description=data['business_description'],
        budget_min=data['budget_min'],
        budget_max=data['budget_max'],
        top_n=data.get('top_k', 10),
        business_prediction=business_prediction,
        audience_countries=audience_countries,
        audience_cities=audience_cities,
    )

    # Step 4: Serialize results (tier labels removed for user clarity)
    match_results = []
    for influencer, similarity in matches:
        match_results.append({
            'profile': InfluencerProfileListSerializer(influencer).data,
            'match_score': similarity['total_score'],
            'niche_similarity': similarity['niche_score'],
            'budget_fit': similarity['budget_match_score'],
            'location_match_score': similarity['location_match_score'],
            'price_info': similarity['price_info']
        })

    # Step 5: Save search to database (internal tracking only)
    search = BusinessSearch.objects.create(
        business_user=request.user,
        business_description=data['business_description'],
        budget_min=data['budget_min'],
        budget_max=data['budget_max'],
        top_k=data.get('top_k', 10),
        audience_countries=audience_countries,
        audience_cities=audience_cities,
        predicted_niche_probabilities=business_prediction['niche_probabilities'],
        predicted_popularity_probabilities=business_prediction['popularity_probabilities'],  # Internal use only
        matched_influencers=[
            {
                'influencer_id': influencer.id,
                'match_score': similarity['total_score'],
                'niche_similarity': similarity['niche_score'],
                'budget_fit': similarity['budget_match_score'],
                'location_match_score': similarity['location_match_score'],
            }
            for influencer, similarity in matches
        ]
    )

    # Step 6: Return response (tier/popularity labels removed for user clarity)
    return Response({
        'matches': match_results,
        'business_requirements': {
            'niche_probabilities': business_prediction['niche_probabilities'],
            'top_niche': business_prediction.get('processed_data', {}).get('top_niche')
        },
        'search_id': search.id
    }, status=status.HTTP_200_OK)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def search_history(request):
    """
    Get search history for the current business user.

    GET /api/businesses/search-history/

    Returns list of previous searches with match results.
    """
    searches = BusinessSearch.objects.filter(
        business_user=request.user
    ).order_by('-created_at')

    serializer = BusinessSearchListSerializer(searches, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def business_collaborations(request):
    """
    GET  — list collaboration requests sent by this business.
    POST — send a new collaboration request.
    """
    if not request.user.is_business:
        return Response({'error': 'Only business users can access this.'}, status=status.HTTP_403_FORBIDDEN)

    business_profile = getattr(request.user, 'business_profile', None)

    if request.method == 'GET':
        if not business_profile:
            return Response([])
        collabs = CollaborationRequest.objects.filter(business=business_profile)
        serializer = CollaborationRequestSerializer(collabs, many=True)
        return Response(serializer.data)

    # POST — create collaboration request
    if not business_profile:
        return Response({'error': 'Create a business profile first.'}, status=status.HTTP_400_BAD_REQUEST)

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

    influencer = serializer.validated_data['influencer']

    existing = CollaborationRequest.objects.filter(
        business=business_profile,
        influencer=influencer,
        status=CollaborationRequest.Status.PENDING,
    ).exists()
    if existing:
        return Response(
            {'error': 'You already have a pending request with this creator.'},
            status=status.HTTP_400_BAD_REQUEST,
        )

    collab = CollaborationRequest.objects.create(
        business=business_profile,
        **serializer.validated_data,
    )
    return Response(
        CollaborationRequestSerializer(collab).data,
        status=status.HTTP_201_CREATED,
    )
