"""
Publisher Service
Phase 5: Content Publishing

Main publishing orchestrator for content.
Legacy: SiteBlueprint publishing removed.
"""
import logging
from typing import Optional, List, Dict, Any

from igny8_core.business.publishing.models import PublishingRecord, DeploymentRecord
# Removed: from igny8_core.business.site_building.models import SiteBlueprint

logger = logging.getLogger(__name__)


class PublisherService:
    """
    Main publishing service for content.
    Routes to appropriate adapters based on destination.
    Legacy: SiteBlueprint publishing removed.
    """
    
    def __init__(self):
        self.adapters = {}
        self._load_adapters()
    
    def _load_adapters(self):
        """Lazy load adapters to avoid circular imports"""
        pass  # Will be implemented when adapters are created
    
    def publish_content(
        self,
        content_id: int,
        destinations: List[str],
        account
    ) -> Dict[str, Any]:
        """
        Publish content to multiple destinations.
        
        Args:
            content_id: Content ID to publish
            destinations: List of destination platforms ('wordpress', 'sites', 'shopify')
            account: Account instance
        
        Returns:
            dict: Publishing results per destination
        """
        from igny8_core.business.content.models import Content
        
        logger.info(f"[PublisherService.publish_content] 🎯 Starting publish: content_id={content_id}, destinations={destinations}")
        
        try:
            content = Content.objects.get(id=content_id, account=account)
            logger.info(f"[PublisherService.publish_content] 📄 Content found: title='{content.title}', site={content.site.name if content.site else 'None'}")
        except Content.DoesNotExist:
            logger.error(f"[PublisherService.publish_content] ❌ Content {content_id} not found")
            return {
                'success': False,
                'error': f'Content {content_id} not found'
            }
        
        results = []
        for destination in destinations:
            logger.info(f"[PublisherService.publish_content] 🔄 Publishing to destination: {destination}")
            try:
                result = self._publish_to_destination(content, destination, account)
                logger.info(f"[PublisherService.publish_content] {'✅' if result.get('success') else '❌'} Destination {destination} result: {result}")
                results.append(result)
            except Exception as e:
                logger.error(
                    f"[PublisherService.publish_content] ❌ Error publishing content {content_id} to {destination}: {str(e)}",
                    exc_info=True
                )
                results.append({
                    'destination': destination,
                    'success': False,
                    'error': str(e)
                })
        
        overall_success = all(r.get('success', False) for r in results)
        logger.info(f"[PublisherService.publish_content] {'✅' if overall_success else '❌'} Overall publish result: success={overall_success}, {len(results)} destinations")
        
        return {
            'success': overall_success,
            'results': results
        }
    
    def _publish_to_destination(
        self,
        content,
        destination: str,
        account
    ) -> Dict[str, Any]:
        """
        Publish content to a specific destination.
        
        Args:
            content: Content instance
            destination: Destination platform name
            account: Account instance
        
        Returns:
            dict: Publishing result
        """
        # Create publishing record
        logger.info(f"[PublisherService._publish_to_destination] 📝 Creating publishing record for {destination}")
        record = PublishingRecord.objects.create(
            account=account,
            site=content.site,
            sector=content.sector,
            content=content,
            destination=destination,
            status='pending'
        )
        logger.info(f"[PublisherService._publish_to_destination] ✅ Publishing record created: id={record.id}")
        
        try:
            # Get adapter for destination
            logger.info(f"[PublisherService._publish_to_destination] 🔌 Getting adapter for {destination}")
            adapter = self._get_adapter(destination)
            if not adapter:
                logger.error(f"[PublisherService._publish_to_destination] ❌ No adapter found for destination: {destination}")
                raise ValueError(f"No adapter found for destination: {destination}")
            logger.info(f"[PublisherService._publish_to_destination] ✅ Adapter found: {adapter.__class__.__name__}")
            
            # Get destination config
            destination_config = {}
            
            # If content has site, try to get integration config
            if hasattr(content, 'site') and content.site:
                from igny8_core.business.integration.models import SiteIntegration
                logger.info(f"[PublisherService._publish_to_destination] 🔍 Looking for integration: site={content.site.name}, platform={destination}")
                integration = SiteIntegration.objects.filter(
                    site=content.site,
                    platform=destination,
                    is_active=True
                ).first()
                
                if integration:
                    logger.info(f"[PublisherService._publish_to_destination] ✅ Integration found: id={integration.id}")
                    # Merge config_json and credentials_json
                    destination_config.update(integration.config_json or {})
                    destination_config.update(integration.get_credentials() or {})
                    logger.info(f"[PublisherService._publish_to_destination] 🔑 Config merged: has_api_key={bool(destination_config.get('api_key'))}, has_site_url={bool(destination_config.get('site_url'))}")
                    
                    # Ensure site_url is set (from config or from site model)
                    if not destination_config.get('site_url'):
                        destination_config['site_url'] = content.site.url
                        logger.info(f"[PublisherService._publish_to_destination] 🌐 Using site.url: {content.site.url}")
                else:
                    logger.warning(f"[PublisherService._publish_to_destination] ⚠️ No integration found for site={content.site.name}, platform={destination}")
            
            # Publish via adapter
            logger.info(f"[PublisherService._publish_to_destination] 🚀 Calling adapter.publish() with config keys: {list(destination_config.keys())}")
            result = adapter.publish(content, destination_config)
            logger.info(f"[PublisherService._publish_to_destination] 📬 Adapter returned: success={result.get('success')}, external_id={result.get('external_id')}")
            
            # Update record
            record.status = 'published' if result.get('success') else 'failed'
            record.destination_id = result.get('external_id')
            record.destination_url = result.get('url')
            record.published_at = result.get('published_at')
            record.error_message = result.get('error')
            record.metadata = result.get('metadata', {})
            record.save()
            
            # Update content status to published if successful
            if result.get('success'):
                content.status = 'published'
                content.external_id = result.get('external_id')
                content.external_url = result.get('url')
                
                # NEW: Save term_ids to external_metadata if available
                if result.get('metadata') and result['metadata'].get('term_ids'):
                    if not hasattr(content, 'external_metadata'):
                        logger.warning(f"[PublisherService._publish_to_destination] ⚠️  Content model missing external_metadata field - run migrations")
                        content.save(update_fields=['status', 'external_id', 'external_url', 'updated_at'])
                    else:
                        if content.external_metadata is None:
                            content.external_metadata = {}
                        content.external_metadata['wordpress_term_ids'] = result['metadata']['term_ids']
                        logger.info(f"[PublisherService._publish_to_destination] 🏷️  Saved term_ids to external_metadata: {result['metadata']['term_ids']}")
                        content.save(update_fields=['status', 'external_id', 'external_url', 'external_metadata', 'updated_at'])
                else:
                    content.save(update_fields=['status', 'external_id', 'external_url', 'updated_at'])
                
                logger.info(f"[PublisherService._publish_to_destination] ✅ Updated content status to 'published'")
            
            return {
                'destination': destination,
                'success': result.get('success', False),
                'publishing_record_id': record.id,
                'external_id': result.get('external_id'),
                'url': result.get('url'),
                'error': result.get('error') if not result.get('success') else None
            }
        except Exception as e:
            record.status = 'failed'
            record.error_message = str(e)
            record.save()
            logger.error(f"[PublisherService._publish_to_destination] ❌ Exception during publish: {str(e)}")
            # Don't raise - return error result instead
            return {
                'destination': destination,
                'success': False,
                'publishing_record_id': record.id,
                'error': str(e)
            }
    
    def publish_to_multiple_destinations(
        self,
        content: Any,
        destinations: List[Dict[str, Any]],
        account
    ) -> Dict[str, Any]:
        """
        Publish content to multiple destinations.
        
        Args:
            content: Content instance
            destinations: List of destination configs, e.g.:
                [
                    {'platform': 'wordpress', 'site_url': '...', 'username': '...', 'app_password': '...'},
                    {'platform': 'sites'},
                    {'platform': 'shopify', 'shop_domain': '...', 'access_token': '...'}
                ]
            account: Account instance
        
        Returns:
            dict: {
                'success': bool,
                'results': list of publishing results per destination
            }
        """
        results = []
        
        for destination_config in destinations:
            platform = destination_config.get('platform')
            if not platform:
                results.append({
                    'platform': 'unknown',
                    'success': False,
                    'error': 'Platform not specified'
                })
                continue
            
            try:
                adapter = self._get_adapter(platform)
                if not adapter:
                    results.append({
                        'platform': platform,
                        'success': False,
                        'error': f'No adapter found for platform: {platform}'
                    })
                    continue
                
                # Validate config
                is_valid, error_msg = adapter.validate_config(destination_config)
                if not is_valid:
                    results.append({
                        'platform': platform,
                        'success': False,
                        'error': error_msg or 'Invalid configuration'
                    })
                    continue
                
                # Publish via adapter
                result = adapter.publish(content, destination_config)
                
                # Create publishing record if content has site/sector
                if hasattr(content, 'site') and hasattr(content, 'sector'):
                    record = PublishingRecord.objects.create(
                        account=account,
                        site=content.site,
                        sector=content.sector,
                        content=content if hasattr(content, 'id') else None,
                        destination=platform,
                        status='published' if result.get('success') else 'failed',
                        destination_id=result.get('external_id'),
                        destination_url=result.get('url'),
                        published_at=result.get('published_at'),
                        error_message=result.get('metadata', {}).get('error'),
                        metadata=result.get('metadata', {})
                    )
                    result['publishing_record_id'] = record.id
                
                results.append({
                    'platform': platform,
                    'success': result.get('success', False),
                    'external_id': result.get('external_id'),
                    'url': result.get('url'),
                    'error': result.get('metadata', {}).get('error')
                })
                
            except Exception as e:
                logger.error(
                    f"Error publishing to {platform}: {str(e)}",
                    exc_info=True
                )
                results.append({
                    'platform': platform,
                    'success': False,
                    'error': str(e)
                })
        
        return {
            'success': all(r.get('success', False) for r in results),
            'results': results
        }
    
    def publish_with_integrations(
        self,
        content: Any,
        site,
        account,
        platforms: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Publish content using site integrations.
        
        Args:
            content: Content instance
            site: Site instance
            account: Account instance
            platforms: Optional list of platforms to publish to (all active if None)
        
        Returns:
            dict: Publishing results
        """
        from igny8_core.business.integration.models import SiteIntegration
        
        # Get active integrations for site
        integrations = SiteIntegration.objects.filter(
            site=site,
            is_active=True
        )
        
        if platforms:
            integrations = integrations.filter(platform__in=platforms)
        
        destinations = []
        for integration in integrations:
            config = integration.config_json.copy()
            credentials = integration.get_credentials()
            
            destination_config = {
                'platform': integration.platform,
                **config,
                **credentials
            }
            destinations.append(destination_config)
        
        # Also add 'sites' destination if not in platforms filter or if platforms is None
        if not platforms or 'sites' in platforms:
            destinations.append({'platform': 'sites'})
        
        return self.publish_to_multiple_destinations(content, destinations, account)
    
    def _get_adapter(self, destination: str):
        """
        Get adapter for destination platform.
        
        Args:
            destination: Platform name ('wordpress', 'sites', 'shopify')
        
        Returns:
            Adapter instance or None
        """
        # Lazy import to avoid circular dependencies
        # REMOVED: 'sites' destination (SitesRendererAdapter) - legacy SiteBlueprint functionality
        if destination == 'wordpress':
            from igny8_core.business.publishing.services.adapters.wordpress_adapter import WordPressAdapter
            return WordPressAdapter()
        elif destination == 'shopify':
            from igny8_core.business.publishing.services.adapters.shopify_adapter import ShopifyAdapter
            return ShopifyAdapter()
        return None

