"""
Content Sync Service
Phase 6: Site Integration & Multi-Destination Publishing
Stage 4: Enhanced with taxonomy and product sync

Syncs content between IGNY8 and external platforms.
"""
import logging
from typing import Dict, Any, Optional, List

from igny8_core.business.integration.models import SiteIntegration
from igny8_core.utils.wordpress import WordPressClient

logger = logging.getLogger(__name__)


class ContentSyncService:
    """
    Service for syncing content to/from external platforms.
    """
    
    def sync_to_external(
        self,
        integration: SiteIntegration,
        content_types: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Sync content from IGNY8 to external platform.
        
        Args:
            integration: SiteIntegration instance
            content_types: List of content types to sync (optional)
        
        Returns:
            dict: Sync result
        """
        try:
            if integration.platform == 'wordpress':
                return self._sync_to_wordpress(integration, content_types)
            elif integration.platform == 'shopify':
                return self._sync_to_shopify(integration, content_types)
            else:
                return {
                    'success': False,
                    'error': f'Sync to {integration.platform} not implemented',
                    'synced_count': 0
                }
        except Exception as e:
            logger.error(
                f"[ContentSyncService] Error syncing to {integration.platform}: {str(e)}",
                exc_info=True
            )
            return {
                'success': False,
                'error': str(e),
                'synced_count': 0
            }
    
    def sync_from_external(
        self,
        integration: SiteIntegration,
        content_types: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Sync content from external platform to IGNY8.
        
        Args:
            integration: SiteIntegration instance
            content_types: List of content types to sync (optional)
        
        Returns:
            dict: Sync result
        """
        try:
            if integration.platform == 'wordpress':
                return self._sync_from_wordpress(integration, content_types)
            elif integration.platform == 'shopify':
                return self._sync_from_shopify(integration, content_types)
            else:
                return {
                    'success': False,
                    'error': f'Sync from {integration.platform} not implemented',
                    'synced_count': 0
                }
        except Exception as e:
            logger.error(
                f"[ContentSyncService] Error syncing from {integration.platform}: {str(e)}",
                exc_info=True
            )
            return {
                'success': False,
                'error': str(e),
                'synced_count': 0
            }
    
    def _sync_to_wordpress(
        self,
        integration: SiteIntegration,
        content_types: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Sync content from IGNY8 to WordPress.
        Stage 4: Enhanced to sync taxonomies before content.
        
        Args:
            integration: SiteIntegration instance
            content_types: List of content types to sync
        
        Returns:
            dict: Sync result
        """
        try:
            # Get WordPress client
            credentials = integration.get_credentials()
            client = WordPressClient(
                site_url=integration.config_json.get('site_url', ''),
                username=credentials.get('username'),
                app_password=credentials.get('app_password')
            )
            
            # Stage 4: Sync taxonomies first
            taxonomy_result = self._sync_taxonomies_to_wordpress(integration, client)
            
            # Sync content (posts/products)
            from igny8_core.business.content.models import Content
            from igny8_core.business.publishing.services.adapters.wordpress_adapter import WordPressAdapter
            
            content_query = Content.objects.filter(
                account=integration.account,
                site=integration.site,
                source='igny8',
                status='publish'
            )
            
            if content_types:
                content_query = content_query.filter(content_type__in=content_types)
            
            synced_count = 0
            adapter = WordPressAdapter()
            destination_config = {
                'site_url': integration.config_json.get('site_url', ''),
                'username': credentials.get('username'),
                'app_password': credentials.get('app_password'),
                'status': 'publish'
            }
            
            for content in content_query[:100]:  # Limit to 100 per sync
                result = adapter.publish(content, destination_config)
                if result.get('success'):
                    synced_count += 1
                    # Store external reference
                    if not content.metadata:
                        content.metadata = {}
                    content.metadata['wordpress_id'] = result.get('external_id')
                    content.save(update_fields=['metadata'])
            
            return {
                'success': True,
                'synced_count': synced_count,
                'taxonomies_synced': taxonomy_result.get('synced_count', 0),
                'message': f'Synced {synced_count} content items and {taxonomy_result.get("synced_count", 0)} taxonomies'
            }
        except Exception as e:
            logger.error(
                f"[ContentSyncService] Error syncing to WordPress: {str(e)}",
                exc_info=True
            )
            return {
                'success': False,
                'error': str(e),
                'synced_count': 0
            }
    
    def sync_from_wordpress(
        self,
        integration: SiteIntegration
    ) -> Dict[str, Any]:
        """
        STAGE 3: Sync content from WordPress to IGNY8 using final Stage 1 schema.
        
        Args:
            integration: SiteIntegration instance
        
        Returns:
            dict: Sync result with synced_count
        """
        try:
            posts = self._fetch_wordpress_posts(integration)
            synced_count = 0
            
            from igny8_core.business.content.models import Content, ContentTaxonomy
            
            # Get default cluster if available
            from igny8_core.business.planning.models import Clusters
            default_cluster = Clusters.objects.filter(
                site=integration.site,
                name__icontains='imported'
            ).first()
            
            for post in posts:
                # Map WP post type to content_type
                wp_type = post.get('type', 'post')
                content_type = self._map_wp_post_type(wp_type)
                
                # Check if content already exists by external_id
                existing = Content.objects.filter(
                    site=integration.site,
                    external_id=str(post.get('id')),
                    source='wordpress'
                ).first()
                
                if existing:
                    # Update existing content
                    existing.title = post.get('title', {}).get('rendered', '') or post.get('title', '')
                    existing.content_html = post.get('content', {}).get('rendered', '') or post.get('content', '')
                    existing.external_url = post.get('link', '')
                    existing.status = 'published' if post.get('status') == 'publish' else 'draft'
                    existing.save()
                    content = existing
                else:
                    # Create new content
                    content = Content.objects.create(
                        account=integration.account,
                        site=integration.site,
                        sector=integration.site.sectors.first() if hasattr(integration.site, 'sectors') else None,
                        title=post.get('title', {}).get('rendered', '') or post.get('title', ''),
                        content_html=post.get('content', {}).get('rendered', '') or post.get('content', ''),
                        cluster=default_cluster,
                        content_type=content_type,
                        content_structure='article',  # Default, can be refined
                        source='wordpress',
                        status='published' if post.get('status') == 'publish' else 'draft',
                        external_id=str(post.get('id')),
                        external_url=post.get('link', ''),
                    )
                
                # Sync taxonomies (categories and tags)
                self._sync_post_taxonomies(content, post, integration)
                
                synced_count += 1
            
            return {
                'success': True,
                'synced_count': synced_count
            }
        except Exception as e:
            logger.error(
                f"[ContentSyncService] Error syncing from WordPress: {str(e)}",
                exc_info=True
            )
            return {
                'success': False,
                'error': str(e),
                'synced_count': 0
            }
    
    def _sync_from_wordpress(
        self,
        integration: SiteIntegration,
        content_types: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Internal method for syncing from WordPress (used by sync_from_external).
        Stage 4: Enhanced to sync taxonomies and products.
        
        Args:
            integration: SiteIntegration instance
            content_types: List of content types to sync
        
        Returns:
            dict: Sync result
        """
        try:
            # Get WordPress client
            credentials = integration.get_credentials()
            client = WordPressClient(
                site_url=integration.config_json.get('site_url', ''),
                username=credentials.get('username'),
                app_password=credentials.get('app_password')
            )
            
            # Stage 4: Sync taxonomies first
            taxonomy_result = self._sync_taxonomies_from_wordpress(integration, client)
            
            # Sync posts
            posts_result = self.sync_from_wordpress(integration)
            
            # Sync WooCommerce products if available
            products_result = self._sync_products_from_wordpress(integration, client)
            
            total_synced = (
                posts_result.get('synced_count', 0) +
                products_result.get('synced_count', 0)
            )
            
            return {
                'success': True,
                'synced_count': total_synced,
                'taxonomies_synced': taxonomy_result.get('synced_count', 0),
                'posts_synced': posts_result.get('synced_count', 0),
                'products_synced': products_result.get('synced_count', 0),
            }
        except Exception as e:
            logger.error(
                f"[ContentSyncService] Error syncing from WordPress: {str(e)}",
                exc_info=True
            )
            return {
                'success': False,
                'error': str(e),
                'synced_count': 0
            }
    
    def _fetch_wordpress_posts(
        self,
        integration: SiteIntegration
    ) -> List[Dict[str, Any]]:
        """
        Fetch posts from WordPress.
        
        Args:
            integration: SiteIntegration instance
        
        Returns:
            List of post dictionaries
        """
        try:
            credentials = integration.get_credentials()
            client = WordPressClient(
                site_url=integration.config_json.get('site_url', ''),
                username=credentials.get('username'),
                app_password=credentials.get('app_password')
            )
            
            # Fetch posts via WordPress REST API
            import requests
            response = client.session.get(
                f"{client.api_base}/posts",
                params={'per_page': 100, 'status': 'publish'}
            )
            
            if response.status_code == 200:
                posts = response.json()
                return [
                    {
                        'id': post.get('id'),
                        'title': post.get('title', {}).get('rendered', ''),
                        'content': post.get('content', {}).get('rendered', ''),
                        'status': post.get('status', 'publish'),
                        'categories': post.get('categories', []),
                        'tags': post.get('tags', [])
                    }
                    for post in posts
                ]
            return []
        except Exception as e:
            logger.error(f"Error fetching WordPress posts: {e}")
            return []
    
    # Stage 4: Taxonomy Sync Methods
    
    def _sync_taxonomies_from_wordpress(
        self,
        integration: SiteIntegration,
        client: WordPressClient
    ) -> Dict[str, Any]:
        """
        Sync taxonomies from WordPress to IGNY8.
        
        Args:
            integration: SiteIntegration instance
            client: WordPressClient instance
        
        Returns:
            dict: Sync result with synced_count
        """
        try:
            from igny8_core.business.site_building.models import SiteBlueprint
            from igny8_core.business.site_building.services.taxonomy_service import TaxonomyService
            
            # Get or create site blueprint for this site
            blueprint = SiteBlueprint.objects.filter(
                account=integration.account,
                site=integration.site
            ).first()
            
            if not blueprint:
                logger.warning(f"No blueprint found for site {integration.site.id}, skipping taxonomy sync")
                return {'success': True, 'synced_count': 0}
            
            taxonomy_service = TaxonomyService()
            synced_count = 0
            
            # Sync WordPress categories
            categories = client.get_categories(per_page=100)
            category_records = [
                {
                    'name': cat['name'],
                    'slug': cat['slug'],
                    'description': cat.get('description', ''),
                    'taxonomy_type': 'blog_category',
                    'external_reference': str(cat['id']),
                    'metadata': {'parent': cat.get('parent', 0)}
                }
                for cat in categories
            ]
            if category_records:
                taxonomy_service.import_from_external(
                    blueprint,
                    category_records,
                    default_type='blog_category'
                )
                synced_count += len(category_records)
            
            # Sync WordPress tags
            tags = client.get_tags(per_page=100)
            tag_records = [
                {
                    'name': tag['name'],
                    'slug': tag['slug'],
                    'description': tag.get('description', ''),
                    'taxonomy_type': 'blog_tag',
                    'external_reference': str(tag['id'])
                }
                for tag in tags
            ]
            if tag_records:
                taxonomy_service.import_from_external(
                    blueprint,
                    tag_records,
                    default_type='blog_tag'
                )
                synced_count += len(tag_records)
            
            # Sync WooCommerce product categories if available (401 is expected if WooCommerce not installed or credentials missing)
            try:
                product_categories = client.get_product_categories(per_page=100)
                product_category_records = [
                    {
                        'name': cat['name'],
                        'slug': cat['slug'],
                        'description': cat.get('description', ''),
                        'taxonomy_type': 'product_category',
                        'external_reference': f"wc_cat_{cat['id']}",
                        'metadata': {'parent': cat.get('parent', 0)}
                    }
                    for cat in product_categories
                ]
                if product_category_records:
                    taxonomy_service.import_from_external(
                        blueprint,
                        product_category_records,
                        default_type='product_category'
                    )
                    synced_count += len(product_category_records)
            except Exception as e:
                # Silently skip WooCommerce if not available (401 means no consumer key/secret configured or plugin not installed)
                logger.debug(f"WooCommerce product categories not available: {e}")
            
            return {
                'success': True,
                'synced_count': synced_count
            }
        except Exception as e:
            logger.error(f"Error syncing taxonomies from WordPress: {e}", exc_info=True)
            return {
                'success': False,
                'error': str(e),
                'synced_count': 0
            }
    
    def _sync_taxonomies_to_wordpress(
        self,
        integration: SiteIntegration,
        client: WordPressClient
    ) -> Dict[str, Any]:
        """
        DEPRECATED: Legacy SiteBlueprint taxonomy sync removed.
        Taxonomy management now uses ContentTaxonomy model.
        """
        return {'success': True, 'synced_count': 0}
    
    def _sync_products_from_wordpress(
        self,
        integration: SiteIntegration,
        client: WordPressClient
    ) -> Dict[str, Any]:
        """
        Sync WooCommerce products from WordPress to IGNY8.
        
        Args:
            integration: SiteIntegration instance
            client: WordPressClient instance
        
        Returns:
            dict: Sync result with synced_count
        """
        try:
            products = client.get_products(per_page=100)
            synced_count = 0
            
            from igny8_core.business.content.models import Content
            
            for product in products:
                content, created = Content.objects.get_or_create(
                    account=integration.account,
                    site=integration.site,
                    sector=integration.site.sectors.first() if hasattr(integration.site, 'sectors') else None,
                    title=product.get('name', ''),
                    source='wordpress',
                    defaults={
                        'html_content': product.get('description', ''),
                        'content_type': 'product',
                        'status': 'published' if product.get('status') == 'publish' else 'draft',
                        'metadata': {
                            'wordpress_id': product.get('id'),
                            'product_type': product.get('type'),
                            'sku': product.get('sku'),
                            'price': product.get('price'),
                            'regular_price': product.get('regular_price'),
                            'sale_price': product.get('sale_price'),
                            'categories': product.get('categories', []),
                            'tags': product.get('tags', []),
                            'attributes': product.get('attributes', [])
                        }
                    }
                )
                
                if not created:
                    content.html_content = product.get('description', '')
                    if not content.metadata:
                        content.metadata = {}
                    content.metadata.update({
                        'wordpress_id': product.get('id'),
                        'product_type': product.get('type'),
                        'sku': product.get('sku'),
                        'price': product.get('price'),
                        'regular_price': product.get('regular_price'),
                        'sale_price': product.get('sale_price'),
                        'categories': product.get('categories', []),
                        'tags': product.get('tags', []),
                        'attributes': product.get('attributes', [])
                    })
                    content.save()
                
                synced_count += 1
            
            return {
                'success': True,
                'synced_count': synced_count
            }
        except Exception as e:
            # Silently skip products if WooCommerce auth fails (expected if consumer key/secret not configured)
            logger.debug(f"WooCommerce products not synced: {e}")
            return {
                'success': True,
                'synced_count': 0
            }
    
    def _sync_to_shopify(
        self,
        integration: SiteIntegration,
        content_types: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Sync content from IGNY8 to Shopify.
        
        Args:
            integration: SiteIntegration instance
            content_types: List of content types to sync
        
        Returns:
            dict: Sync result
        """
        # TODO: Implement Shopify sync
        logger.info(f"[ContentSyncService] Syncing to Shopify for integration {integration.id}")
        
        return {
            'success': True,
            'synced_count': 0,
            'message': 'Shopify sync not yet implemented'
        }
    
    def sync_from_shopify(
        self,
        integration: SiteIntegration
    ) -> Dict[str, Any]:
        """
        Sync content from Shopify to IGNY8.
        
        Args:
            integration: SiteIntegration instance
        
        Returns:
            dict: Sync result with synced_count
        """
        try:
            products = self._fetch_shopify_products(integration)
            synced_count = 0
            
            from igny8_core.business.content.models import Content
            
            for product in products:
                # Create or update content from product
                content, created = Content.objects.get_or_create(
                    account=integration.account,
                    site=integration.site,
                    sector=integration.site.sectors.first() if hasattr(integration.site, 'sectors') else None,
                    title=product.get('title', ''),
                    source='shopify',
                    defaults={
                        'html_content': product.get('body_html', ''),
                        'status': 'published',
                        'metadata': {'shopify_id': product.get('id')}
                    }
                )
                
                if not created:
                    content.html_content = product.get('body_html', '')
                    if not content.metadata:
                        content.metadata = {}
                    content.metadata['shopify_id'] = product.get('id')
                    content.save()
                
                synced_count += 1
            
            return {
                'success': True,
                'synced_count': synced_count
            }
        except Exception as e:
            logger.error(
                f"[ContentSyncService] Error syncing from Shopify: {str(e)}",
                exc_info=True
            )
            return {
                'success': False,
                'error': str(e),
                'synced_count': 0
            }
    
    def _map_wp_post_type(self, wp_type: str) -> str:
        """
        STAGE 3: Map WordPress post type to IGNY8 content_type.
        
        Args:
            wp_type: WordPress post type (post, page, product, etc.)
        
        Returns:
            str: Mapped content_type
        """
        mapping = {
            'post': 'post',
            'page': 'page',
            'product': 'product',
            'service': 'service',
            # Add more mappings as needed
        }
        return mapping.get(wp_type, 'post')
    
    def _sync_post_taxonomies(
        self,
        content,
        post: Dict[str, Any],
        integration: SiteIntegration
    ) -> None:
        """
        STAGE 3: Sync taxonomies (categories, tags) for a WordPress post.
        
        Args:
            content: Content instance
            post: WordPress post data
            integration: SiteIntegration instance
        """
        from igny8_core.business.content.models import ContentTaxonomy
        
        # Sync categories
        for cat_id in post.get('categories', []):
            taxonomy, _ = ContentTaxonomy.objects.get_or_create(
                site=integration.site,
                external_id=cat_id,
                external_taxonomy='category',
                defaults={
                    'name': f'Category {cat_id}',  # Will be updated later
                    'slug': f'category-{cat_id}',
                    'taxonomy_type': 'category',
                    'account': integration.account,
                    'sector': integration.site.sectors.first() if hasattr(integration.site, 'sectors') else None,
                }
            )
            content.taxonomy_terms.add(taxonomy)
        
        # Sync tags
        for tag_id in post.get('tags', []):
            taxonomy, _ = ContentTaxonomy.objects.get_or_create(
                site=integration.site,
                external_id=tag_id,
                external_taxonomy='post_tag',
                defaults={
                    'name': f'Tag {tag_id}',  # Will be updated later
                    'slug': f'tag-{tag_id}',
                    'taxonomy_type': 'tag',
                    'account': integration.account,
                    'sector': integration.site.sectors.first() if hasattr(integration.site, 'sectors') else None,
                }
            )
            content.taxonomy_terms.add(taxonomy)
    
    def _sync_from_shopify(
        self,
        integration: SiteIntegration,
        content_types: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Internal method for syncing from Shopify (used by sync_from_external).
        
        Args:
            integration: SiteIntegration instance
            content_types: List of content types to sync
        
        Returns:
            dict: Sync result
        """
        return self.sync_from_shopify(integration)
    
    def _fetch_shopify_products(
        self,
        integration: SiteIntegration
    ) -> List[Dict[str, Any]]:
        """
        Fetch products from Shopify.
        
        Args:
            integration: SiteIntegration instance
        
        Returns:
            List of product dictionaries
        """
        # TODO: Implement actual Shopify API call
        # For now, return empty list - tests will mock this
        logger.info(f"[ContentSyncService] Fetching Shopify products for integration {integration.id}")
        return []

