"""
Tests for Optimizer API endpoints
"""
from unittest.mock import patch
from django.test import TestCase
from rest_framework.test import APIClient
from rest_framework import status
from igny8_core.business.content.models import Content
from igny8_core.business.optimization.models import OptimizationTask
from igny8_core.business.billing.exceptions import InsufficientCreditsError
from igny8_core.api.tests.test_integration_base import IntegrationTestBase


class OptimizerAPITests(IntegrationTestBase):
    """Tests for Optimizer API endpoints"""
    
    def setUp(self):
        super().setUp()
        self.client = APIClient()
        self.client.force_authenticate(user=self.user)
        
        # Create test content
        self.content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Test Content",
            html_content="<p>Test content.</p>",
            word_count=500,
            status='draft',
            source='igny8'
        )
    
    def test_optimize_endpoint_requires_authentication(self):
        """Test that optimize endpoint requires authentication"""
        client = APIClient()  # Not authenticated
        response = client.post('/api/v1/optimizer/optimize/', {
            'content_id': self.content.id
        })
        
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
    
    @patch('igny8_core.modules.optimizer.views.OptimizerService.optimize_from_writer')
    def test_optimize_endpoint_success(self, mock_optimize):
        """Test successful optimization"""
        optimized_content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Optimized",
            html_content="<p>Optimized.</p>",
            word_count=500,
            optimizer_version=1,
            optimization_scores={'overall_score': 75.0}
        )
        mock_optimize.return_value = optimized_content
        
        # Create optimization task
        task = OptimizationTask.objects.create(
            content=optimized_content,
            scores_before={'overall_score': 50.0},
            scores_after={'overall_score': 75.0},
            status='completed',
            account=self.account
        )
        
        response = self.client.post('/api/v1/optimizer/optimize/', {
            'content_id': self.content.id,
            'entry_point': 'writer'
        }, format='json')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(response.data['success'])
        self.assertEqual(response.data['data']['content_id'], self.content.id)
    
    def test_optimize_endpoint_all_entry_points(self):
        """Test optimize endpoint with all entry point values"""
        entry_points = ['auto', 'writer', 'wordpress', 'external', 'manual']
        
        for entry_point in entry_points:
            with patch(f'igny8_core.modules.optimizer.views.OptimizerService.optimize_{entry_point if entry_point != "auto" else "from_writer"}') as mock_opt:
                if entry_point == 'auto':
                    mock_opt = patch('igny8_core.modules.optimizer.views.OptimizerService.optimize_from_writer')
                mock_opt.return_value = self.content
                
                response = self.client.post('/api/v1/optimizer/optimize/', {
                    'content_id': self.content.id,
                    'entry_point': entry_point
                }, format='json')
                
                # Should accept all entry points
                self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])
    
    @patch('igny8_core.modules.optimizer.views.OptimizerService.optimize_from_writer')
    def test_batch_optimize_endpoint_success(self, mock_optimize):
        """Test successful batch optimization"""
        content2 = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Content 2",
            word_count=500,
            source='igny8'
        )
        
        mock_optimize.return_value = self.content
        
        response = self.client.post('/api/v1/optimizer/batch_optimize/', {
            'content_ids': [self.content.id, content2.id],
            'entry_point': 'writer'
        }, format='json')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(response.data['success'])
        self.assertIn('succeeded', response.data['data'])
    
    @patch('igny8_core.modules.optimizer.views.OptimizerService.analyze_only')
    def test_analyze_endpoint_success(self, mock_analyze):
        """Test analyze endpoint returns scores"""
        scores = {
            'seo_score': 50.0,
            'readability_score': 60.0,
            'engagement_score': 55.0,
            'overall_score': 55.0
        }
        mock_analyze.return_value = scores
        
        response = self.client.post('/api/v1/optimizer/analyze/', {
            'content_id': self.content.id
        }, format='json')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(response.data['success'])
        self.assertIn('scores', response.data['data'])
        self.assertEqual(response.data['data']['scores']['overall_score'], 55.0)
    
    @patch('igny8_core.modules.optimizer.views.OptimizerService.optimize_from_writer')
    def test_optimize_endpoint_insufficient_credits(self, mock_optimize):
        """Test optimize endpoint with insufficient credits"""
        mock_optimize.side_effect = InsufficientCreditsError("Insufficient credits")
        
        response = self.client.post('/api/v1/optimizer/optimize/', {
            'content_id': self.content.id
        }, format='json')
        
        self.assertEqual(response.status_code, status.HTTP_402_PAYMENT_REQUIRED)
    
    def test_optimize_endpoint_invalid_content_id(self):
        """Test optimize endpoint with invalid content ID"""
        response = self.client.post('/api/v1/optimizer/optimize/', {
            'content_id': 99999
        }, format='json')
        
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
    
    def test_optimize_endpoint_respects_account_isolation(self):
        """Test that optimize endpoint respects account isolation"""
        from igny8_core.auth.models import Account
        other_account = Account.objects.create(
            name="Other Account",
            slug="other",
            plan=self.plan,
            owner=self.user
        )
        
        other_content = Content.objects.create(
            account=other_account,
            site=self.site,
            sector=self.sector,
            title="Other Content",
            word_count=100
        )
        
        response = self.client.post('/api/v1/optimizer/optimize/', {
            'content_id': other_content.id
        }, format='json')
        
        # Should return 400 because content belongs to different account
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

