# app/modules/prospecting/tests/unit/test_scoring_service.py
"""
Unit tests for ScoringService.
"""

import json

import pytest

from app.modules.prospecting.services.scoring_service import ScoringService


@pytest.mark.unit
@pytest.mark.prospecting
class TestScoringService:
    """Tests for ScoringService."""

    def setup_method(self):
        self.service = ScoringService()

    def test_score_digital_no_ssl(self, db, digital_prospect):
        """Test scoring a digital prospect without SSL."""
        digital_prospect.uses_https = False
        db.commit()
        db.refresh(digital_prospect)

        score = self.service.compute_score(db, digital_prospect)
        assert score.score > 0
        flags = json.loads(score.reason_flags) if score.reason_flags else []
        assert "no_ssl" in flags

    def test_score_digital_slow_site(self, db, prospect_with_performance):
        """Test scoring a prospect with slow performance."""
        score = self.service.compute_score(db, prospect_with_performance)
        assert score.technical_health_score > 0
        flags = json.loads(score.reason_flags) if score.reason_flags else []
        assert "slow" in flags or "very_slow" in flags

    def test_score_digital_outdated_cms(self, db, prospect_with_tech):
        """Test scoring a prospect with outdated CMS (jQuery counts as legacy)."""
        # WordPress is not "outdated" but jQuery is legacy
        score = self.service.compute_score(db, prospect_with_tech)
        flags = json.loads(score.reason_flags) if score.reason_flags else []
        assert "legacy_js" in flags

    def test_score_digital_full_prospect(self, db, prospect_full):
        """Test scoring a fully enriched prospect (no SSL, slow, outdated CMS)."""
        score = self.service.compute_score(db, prospect_full)
        assert score.score >= 70
        assert score.lead_tier == "top_priority"

    def test_score_offline_no_website(self, db, offline_prospect):
        """Test scoring an offline prospect with no website (base score 70)."""
        score = self.service.compute_score(db, offline_prospect)
        assert score.score >= 70
        assert score.lead_tier == "top_priority"
        flags = json.loads(score.reason_flags) if score.reason_flags else []
        assert "no_website" in flags

    def test_score_components_max(self, db, prospect_full):
        """Test that score components don't exceed their maximums."""
        score = self.service.compute_score(db, prospect_full)
        assert score.technical_health_score <= 40
        assert score.modernity_score <= 25
        assert score.business_value_score <= 25
        assert score.engagement_score <= 10
        assert score.score <= 100

    def test_lead_tier_assignment(self, db, digital_prospect, offline_prospect):
        """Test that lead tiers are correctly assigned based on score."""
        # Digital prospect with website + SSL should be low score
        score1 = self.service.compute_score(db, digital_prospect)
        assert score1.lead_tier in ("top_priority", "quick_win", "strategic", "low_priority")

        # Offline prospect with no website should be top_priority
        score2 = self.service.compute_score(db, offline_prospect)
        assert score2.lead_tier == "top_priority"

    def test_compute_score_updates_existing(self, db, prospect_with_score):
        """Test that recomputing a score updates the existing record."""
        old_score_id = prospect_with_score.score.id
        score = self.service.compute_score(db, prospect_with_score)
        # Should update the same record
        assert score.id == old_score_id

    def test_compute_all(self, db, digital_prospect, offline_prospect):
        """Test batch score computation."""
        count = self.service.compute_all(db, limit=100)
        assert count >= 2
