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.optimization.services.optimizer_service import OptimizerService
from igny8_core.business.billing.exceptions import InsufficientCreditsError
from igny8_core.modules.optimizer.serializers import (
    OptimizeContentSerializer,
    BatchOptimizeContentSerializer,
    AnalyzeContentSerializer,
)

logger = logging.getLogger(__name__)


@extend_schema_view(
    optimize=extend_schema(tags=['Optimizer']),
    batch_optimize=extend_schema(tags=['Optimizer']),
    analyze=extend_schema(tags=['Optimizer']),
)
class OptimizerViewSet(ViewSet):
    """
    API endpoints for content optimization operations.
    Unified API Standard v1.0 compliant
    """
    permission_classes = [IsAuthenticatedAndActive, IsEditorOrAbove]
    throttle_scope = 'optimizer'
    throttle_classes = [DebugScopedRateThrottle]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.optimizer_service = OptimizerService()

    @action(detail=False, methods=['post'])
    def optimize(self, request):
        """
        Optimize content (auto-detects entry point based on source).
        
        POST /api/v1/optimizer/optimize/
        {
            "content_id": 123,
            "entry_point": "auto"  // optional: auto, writer, wordpress, external, manual
        }
        """
        serializer = OptimizeContentSerializer(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']
        entry_point = serializer.validated_data.get('entry_point', 'auto')
        
        try:
            content = Content.objects.get(id=content_id)
            
            # Route to appropriate entry point
            if entry_point == 'auto':
                # Auto-detect based on source
                if content.source == 'igny8':
                    content = self.optimizer_service.optimize_from_writer(content_id)
                elif content.source == 'wordpress':
                    content = self.optimizer_service.optimize_from_wordpress_sync(content_id)
                elif content.source in ['shopify', 'custom']:
                    content = self.optimizer_service.optimize_from_external_sync(content_id)
                else:
                    content = self.optimizer_service.optimize_manual(content_id)
            elif entry_point == 'writer':
                content = self.optimizer_service.optimize_from_writer(content_id)
            elif entry_point == 'wordpress':
                content = self.optimizer_service.optimize_from_wordpress_sync(content_id)
            elif entry_point == 'external':
                content = self.optimizer_service.optimize_from_external_sync(content_id)
            else:  # manual
                content = self.optimizer_service.optimize_manual(content_id)
            
            # Get latest optimization task
            task = content.optimization_tasks.order_by('-created_at').first()
            
            result = {
                'content_id': content.id,
                'optimizer_version': content.optimizer_version,
                'scores_before': task.scores_before if task else {},
                'scores_after': content.optimization_scores,
                'task_id': task.id if task else None,
                '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 optimizing 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_optimize(self, request):
        """
        Batch optimize multiple content items.
        
        POST /api/v1/optimizer/batch_optimize/
        {
            "content_ids": [123, 456, 789],
            "entry_point": "auto"
        }
        """
        serializer = BatchOptimizeContentSerializer(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']
        entry_point = serializer.validated_data.get('entry_point', 'auto')
        
        results = []
        errors = []
        
        for content_id in content_ids:
            try:
                content = Content.objects.get(id=content_id)
                
                # Route to appropriate entry point
                if entry_point == 'auto':
                    if content.source == 'igny8':
                        content = self.optimizer_service.optimize_from_writer(content_id)
                    elif content.source == 'wordpress':
                        content = self.optimizer_service.optimize_from_wordpress_sync(content_id)
                    elif content.source in ['shopify', 'custom']:
                        content = self.optimizer_service.optimize_from_external_sync(content_id)
                    else:
                        content = self.optimizer_service.optimize_manual(content_id)
                elif entry_point == 'writer':
                    content = self.optimizer_service.optimize_from_writer(content_id)
                elif entry_point == 'wordpress':
                    content = self.optimizer_service.optimize_from_wordpress_sync(content_id)
                elif entry_point == 'external':
                    content = self.optimizer_service.optimize_from_external_sync(content_id)
                else:
                    content = self.optimizer_service.optimize_manual(content_id)
                
                task = content.optimization_tasks.order_by('-created_at').first()
                
                results.append({
                    'content_id': content.id,
                    'optimizer_version': content.optimizer_version,
                    'scores_after': content.optimization_scores,
                    'success': True,
                })
                
            except Exception as e:
                logger.error(f"Error optimizing content {content_id}: {str(e)}", exc_info=True)
                errors.append({
                    'content_id': content_id,
                    'error': str(e),
                    'success': False,
                })
        
        return success_response({
            'results': results,
            'errors': errors,
            'total': len(content_ids),
            'succeeded': len(results),
            'failed': len(errors),
        }, request=request)

    @action(detail=False, methods=['post'])
    def analyze(self, request):
        """
        Analyze content without optimizing (preview scores).
        
        POST /api/v1/optimizer/analyze/
        {
            "content_id": 123
        }
        """
        serializer = AnalyzeContentSerializer(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:
            scores = self.optimizer_service.analyze_only(content_id)
            
            return success_response({
                'content_id': content_id,
                'scores': scores,
            }, request=request)
            
        except ValueError as e:
            return error_response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST, request=request)
        except Exception as e:
            logger.error(f"Error analyzing content {content_id}: {str(e)}", exc_info=True)
            return error_response({'error': 'Internal server error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, request=request)

