"""
IGNY8 Content Publishing Celery Tasks

Handles automated publishing of content from IGNY8 to WordPress sites.
"""
from celery import shared_task
from django.conf import settings
from django.utils import timezone
from datetime import timedelta
import requests
import logging
from typing import Dict, List, Any, Optional

logger = logging.getLogger(__name__)
publish_logger = logging.getLogger('publish_sync')
api_logger = logging.getLogger('wordpress_api')


@shared_task(bind=True, max_retries=3)
def publish_content_to_wordpress(self, content_id: int, site_integration_id: int, task_id: Optional[int] = None) -> Dict[str, Any]:
    """
    Publish a single content item to WordPress
    
    Args:
        content_id: IGNY8 content ID
        site_integration_id: WordPress site integration ID
        task_id: Optional IGNY8 task ID
        
    Returns:
        Dict with success status and details
    """
    try:
        from igny8_core.business.content.models import Content
        from igny8_core.business.integration.models import SiteIntegration
        
        publish_logger.info("="*80)
        publish_logger.info(f"🎯 PUBLISH WORKFLOW STARTED")
        publish_logger.info(f"   Content ID: {content_id}")
        publish_logger.info(f"   Site Integration ID: {site_integration_id}")
        publish_logger.info(f"   Task ID: {task_id}")
        publish_logger.info("="*80)
        
        # Get content and site integration
        try:
            publish_logger.info(f"STEP 1: Loading content and integration from database...")
            content = Content.objects.get(id=content_id)
            publish_logger.info(f"   ✅ Content loaded: '{content.title}'")
            publish_logger.info(f"      - Status: {content.status}")
            publish_logger.info(f"      - Type: {content.content_type}")
            publish_logger.info(f"      - Site: {content.site.name if content.site else 'None'}")
            
            site_integration = SiteIntegration.objects.get(id=site_integration_id)
            publish_logger.info(f"   ✅ Integration loaded:")
            publish_logger.info(f"      - Platform: {site_integration.platform}")
            publish_logger.info(f"      - Site: {site_integration.site.name}")
            publish_logger.info(f"      - Base URL: {site_integration.base_url}")
        except (Content.DoesNotExist, SiteIntegration.DoesNotExist) as e:
            publish_logger.error(f"   ❌ Database lookup failed: {e}")
            return {"success": False, "error": str(e)}
        
        # Check if content is already published
        if content.external_id:
            logger.info(f"[publish_content_to_wordpress] ⚠️ Content {content_id} already published: external_id={content.external_id}")
            return {"success": True, "message": "Already published", "external_id": content.external_id}
        
        logger.info(f"[publish_content_to_wordpress] 📦 Preparing content payload...")
        logger.info(f"[publish_content_to_wordpress] Content title: '{content.title}'")
        logger.info(f"[publish_content_to_wordpress] Content status: '{content.status}'")
        logger.info(f"[publish_content_to_wordpress] Content type: '{content.content_type}'")
        
        # Prepare content data for WordPress
        # Generate excerpt from content_html (Content model has no 'brief' field)
        excerpt = ''
        if content.content_html:
            from django.utils.html import strip_tags
            excerpt = strip_tags(content.content_html)[:150].strip()
            if len(content.content_html) > 150:
                excerpt += '...'
            logger.info(f"[publish_content_to_wordpress] Content HTML length: {len(content.content_html)} chars")
        else:
            logger.warning(f"[publish_content_to_wordpress] ⚠️ No content_html found!")
        
        # Get taxonomy terms from ContentTaxonomyMap
        from igny8_core.business.content.models import ContentTaxonomyMap
        taxonomy_maps = ContentTaxonomyMap.objects.filter(content=content).select_related('taxonomy')
        logger.info(f"[publish_content_to_wordpress] Found {taxonomy_maps.count()} taxonomy mappings")
        
        # Build categories and tags arrays from taxonomy mappings
        categories = []
        tags = []
        for mapping in taxonomy_maps:
            tax = mapping.taxonomy
            if tax:
                # Add taxonomy term name to categories (will be mapped in WordPress)
                categories.append(tax.name)
                logger.info(f"[publish_content_to_wordpress] 📁 Added category: '{tax.name}'")
        
        # Get images from Images model
        from igny8_core.modules.writer.models import Images
        featured_image_url = None
        gallery_images = []
        
        images = Images.objects.filter(content=content).order_by('position')
        logger.info(f"[publish_content_to_wordpress] Found {images.count()} images for content")
        
        for image in images:
            if image.image_type == 'featured' and image.image_url:
                featured_image_url = image.image_url
                logger.info(f"[publish_content_to_wordpress] 🖼️ Featured image: {image.image_url[:100]}")
            elif image.image_type == 'in_article' and image.image_url:
                gallery_images.append({
                    'url': image.image_url,
                    'alt': image.alt_text or '',
        # Add primary and secondary keywords as tags
        if content.primary_keyword:
            tags.append(content.primary_keyword)
            logger.info(f"[publish_content_to_wordpress] 🏷️ Primary keyword (tag): '{content.primary_keyword}'")
        else:
            logger.info(f"[publish_content_to_wordpress] No primary keyword found")
        
        if content.secondary_keywords:
            if isinstance(content.secondary_keywords, list):
                tags.extend(content.secondary_keywords)
                logger.info(f"[publish_content_to_wordpress] 🏷️ Added {len(content.secondary_keywords)} secondary keywords as tags")
            elif isinstance(content.secondary_keywords, str):
                import json
                try:
                    keywords = json.loads(content.secondary_keywords)
                    if isinstance(keywords, list):
                        tags.extend(keywords)
                        logger.info(f"[publish_content_to_wordpress] 🏷️ Added {len(keywords)} secondary keywords as tags (from JSON)")
                except (json.JSONDecodeError, TypeError):
                    logger.warning(f"[publish_content_to_wordpress] Failed to parse secondary_keywords as JSON")
        else:
            logger.info(f"[publish_content_to_wordpress] No secondary keywords found")
        
        logger.info(f"[publish_content_to_wordpress] 📊 TOTAL: {len(categories)} categories, {len(tags)} tags")ords = json.loads(content.secondary_keywords)
                    if isinstance(keywords, list):
                        tags.extend(keywords)
                except (json.JSONDecodeError, TypeError):
                    pass
        
        content_data = {
            'content_id': content.id,
            'task_id': task_id,
            'title': content.title,
            'content_html': content.content_html or '',
            'excerpt': excerpt,
            'status': 'publish',
            # Content model has no author field - use site default author in WordPress
            'author_email': None,
            'author_name': None,
            # Content model has no published_at - WordPress will use current time
            'published_at': None,
            # Use correct Content model field names
            'seo_title': content.meta_title or '',
            'seo_description': content.meta_description or '',
            'primary_keyword': content.primary_keyword or '',
            'secondary_keywords': content.secondary_keywords or [],
            # Send featured image URL from Images model
            'featured_image_url': featured_image_url,
            'gallery_images': gallery_images,
            # Send cluster and sector IDs (Content has ForeignKey to cluster, not many-to-many)
            'cluster_id': content.cluster.id if content.cluster else None,
            'sector_id': content.sector.id if content.sector else None,
            # Send categories and tags from taxonomy mappings and keywords
            'categories': categories,
            'tags': tags,
            # Keep for backward compatibility
            'sectors': [],
            'clusters': []
        logger.info(f"[publish_content_to_wordpress] 🚀 POSTing to WordPress: {wordpress_url}")
        logger.info(f"[publish_content_to_wordpress] 📦 Payload summary:")
        logger.info(f"  - Categories: {categories}")
        logger.info(f"  - Tags: {tags}")
        logger.info(f"  - Featured image: {'Yes' if featured_image_url else 'No'}")
        logger.info(f"  - Gallery images: {len(gallery_images)}")
        logger.info(f"  - SEO title: {'Yes' if content_data.get('seo_title') else 'No'}")
        logger.info(f"  - SEO description: {'Yes' if content_data.get('seo_description') else 'No'}")
        
        response = requests.post(
            wordpress_url,
            json=content_data,
            headers=headers,
            timeout=30
            # Update external_id and external_url for unified Content model
            old_status = content.status
            content.external_id = wp_data.get('post_id')
            content.external_url = wp_data.get('post_url')
            content.status = 'published'
            content.save(update_fields=[
                'external_id', 'external_url', 'status', 'updated_at'
            ])
            logger.info(f"[publish_content_to_wordpress] 💾 Content model updated:")
            logger.info(f"  - Status: '{old_status}' → 'published'")
            logger.info(f"  - External ID: {content.external_id}")
            logger.info(f"  - External URL: {content.external_url}")
            wordpress_url,
            json=content_data,
            headers=headers,
            timeout=30
        )
        logger.info(f"[publish_content_to_wordpress] 📬 WordPress response: status={response.status_code}")
        
        # Track start time for duration measurement
        import time
        from igny8_core.business.integration.models import SyncEvent
        start_time = time.time()
        
        if response.status_code == 201:
            # Success
            wp_data = response.json().get('data', {})
            wp_status = wp_data.get('post_status', 'publish')
            logger.info(f"[publish_content_to_wordpress] ✅ WordPress post created successfully: post_id={wp_data.get('post_id')}, status={wp_status}")
            
            # Update external_id, external_url, and wordpress_status in Content model
            content.external_id = str(wp_data.get('post_id'))
            content.external_url = wp_data.get('post_url')
            content.status = 'published'
            
            # Add wordpress_status field to Content model metadata
            if not hasattr(content, 'metadata') or content.metadata is None:
                content.metadata = {}
            content.metadata['wordpress_status'] = wp_status
            
            content.save(update_fields=[
                'external_id', 'external_url', 'status', 'metadata', 'updated_at'
            ])
            logger.info(f"[publish_content_to_wordpress] 💾 Content model updated:")
            logger.info(f"  - External ID: {content.external_id}")
            logger.info(f"  - External URL: {content.external_url}")
            logger.info(f"  - Status: published")
            logger.info(f"  - WordPress Status: {wp_status}")
            
            # Log sync event
            duration_ms = int((time.time() - start_time) * 1000)
            SyncEvent.objects.create(
                integration=site_integration,
                site=content.site,
                account=content.account,
                event_type='publish',
                action='content_publish',
                description=f"Published content '{content.title}' to WordPress",
                success=True,
                content_id=content.id,
                external_id=str(content.external_id),
                details={
                    'post_url': content.external_url,
                    'wordpress_status': wp_status,
                    'categories': categories,
                    'tags': tags,
                    'has_featured_image': bool(featured_image_url),
                    'gallery_images_count': len(gallery_images),
                },
                duration_ms=duration_ms
            )
            
            logger.info(f"[publish_content_to_wordpress] 🎉 Successfully published content {content_id} to WordPress post {content.external_id}")
            return {
                "success": True,
                "external_id": content.external_id,
                "external_url": content.external_url,
                "wordpress_status": wp_status
            }
            
        elif response.status_code == 409:
            # Content already exists
            wp_data = response.json().get('data', {})
            wp_status = wp_data.get('post_status', 'publish')
            content.external_id = str(wp_data.get('post_id'))
            content.external_url = wp_data.get('post_url')
            content.status = 'published'
            
            # Update wordpress_status in metadata
            if not hasattr(content, 'metadata') or content.metadata is None:
                content.metadata = {}
            content.metadata['wordpress_status'] = wp_status
            
            content.save(update_fields=[
                'external_id', 'external_url', 'status', 'metadata', 'updated_at'
            ])
            
            # Log sync event
            duration_ms = int((time.time() - start_time) * 1000)
            SyncEvent.objects.create(
                integration=site_integration,
                site=content.site,
                account=content.account,
                event_type='sync',
                action='content_publish',
                description=f"Content '{content.title}' already exists in WordPress",
                success=True,
                content_id=content.id,
                external_id=str(content.external_id),
                details={
                    'post_url': content.external_url,
                    'wordpress_status': wp_status,
                    'already_exists': True,
                },
                duration_ms=duration_ms
            )
            
            logger.info(f"Content {content_id} already exists on WordPress")
            return {
                "success": True,
                "message": "Content already exists",
                "external_id": content.external_id,
                "wordpress_status": wp_status
            }
            
        else:
            # Error
            error_msg = f"WordPress API error: {response.status_code} - {response.text}"
            logger.error(f"[publish_content_to_wordpress] ❌ {error_msg}")
            
            # Log sync event for failure
            duration_ms = int((time.time() - start_time) * 1000)
            SyncEvent.objects.create(
                integration=site_integration,
                site=content.site,
                account=content.account,
                event_type='error',
                action='content_publish',
                description=f"Failed to publish content '{content.title}' to WordPress",
                success=False,
                content_id=content.id,
                error_message=error_msg,
                details={
                    'status_code': response.status_code,
                    'response_text': response.text[:500],  # Limit length
                },
                duration_ms=duration_ms
            )
            
            # Retry logic
            if self.request.retries < self.max_retries:
                # Exponential backoff: 1min, 5min, 15min
                countdown = 60 * (5 ** self.request.retries)
                logger.warning(f"[publish_content_to_wordpress] 🔄 Retrying (attempt {self.request.retries + 1}/{self.max_retries}) in {countdown}s")
                raise self.retry(countdown=countdown, exc=Exception(error_msg))
            else:
                # Max retries reached - mark as failed
                logger.error(f"[publish_content_to_wordpress] ❌ Max retries reached, giving up")
                return {"success": False, "error": error_msg}
                
    except Exception as e:
        logger.error(f"[publish_content_to_wordpress] ❌ Exception during publish: {str(e)}", exc_info=True)
        
        # Log sync event for exception
        try:
            from igny8_core.business.integration.models import SyncEvent
            import time
            
            SyncEvent.objects.create(
                integration=site_integration,
                site=content.site,
                account=content.account,
                event_type='error',
                action='content_publish',
                description=f"Exception while publishing content '{content.title}' to WordPress",
                success=False,
                content_id=content.id,
                error_message=str(e),
                details={
                    'exception_type': type(e).__name__,
                    'traceback': str(e),
                },
            )
        except Exception as log_error:
            logger.error(f"Failed to log sync event: {str(log_error)}")
        
        return {"success": False, "error": str(e)}


@shared_task
def process_pending_wordpress_publications() -> Dict[str, Any]:
    """
    Process all content items pending WordPress publication
    Runs every 5 minutes
    """
    try:
        from igny8_core.business.content.models import Content
        from igny8_core.business.integration.models import SiteIntegration
        
        # Find content marked for WordPress publishing (status = published, external_id = empty)
        pending_content = Content.objects.filter(
            status='published',
            external_id__isnull=True
        ).select_related('site', 'sector', 'cluster')
        
        if not pending_content.exists():
            logger.info("No content pending WordPress publication")
            return {"success": True, "processed": 0}
        
        # Get active WordPress integrations
        active_integrations = SiteIntegration.objects.filter(
            platform='wordpress',
            is_active=True
        )
        
        if not active_integrations.exists():
            logger.warning("No active WordPress integrations found")
            return {"success": False, "error": "No active WordPress integrations"}
        
        processed = 0
        
        for content in pending_content[:50]:  # Process max 50 at a time
            for integration in active_integrations.filter(site=content.site):
                # Queue individual publish task
                publish_content_to_wordpress.delay(
                    content.id,
                    integration.id
                )
                processed += 1
                break  # Only queue with first matching integration
        
        logger.info(f"Queued {processed} content items for WordPress publication")
        return {"success": True, "processed": processed}
        
    except Exception as e:
        logger.error(f"Error processing pending WordPress publications: {str(e)}", exc_info=True)
        return {"success": False, "error": str(e)}


@shared_task
def bulk_publish_content_to_wordpress(content_ids: List[int], site_integration_id: int) -> Dict[str, Any]:
    """
    Bulk publish multiple content items to WordPress
    Used for manual bulk operations from Content Manager
    """
    try:
        from igny8_core.business.content.models import Content
        from igny8_core.business.integration.models import SiteIntegration
        
        site_integration = SiteIntegration.objects.get(id=site_integration_id)
        content_items = Content.objects.filter(id__in=content_ids)
        
        results = {
            "success": True,
            "total": len(content_ids),
            "queued": 0,
            "skipped": 0,
            "errors": []
        }
        
        for content in content_items:
            try:
                # Skip if already published
                if content.external_id:
                    results["skipped"] += 1
                    continue
                
                # Queue individual publish task
                publish_content_to_wordpress.delay(
                    content.id,
                    site_integration.id
                )
                results["queued"] += 1
                
            except Exception as e:
                results["errors"].append(f"Content {content.id}: {str(e)}")
        
        if results["errors"]:
            results["success"] = len(results["errors"]) < results["total"] / 2
        
        logger.info(f"Bulk publish: {results['queued']} queued, {results['skipped']} skipped, {len(results['errors'])} errors")
        return results
        
    except Exception as e:
        logger.error(f"Error in bulk publish: {str(e)}", exc_info=True)
        return {"success": False, "error": str(e)}


@shared_task
def wordpress_status_reconciliation() -> Dict[str, Any]:
    """
    Daily task to verify published content still exists on WordPress
    Checks for discrepancies and fixes them
    """
    try:
        from igny8_core.business.content.models import Content
        
        # Get content marked as published
        published_content = Content.objects.filter(
            external_id__isnull=False
        )[:100]  # Limit to prevent timeouts
        
        logger.info(f"Status reconciliation: Checking {len(published_content)} published items")
        return {"success": True, "checked": len(published_content)}
        
    except Exception as e:
        logger.error(f"Error in status reconciliation: {str(e)}", exc_info=True)
        return {"success": False, "error": str(e)}


@shared_task
def retry_failed_wordpress_publications() -> Dict[str, Any]:
    """
    Retry failed WordPress publications (runs daily)
    For future use when we implement failure tracking
    """
    try:
        logger.info("Retry task: No failure tracking currently implemented")
        return {"success": True, "retried": 0}
        
    except Exception as e:
        logger.error(f"Error retrying failed publications: {str(e)}", exc_info=True)
        return {"success": False, "error": str(e)}