"""
Tests for ContentAnalyzer
"""
from django.test import TestCase
from igny8_core.business.content.models import Content
from igny8_core.business.optimization.services.analyzer import ContentAnalyzer
from igny8_core.api.tests.test_integration_base import IntegrationTestBase


class ContentAnalyzerTests(IntegrationTestBase):
    """Tests for ContentAnalyzer"""
    
    def setUp(self):
        super().setUp()
        self.analyzer = ContentAnalyzer()
    
    def test_analyze_returns_all_scores(self):
        """Test that analyze returns all required scores"""
        content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Test Content",
            html_content="<p>This is test content.</p>",
            meta_title="Test Title",
            meta_description="Test description",
            primary_keyword="test keyword",
            word_count=1500,
            status='draft'
        )
        
        scores = self.analyzer.analyze(content)
        
        self.assertIn('seo_score', scores)
        self.assertIn('readability_score', scores)
        self.assertIn('engagement_score', scores)
        self.assertIn('overall_score', scores)
        self.assertIn('word_count', scores)
        self.assertIn('has_meta_title', scores)
        self.assertIn('has_meta_description', scores)
        self.assertIn('has_primary_keyword', scores)
        self.assertIn('internal_links_count', scores)
    
    def test_analyze_returns_zero_scores_for_empty_content(self):
        """Test that empty content returns zero scores"""
        content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Empty",
            html_content="",
            word_count=0,
            status='draft'
        )
        
        scores = self.analyzer.analyze(content)
        
        self.assertEqual(scores['seo_score'], 0)
        self.assertEqual(scores['readability_score'], 0)
        self.assertEqual(scores['engagement_score'], 0)
        self.assertEqual(scores['overall_score'], 0)
    
    def test_calculate_seo_score_with_meta_title(self):
        """Test SEO score calculation with meta title"""
        content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Test",
            meta_title="Test Title" * 5,  # 50 chars - optimal length
            word_count=1500,
            status='draft'
        )
        
        scores = self.analyzer.analyze(content)
        
        self.assertGreater(scores['seo_score'], 0)
    
    def test_calculate_seo_score_with_primary_keyword(self):
        """Test SEO score calculation with primary keyword"""
        content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Test",
            primary_keyword="test keyword",
            word_count=1500,
            status='draft'
        )
        
        scores = self.analyzer.analyze(content)
        
        self.assertGreater(scores['seo_score'], 0)
    
    def test_calculate_readability_score(self):
        """Test readability score calculation"""
        # Create content with good readability (short sentences, paragraphs)
        html = "<p>This is a sentence.</p><p>This is another sentence.</p><p>And one more.</p>"
        content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Test",
            html_content=html,
            word_count=20,
            status='draft'
        )
        
        scores = self.analyzer.analyze(content)
        
        self.assertGreater(scores['readability_score'], 0)
    
    def test_calculate_engagement_score_with_headings(self):
        """Test engagement score calculation with headings"""
        html = "<h1>Main Heading</h1><h2>Subheading 1</h2><h2>Subheading 2</h2>"
        content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Test",
            html_content=html,
            word_count=100,
            status='draft'
        )
        
        scores = self.analyzer.analyze(content)
        
        self.assertGreater(scores['engagement_score'], 0)
    
    def test_calculate_engagement_score_with_internal_links(self):
        """Test engagement score calculation with internal links"""
        content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Test",
            html_content="<p>Test content.</p>",
            internal_links=[
                {'content_id': 1, 'anchor_text': 'link1'},
                {'content_id': 2, 'anchor_text': 'link2'},
                {'content_id': 3, 'anchor_text': 'link3'}
            ],
            word_count=100,
            status='draft'
        )
        
        scores = self.analyzer.analyze(content)
        
        self.assertGreater(scores['engagement_score'], 0)
        self.assertEqual(scores['internal_links_count'], 3)
    
    def test_overall_score_is_weighted_average(self):
        """Test that overall score is weighted average"""
        content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Test",
            html_content="<p>Test content.</p>",
            meta_title="Test Title",
            meta_description="Test description",
            primary_keyword="test",
            word_count=1500,
            status='draft'
        )
        
        scores = self.analyzer.analyze(content)
        
        # Overall should be weighted: SEO (40%) + Readability (30%) + Engagement (30%)
        expected = (
            scores['seo_score'] * 0.4 +
            scores['readability_score'] * 0.3 +
            scores['engagement_score'] * 0.3
        )
        
        self.assertAlmostEqual(scores['overall_score'], expected, places=1)

