"""
Tests for PublisherService
Phase 5: Sites Renderer & Publishing
"""
from django.test import TestCase
from django.utils import timezone
from unittest.mock import Mock, patch

from igny8_core.auth.models import Account, Site, Sector, User, Plan, Industry, IndustrySector
from igny8_core.business.site_building.models import SiteBlueprint
from igny8_core.business.publishing.models import PublishingRecord, DeploymentRecord
from igny8_core.business.publishing.services.publisher_service import PublisherService


class PublisherServiceTestCase(TestCase):
    """Test cases for PublisherService"""
    
    def setUp(self):
        """Set up test data"""
        # Create plan first
        self.plan = Plan.objects.create(
            name="Test Plan",
            slug="test-plan",
            price=0,
            credits_per_month=1000
        )
        
        # Create user first (Account needs owner)
        self.user = User.objects.create_user(
            username='testuser',
            email='test@test.com',
            password='testpass123',
            role='owner'
        )
        
        # Create account with owner
        self.account = Account.objects.create(
            name="Test Account",
            slug="test-account",
            plan=self.plan,
            owner=self.user
        )
        
        # Update user to have account
        self.user.account = self.account
        self.user.save()
        
        # Create industry and sector
        self.industry = Industry.objects.create(
            name="Test Industry",
            slug="test-industry"
        )
        
        self.industry_sector = IndustrySector.objects.create(
            industry=self.industry,
            name="Test Sector",
            slug="test-sector"
        )
        
        self.site = Site.objects.create(
            account=self.account,
            name="Test Site",
            slug="test-site",
            industry=self.industry
        )
        self.sector = Sector.objects.create(
            account=self.account,
            site=self.site,
            industry_sector=self.industry_sector,
            name="Test Sector",
            slug="test-sector"
        )
        self.blueprint = SiteBlueprint.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            name="Test Blueprint",
            status='ready'
        )
        self.service = PublisherService()
    
    def test_publish_to_sites_creates_deployment_record(self):
        """Test: Deployment works end-to-end"""
        # Don't mock deploy - let it run to create the deployment record
        # But mock the filesystem operations to avoid actual file writes
        with patch('igny8_core.business.publishing.services.adapters.sites_renderer_adapter.Path.mkdir'), \
             patch('igny8_core.business.publishing.services.adapters.sites_renderer_adapter.open', create=True) as mock_open:
            mock_file = mock_open.return_value.__enter__.return_value
            
            result = self.service.publish_to_sites(self.blueprint)
            
            self.assertTrue(result.get('success'))
            self.assertIsNotNone(result.get('deployment_url'))
            
            # Verify deployment record was created
            deployment = DeploymentRecord.objects.filter(site_blueprint=self.blueprint).first()
            self.assertIsNotNone(deployment)
    
    def test_get_deployment_status_returns_latest(self):
        """Test: Sites are accessible publicly"""
        DeploymentRecord.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            site_blueprint=self.blueprint,
            version=1,
            status='deployed',
            deployment_url='https://test-site.igny8.com',
            deployed_at=timezone.now()
        )
        
        status = self.service.get_deployment_status(self.blueprint)
        
        self.assertIsNotNone(status)
        self.assertEqual(status.status, 'deployed')
        self.assertIsNotNone(status.deployment_url)
    
    def test_publish_content_to_multiple_destinations(self):
        """Test: Multi-destination publishing works"""
        from igny8_core.business.content.models import Content
        
        content = Content.objects.create(
            account=self.account,
            site=self.site,
            sector=self.sector,
            title="Test Content",
            html_content="<p>Test</p>"
        )
        
        with patch.object(self.service, '_get_adapter') as mock_get_adapter:
            mock_adapter = Mock()
            mock_adapter.publish.return_value = {
                'success': True,
                'external_id': '123',
                'url': 'https://example.com/post/123'
            }
            mock_get_adapter.return_value = mock_adapter
            
            result = self.service.publish_content(
                content_id=content.id,
                destinations=['wordpress', 'sites'],
                account=self.account
            )
            
            self.assertTrue(result.get('success'))
            self.assertEqual(len(result.get('results', [])), 2)
            
            # Verify publishing records were created
            records = PublishingRecord.objects.filter(content=content)
            self.assertEqual(records.count(), 2)

