import logging
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.viewsets import ViewSet
from drf_spectacular.utils import extend_schema, extend_schema_view

from igny8_core.api.permissions import IsAuthenticatedAndActive, IsEditorOrAbove
from igny8_core.api.response import success_response, error_response
from igny8_core.api.throttles import DebugScopedRateThrottle
from igny8_core.business.content.models import Content
from igny8_core.business.linking.services.linker_service import LinkerService
from igny8_core.business.billing.exceptions import InsufficientCreditsError
from igny8_core.modules.linker.serializers import (
    LinkContentSerializer,
    BatchLinkContentSerializer,
)

logger = logging.getLogger(__name__)


@extend_schema_view(
    process=extend_schema(tags=['Linker']),
    batch_process=extend_schema(tags=['Linker']),
)
class LinkerViewSet(ViewSet):
    """
    API endpoints for internal linking operations.
    Unified API Standard v1.0 compliant
    """
    permission_classes = [IsAuthenticatedAndActive, IsEditorOrAbove]
    throttle_scope = 'linker'
    throttle_classes = [DebugScopedRateThrottle]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.linker_service = LinkerService()

    @action(detail=False, methods=['post'])
    def process(self, request):
        """
        Process a single content item for internal linking.
        
        POST /api/v1/linker/process/
        {
            "content_id": 123
        }
        """
        serializer = LinkContentSerializer(data=request.data, context={'request': request})
        if not serializer.is_valid():
            return error_response(serializer.errors, status=status.HTTP_400_BAD_REQUEST, request=request)
        
        content_id = serializer.validated_data['content_id']
        
        try:
            content = self.linker_service.process(content_id)
            
            result = {
                'content_id': content.id,
                'links_added': len(content.internal_links) if content.internal_links else 0,
                'links': content.internal_links or [],
                'linker_version': content.linker_version,
                'success': True,
            }
            
            return success_response(result, request=request)
            
        except ValueError as e:
            return error_response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST, request=request)
        except InsufficientCreditsError as e:
            return error_response({'error': str(e)}, status=status.HTTP_402_PAYMENT_REQUIRED, request=request)
        except Exception as e:
            logger.error(f"Error processing content {content_id}: {str(e)}", exc_info=True)
            return error_response({'error': 'Internal server error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, request=request)

    @action(detail=False, methods=['post'])
    def batch_process(self, request):
        """
        Process multiple content items for internal linking.
        
        POST /api/v1/linker/batch_process/
        {
            "content_ids": [123, 456, 789]
        }
        """
        serializer = BatchLinkContentSerializer(data=request.data, context={'request': request})
        if not serializer.is_valid():
            return error_response(serializer.errors, status=status.HTTP_400_BAD_REQUEST, request=request)
        
        content_ids = serializer.validated_data['content_ids']
        
        try:
            results = self.linker_service.batch_process(content_ids)
            
            response_data = []
            for content in results:
                response_data.append({
                    'content_id': content.id,
                    'links_added': len(content.internal_links) if content.internal_links else 0,
                    'links': content.internal_links or [],
                    'linker_version': content.linker_version,
                    'success': True,
                })
            
            return success_response(response_data, request=request)
            
        except Exception as e:
            logger.error(f"Error batch processing content: {str(e)}", exc_info=True)
            return error_response({'error': 'Internal server error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, request=request)

