# app/modules/prospecting/tests/unit/test_campaign_service.py
"""
Unit tests for CampaignService.
"""

import pytest

from app.modules.prospecting.exceptions import CampaignTemplateNotFoundException
from app.modules.prospecting.services.campaign_service import CampaignService


@pytest.mark.unit
@pytest.mark.prospecting
class TestCampaignService:
    """Tests for CampaignService."""

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

    def test_create_template(self, db):
        """Test creating a campaign template."""
        template = self.service.create_template(db, {
            "name": "Test Campaign",
            "lead_type": "bad_website",
            "channel": "email",
            "language": "fr",
            "subject_template": "Subject for {domain}",
            "body_template": "Hello {business_name}, your site {domain} has issues.",
        })

        assert template.id is not None
        assert template.name == "Test Campaign"
        assert template.lead_type == "bad_website"

    def test_get_templates(self, db, campaign_template):
        """Test listing campaign templates."""
        templates = self.service.get_templates(db)
        assert len(templates) >= 1

    def test_get_templates_filter_lead_type(self, db, campaign_template):
        """Test filtering templates by lead type."""
        templates = self.service.get_templates(db, lead_type="bad_website")
        assert len(templates) >= 1

        templates = self.service.get_templates(db, lead_type="no_website")
        # campaign_template is bad_website, so this might be empty
        assert isinstance(templates, list)

    def test_get_template_by_id(self, db, campaign_template):
        """Test getting a template by ID."""
        result = self.service.get_template_by_id(db, campaign_template.id)
        assert result.id == campaign_template.id

    def test_get_template_not_found(self, db):
        """Test getting non-existent template raises exception."""
        with pytest.raises(CampaignTemplateNotFoundException):
            self.service.get_template_by_id(db, 99999)

    def test_update_template(self, db, campaign_template):
        """Test updating a template."""
        updated = self.service.update_template(
            db, campaign_template.id, {"name": "Updated Campaign"}
        )
        assert updated.name == "Updated Campaign"

    def test_delete_template(self, db, campaign_template):
        """Test deleting a template."""
        tid = campaign_template.id
        self.service.delete_template(db, tid)

        with pytest.raises(CampaignTemplateNotFoundException):
            self.service.get_template_by_id(db, tid)

    def test_render_campaign(self, db, campaign_template, prospect_with_score):
        """Test rendering a campaign with prospect data."""
        result = self.service.render_campaign(
            db, campaign_template.id, prospect_with_score.id
        )

        assert "subject" in result
        assert "body" in result
        assert prospect_with_score.domain_name in result["subject"]

    def test_send_campaign(self, db, campaign_template, digital_prospect):
        """Test sending a campaign to prospects."""
        sends = self.service.send_campaign(
            db,
            template_id=campaign_template.id,
            prospect_ids=[digital_prospect.id],
            sent_by_user_id=1,
        )

        assert len(sends) == 1
        assert sends[0].prospect_id == digital_prospect.id
        assert sends[0].status.value == "sent"

    def test_get_sends(self, db, campaign_template, digital_prospect):
        """Test getting campaign sends."""
        self.service.send_campaign(
            db,
            template_id=campaign_template.id,
            prospect_ids=[digital_prospect.id],
            sent_by_user_id=1,
        )

        sends = self.service.get_sends(db, prospect_id=digital_prospect.id)
        assert len(sends) >= 1
