"""
Tests for CandidateEngine
"""
from django.test import TestCase
from igny8_core.business.content.models import Content
from igny8_core.business.linking.services.candidate_engine import CandidateEngine
from igny8_core.api.tests.test_integration_base import IntegrationTestBase


class CandidateEngineTests(IntegrationTestBase):
    """Tests for CandidateEngine"""
    
    def setUp(self):
        super().setUp()
        self.engine = CandidateEngine()
        
        # Create source content
        self.source_content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Source Content",
            html_content="<p>Source content about test keyword.</p>",
            primary_keyword="test keyword",
            secondary_keywords=["keyword1", "keyword2"],
            categories=["category1"],
            tags=["tag1", "tag2"],
            word_count=100,
            status='draft'
        )
        
        # Create relevant content (same keyword)
        self.relevant_content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Relevant Content",
            html_content="<p>Relevant content about test keyword.</p>",
            primary_keyword="test keyword",
            secondary_keywords=["keyword1"],
            categories=["category1"],
            tags=["tag1"],
            word_count=150,
            status='draft'
        )
        
        # Create less relevant content (different keyword)
        self.less_relevant = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Less Relevant",
            html_content="<p>Different content.</p>",
            primary_keyword="different keyword",
            word_count=100,
            status='draft'
        )
    
    def test_find_candidates_returns_relevant_content(self):
        """Test that find_candidates returns relevant content"""
        candidates = self.engine.find_candidates(self.source_content, max_candidates=10)
        
        # Should find relevant content
        candidate_ids = [c['content_id'] for c in candidates]
        self.assertIn(self.relevant_content.id, candidate_ids)
    
    def test_find_candidates_scores_by_relevance(self):
        """Test that candidates are scored by relevance"""
        candidates = self.engine.find_candidates(self.source_content, max_candidates=10)
        
        # Relevant content should have higher score
        relevant_candidate = next((c for c in candidates if c['content_id'] == self.relevant_content.id), None)
        self.assertIsNotNone(relevant_candidate)
        self.assertGreater(relevant_candidate['relevance_score'], 0)
    
    def test_find_candidates_excludes_self(self):
        """Test that source content is excluded from candidates"""
        candidates = self.engine.find_candidates(self.source_content, max_candidates=10)
        
        candidate_ids = [c['content_id'] for c in candidates]
        self.assertNotIn(self.source_content.id, candidate_ids)
    
    def test_find_candidates_respects_account_isolation(self):
        """Test that candidates are only from same account"""
        # Create content from different account
        from igny8_core.auth.models import Account
        other_account = Account.objects.create(
            name="Other Account",
            slug="other-account",
            plan=self.plan,
            owner=self.user
        )
        
        other_content = Content.objects.create(
            account=other_account,
            site=self.site,
            sector=self.sector,
            title="Other Account Content",
            primary_keyword="test keyword",
            word_count=100,
            status='draft'
        )
        
        candidates = self.engine.find_candidates(self.source_content, max_candidates=10)
        candidate_ids = [c['content_id'] for c in candidates]
        self.assertNotIn(other_content.id, candidate_ids)
    
    def test_find_candidates_returns_empty_for_no_content(self):
        """Test that empty list is returned when no content"""
        empty_content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Empty",
            html_content="",
            word_count=0,
            status='draft'
        )
        
        candidates = self.engine.find_candidates(empty_content, max_candidates=10)
        self.assertEqual(len(candidates), 0)
    
    def test_find_candidates_respects_max_candidates(self):
        """Test that max_candidates limit is respected"""
        # Create multiple relevant content items
        for i in range(15):
            Content.objects.create(
                account=self.account,
                site=self.site,
                sector=self.sector,
                title=f"Content {i}",
                primary_keyword="test keyword",
                word_count=100,
                status='draft'
            )
        
        candidates = self.engine.find_candidates(self.source_content, max_candidates=5)
        self.assertLessEqual(len(candidates), 5)

