"""
Tests for Universal Content Types Optimization (Phase 8)
Tests for product and taxonomy optimization
"""
from unittest.mock import patch, MagicMock
from django.test import TestCase
from igny8_core.business.content.models import Content
from igny8_core.business.optimization.services.optimizer_service import OptimizerService
from igny8_core.business.optimization.models import OptimizationTask
from igny8_core.api.tests.test_integration_base import IntegrationTestBase


class UniversalContentOptimizationTests(IntegrationTestBase):
    """Tests for Phase 8: Universal Content Types Optimization"""
    
    def setUp(self):
        super().setUp()
        # Add credits to account for testing
        self.account.credits = 10000
        self.account.save()
        self.optimizer_service = OptimizerService()
        
        # Create product content
        self.product_content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title='Test Product',
            html_content='<p>Product content that needs optimization.</p>',
            entity_type='product',
            json_blocks=[
                {'type': 'features', 'heading': 'Features', 'items': ['Feature 1']},
                {'type': 'specifications', 'heading': 'Specs', 'data': {'Spec': 'Value'}}
            ],
            structure_data={'product_type': 'software', 'price_range': '$99-$199'},
            word_count=1500,
            status='draft'
        )
        
        # Create taxonomy content
        self.taxonomy_content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title='Test Taxonomy',
            html_content='<p>Taxonomy content that needs optimization.</p>',
            entity_type='taxonomy',
            json_blocks=[
                {'type': 'categories', 'heading': 'Categories', 'items': [{'name': 'Cat 1'}]},
                {'type': 'tags', 'heading': 'Tags', 'items': ['Tag 1']},
                {'type': 'hierarchy', 'heading': 'Hierarchy', 'structure': {}}
            ],
            word_count=1200,
            status='draft'
        )
    
    @patch('igny8_core.business.optimization.services.optimizer_service.OptimizerService._optimize_content')
    @patch('igny8_core.business.optimization.services.optimizer_service.ContentAnalyzer.analyze')
    @patch('igny8_core.business.optimization.services.optimizer_service.CreditService.check_credits')
    @patch('igny8_core.business.optimization.services.optimizer_service.CreditService.get_credit_cost')
    @patch('igny8_core.business.optimization.services.optimizer_service.CreditService.deduct_credits_for_operation')
    def test_optimization_works_for_products(self, mock_deduct, mock_get_cost, mock_check_credits, mock_analyze, mock_optimize):
        """
        Test: Optimization works for all content types (products, taxonomies)
        Task 21: Verify product optimization includes product-specific metrics
        """
        # Mock analyzer
        mock_analyze.return_value = {
            'seo_score': 75,
            'readability_score': 80,
            'engagement_score': 70,
            'overall_score': 75
        }
        
        # Mock credit cost
        mock_get_cost.return_value = 10
        
        # Mock optimization
        optimized_content = Content.objects.get(id=self.product_content.id)
        optimized_content.html_content = '<p>Optimized product content.</p>'
        mock_optimize.return_value = optimized_content
        
        # Optimize product
        result = self.optimizer_service.optimize_product(self.product_content.id)
        
        # Verify result
        self.assertIsNotNone(result)
        self.assertEqual(result.entity_type, 'product')
        self.assertEqual(result.optimizer_version, 1)
        self.assertIsNotNone(result.optimization_scores)
        
        # Verify product-specific scores were enhanced
        scores = result.optimization_scores
        self.assertIn('product_completeness', scores)
        self.assertGreaterEqual(scores['product_completeness'], 0)
        self.assertLessEqual(scores['product_completeness'], 1)
        
        # Verify optimization task was created
        task = OptimizationTask.objects.filter(content=result).first()
        self.assertIsNotNone(task)
        self.assertEqual(task.status, 'completed')
        self.assertIn('product_completeness', task.scores_after)
    
    @patch('igny8_core.business.optimization.services.optimizer_service.OptimizerService._optimize_content')
    @patch('igny8_core.business.optimization.services.optimizer_service.ContentAnalyzer.analyze')
    @patch('igny8_core.business.optimization.services.optimizer_service.CreditService.check_credits')
    @patch('igny8_core.business.optimization.services.optimizer_service.CreditService.get_credit_cost')
    @patch('igny8_core.business.optimization.services.optimizer_service.CreditService.deduct_credits_for_operation')
    def test_optimization_works_for_taxonomies(self, mock_deduct, mock_get_cost, mock_check_credits, mock_analyze, mock_optimize):
        """
        Test: Optimization works for all content types (products, taxonomies)
        Task 21: Verify taxonomy optimization includes taxonomy-specific metrics
        """
        # Mock analyzer
        mock_analyze.return_value = {
            'seo_score': 70,
            'readability_score': 75,
            'engagement_score': 65,
            'overall_score': 70
        }
        
        # Mock credit cost
        mock_get_cost.return_value = 8
        
        # Mock optimization
        optimized_content = Content.objects.get(id=self.taxonomy_content.id)
        optimized_content.html_content = '<p>Optimized taxonomy content.</p>'
        mock_optimize.return_value = optimized_content
        
        # Optimize taxonomy
        result = self.optimizer_service.optimize_taxonomy(self.taxonomy_content.id)
        
        # Verify result
        self.assertIsNotNone(result)
        self.assertEqual(result.entity_type, 'taxonomy')
        self.assertEqual(result.optimizer_version, 1)
        self.assertIsNotNone(result.optimization_scores)
        
        # Verify taxonomy-specific scores were enhanced
        scores = result.optimization_scores
        self.assertIn('taxonomy_organization', scores)
        self.assertGreaterEqual(scores['taxonomy_organization'], 0)
        self.assertLessEqual(scores['taxonomy_organization'], 1)
        
        # Verify optimization task was created
        task = OptimizationTask.objects.filter(content=result).first()
        self.assertIsNotNone(task)
        self.assertEqual(task.status, 'completed')
        self.assertIn('taxonomy_organization', task.scores_after)
    
    def test_enhance_product_scores_includes_completeness(self):
        """
        Test: Optimization works for all content types (products, taxonomies)
        Task 21: Verify _enhance_product_scores adds product_completeness
        """
        base_scores = {
            'seo_score': 75,
            'readability_score': 80,
            'overall_score': 75
        }
        
        enhanced = self.optimizer_service._enhance_product_scores(base_scores, self.product_content)
        
        self.assertIn('product_completeness', enhanced)
        self.assertGreaterEqual(enhanced['product_completeness'], 0)
        self.assertLessEqual(enhanced['product_completeness'], 1)
    
    def test_enhance_taxonomy_scores_includes_organization(self):
        """
        Test: Optimization works for all content types (products, taxonomies)
        Task 21: Verify _enhance_taxonomy_scores adds taxonomy_organization
        """
        base_scores = {
            'seo_score': 70,
            'readability_score': 75,
            'overall_score': 70
        }
        
        enhanced = self.optimizer_service._enhance_taxonomy_scores(base_scores, self.taxonomy_content)
        
        self.assertIn('taxonomy_organization', enhanced)
        self.assertGreaterEqual(enhanced['taxonomy_organization'], 0)
        self.assertLessEqual(enhanced['taxonomy_organization'], 1)

