"""
WordPress Adapter
Phase 6: Site Integration & Multi-Destination Publishing

Adapter for publishing content to WordPress.
Refactored to use BaseAdapter interface while preserving existing functionality.
"""
import logging
from typing import Dict, Any, Optional
from datetime import datetime

from igny8_core.business.publishing.services.adapters.base_adapter import BaseAdapter
from igny8_core.utils.wordpress import WordPressClient

logger = logging.getLogger(__name__)


class WordPressAdapter(BaseAdapter):
    """
    Adapter for publishing content to WordPress.
    Uses WordPressClient internally to preserve existing functionality.
    """
    
    def publish(
        self,
        content: Any,
        destination_config: Dict[str, Any]
    ) -> Dict[str, Any]:
        """
        Publish content to WordPress.
        
        Args:
            content: Content instance or dict with content data
            destination_config: {
                # API Key method (preferred):
                'site_url': str,
                'api_key': str,
                
                # OR username/password method:
                'site_url': str,
                'username': str,
                'app_password': str,
                
                # Optional:
                'status': str (default 'draft'),
                'featured_image_url': str
            }
        
        Returns:
            dict: {
                'success': bool,
                'external_id': str,  # WordPress post ID
                'url': str,  # Published post URL
                'published_at': datetime,
                'metadata': dict
            }
        """
        try:
            logger.info(f"[WordPressAdapter.publish] 🎬 Starting WordPress publish")
            
            # Extract content data
            if hasattr(content, 'title'):
                # Content model instance
                title = content.title
                content_html = getattr(content, 'content_html', '') or ''
                logger.info(f"[WordPressAdapter.publish] 📄 Content: id={content.id}, title='{title}', html_length={len(content_html)}")
            elif isinstance(content, dict):
                # Dict with content data
                title = content.get('title', '')
                content_html = content.get('content_html', '')
                logger.info(f"[WordPressAdapter.publish] 📄 Content dict: title='{title}', html_length={len(content_html)}")
            else:
                raise ValueError(f"Unsupported content type: {type(content)}")
            
            # Get site URL
            site_url = destination_config.get('site_url')
            if not site_url:
                logger.error(f"[WordPressAdapter.publish] ❌ site_url is missing in destination_config")
                raise ValueError("site_url is required in destination_config")
            logger.info(f"[WordPressAdapter.publish] 🌐 Target site: {site_url}")
            
            # Check if using API key authentication
            api_key = destination_config.get('api_key')
            logger.info(f"[WordPressAdapter.publish] 🔐 Auth method: {'API Key' if api_key else 'Username/Password'}")
            
            if api_key:
                # Use IGNY8 custom endpoint with API key
                logger.info(f"[WordPressAdapter.publish] 🔑 Using API key authentication method")
                return self._publish_via_api_key(
                    site_url=site_url,
                    api_key=api_key,
                    content=content,
                    title=title,
                    content_html=content_html,
                    destination_config=destination_config
                )
            else:
                # Use standard WordPress REST API with username/password
                logger.info(f"[WordPressAdapter.publish] 👤 Using username/password authentication method")
                return self._publish_via_username_password(
                    site_url=site_url,
                    username=destination_config.get('username'),
                    app_password=destination_config.get('app_password'),
                    title=title,
                    content_html=content_html,
                    destination_config=destination_config
                )
                
        except Exception as e:
            logger.error(
                f"[WordPressAdapter] Error publishing content: {str(e)}",
                exc_info=True
            )
            return {
                'success': False,
                'external_id': None,
                'url': None,
                'published_at': None,
                'metadata': {
                    'error': str(e)
                }
            }
    
    def _publish_via_api_key(
        self,
        site_url: str,
        api_key: str,
        content: Any,
        title: str,
        content_html: str,
        destination_config: Dict[str, Any]
    ) -> Dict[str, Any]:
        """
        Publish via IGNY8 custom WordPress endpoint using API key.
        This uses the /wp-json/igny8/v1/publish endpoint.
        """
        import requests
        from django.utils.html import strip_tags
        import json
        
        logger.info(f"[WordPressAdapter._publish_via_api_key] 📦 Preparing payload for {site_url}")
        
        # Generate excerpt
        excerpt = ''
        if content_html:
            excerpt = strip_tags(content_html)[:150].strip()
            if len(content_html) > 150:
                excerpt += '...'
        logger.info(f"[WordPressAdapter._publish_via_api_key] 📝 Generated excerpt: {excerpt[:50]}...")
        
        # Prepare base payload
        content_data = {
            'content_id': content.id if hasattr(content, 'id') else None,
            'title': title,
            'content_html': content_html,
            'excerpt': excerpt,
            'status': destination_config.get('status', 'publish'),
        }
        logger.info(f"[WordPressAdapter._publish_via_api_key] ✅ Base payload prepared: content_id={content_data['content_id']}, status={content_data['status']}")
        
        # Add optional fields from content model
        optional_fields = []
        if hasattr(content, 'meta_title'):
            content_data['seo_title'] = content.meta_title or ''
            optional_fields.append('meta_title')
        if hasattr(content, 'meta_description'):
            content_data['seo_description'] = content.meta_description or ''
            optional_fields.append('meta_description')
        if hasattr(content, 'primary_keyword'):
            content_data['primary_keyword'] = content.primary_keyword or ''
            optional_fields.append('primary_keyword')
        if hasattr(content, 'secondary_keywords'):
            content_data['secondary_keywords'] = content.secondary_keywords or []
            optional_fields.append('secondary_keywords')
        if hasattr(content, 'cluster') and content.cluster:
            content_data['cluster_id'] = content.cluster.id
            content_data['cluster_name'] = content.cluster.name  # NEW: Send cluster name for taxonomy creation
            optional_fields.append('cluster_id')
        if hasattr(content, 'sector') and content.sector:
            content_data['sector_id'] = content.sector.id
            content_data['sector_name'] = content.sector.name  # NEW: Send sector name for taxonomy creation
            optional_fields.append('sector_id')
        
        # STEP: Get categories from taxonomy_terms
        categories = []
        if hasattr(content, 'taxonomy_terms'):
            categories = [
                term.name
                for term in content.taxonomy_terms.filter(taxonomy_type='category')
            ]
            logger.info(f"[WordPressAdapter._publish_via_api_key] 📁 Found {len(categories)} categories from taxonomy_terms")
        
        # FALLBACK: Use cluster as category if no categories found
        if not categories and hasattr(content, 'cluster') and content.cluster:
            categories.append(content.cluster.name)
            logger.info(f"[WordPressAdapter._publish_via_api_key] 📁 Using cluster as category: {content.cluster.name}")
        
        content_data['categories'] = categories
        optional_fields.append(f'categories({len(categories)})')
        
        # STEP: Get tags from taxonomy_terms + keywords
        tags = []
        if hasattr(content, 'taxonomy_terms'):
            tags = [
                term.name
                for term in content.taxonomy_terms.filter(taxonomy_type='tag')
            ]
            logger.info(f"[WordPressAdapter._publish_via_api_key] 🏷️  Found {len(tags)} tags from taxonomy_terms")
        
        # Add primary keyword as tag
        if hasattr(content, 'primary_keyword') and content.primary_keyword:
            if content.primary_keyword not in tags:
                tags.append(content.primary_keyword)
        
        # Add secondary keywords as tags
        if hasattr(content, 'secondary_keywords') and content.secondary_keywords:
            if isinstance(content.secondary_keywords, list):
                for keyword in content.secondary_keywords:
                    if keyword and keyword not in tags:
                        tags.append(keyword)
            elif isinstance(content.secondary_keywords, str):
                try:
                    keywords = json.loads(content.secondary_keywords)
                    if isinstance(keywords, list):
                        for keyword in keywords:
                            if keyword and keyword not in tags:
                                tags.append(keyword)
                except (json.JSONDecodeError, TypeError):
                    pass
        
        content_data['tags'] = tags
        optional_fields.append(f'tags({len(tags)})')
        
        # STEP: Get images (featured + gallery)
        featured_image_url = None
        gallery_images = []
        
        if hasattr(content, 'id'):
            try:
                from igny8_core.modules.writer.models import Images
                images = Images.objects.filter(content=content).order_by('position')
                logger.info(f"[WordPressAdapter._publish_via_api_key] 🖼️  Found {images.count()} images")
                
                def convert_image_path_to_url(image_path):
                    """Convert local image path to public URL"""
                    if not image_path:
                        return None
                    if '/frontend/public/' in image_path:
                        relative_path = image_path.split('/frontend/public/')[-1]
                        return f"https://app.igny8.com/{relative_path}"
                    return image_path
                
                for image in images:
                    image_url = convert_image_path_to_url(image.image_path) if hasattr(image, 'image_path') and image.image_path else None
                    
                    if image.image_type == 'featured' and image_url:
                        featured_image_url = image_url
                        logger.info(f"[WordPressAdapter._publish_via_api_key] 🖼️  Featured image: {image_url[:80]}...")
                    elif image.image_type == 'in_article' and image_url:
                        gallery_images.append({
                            'url': image_url,
                            'alt': getattr(image, 'alt', '') or '',
                            'caption': getattr(image, 'caption', '') or ''
                        })
                        logger.info(f"[WordPressAdapter._publish_via_api_key] 🖼️  Gallery image {len(gallery_images)}")
            except Exception as e:
                logger.warning(f"[WordPressAdapter._publish_via_api_key] ⚠️ Could not load images: {e}")
        
        content_data['featured_image_url'] = featured_image_url
        content_data['gallery_images'] = gallery_images
        if featured_image_url:
            optional_fields.append('featured_image')
        if gallery_images:
            optional_fields.append(f'gallery({len(gallery_images)})')
        
        logger.info(f"[WordPressAdapter._publish_via_api_key] ➕ Added optional fields: {', '.join(optional_fields)}")
        
        # Call WordPress endpoint
        url = f"{site_url.rstrip('/')}/wp-json/igny8/v1/publish"
        headers = {
            'Content-Type': 'application/json',
            'X-IGNY8-API-KEY': api_key,
        }
        
        logger.info(f"[WordPressAdapter._publish_via_api_key] 🚀 POST to WordPress: {url}")
        logger.info(f"[WordPressAdapter._publish_via_api_key] 📡 Payload size: {len(str(content_data))} chars")
        response = requests.post(url, json=content_data, headers=headers, timeout=30)
        logger.info(f"[WordPressAdapter._publish_via_api_key] 📬 WordPress response: status={response.status_code}")
        
        if response.status_code == 201:
            wp_data = response.json().get('data', {})
            logger.info(f"[WordPressAdapter._publish_via_api_key] ✅ Success! WordPress post created: post_id={wp_data.get('post_id')}, url={wp_data.get('post_url')}")
            
            # NEW: Extract term_ids from WordPress response
            term_ids = wp_data.get('term_ids', {})
            if term_ids:
                logger.info(f"[WordPressAdapter._publish_via_api_key] 🏷️  Term IDs received: {term_ids}")
            
            return {
                'success': True,
                'external_id': str(wp_data.get('post_id')),
                'url': wp_data.get('post_url'),
                'published_at': datetime.now(),
                'metadata': {
                    'post_id': wp_data.get('post_id'),
                    'status': destination_config.get('status', 'publish'),
                    'term_ids': term_ids  # NEW: Save term ID mappings for future reference
                }
            }
        else:
            error_msg = f"HTTP {response.status_code}: {response.text}"
            logger.error(f"[WordPressAdapter._publish_via_api_key] ❌ WordPress API error: {error_msg}")
            return {
                'success': False,
                'external_id': None,
                'url': None,
                'published_at': None,
                'metadata': {'error': error_msg}
            }
    
    def _publish_via_username_password(
        self,
        site_url: str,
        username: str,
        app_password: str,
        title: str,
        content_html: str,
        destination_config: Dict[str, Any]
    ) -> Dict[str, Any]:
        """
        Publish via standard WordPress REST API using username/password.
        """
        if not username or not app_password:
            raise ValueError("username and app_password are required when not using API key")
        
        # Get WordPress client
        client = WordPressClient(site_url, username, app_password)
        
        # Get publishing options
        status = destination_config.get('status', 'draft')
        featured_image_url = destination_config.get('featured_image_url')
        
        # Publish to WordPress
        result = client.create_post(
            title=title,
            content=content_html,
            status=status,
            featured_image_url=featured_image_url
        )
        
        # Handle response
        if result.get('success') or result.get('post_id'):
            post_id = result.get('post_id') or result.get('id')
            url = result.get('url') or result.get('link')
            
            return {
                'success': True,
                'external_id': str(post_id) if post_id else None,
                'url': url,
                'published_at': datetime.now(),
                'metadata': {
                    'post_id': post_id,
                    'status': status
                }
            }
        else:
            return {
                'success': False,
                'external_id': None,
                'url': None,
                'published_at': None,
                'metadata': {
                    'error': result.get('error', 'Unknown error')
                }
            }
    
    def test_connection(
        self,
        config: Dict[str, Any]
    ) -> Dict[str, Any]:
        """
        Test connection to WordPress.
        
        Args:
            config: {
                'site_url': str,
                'username': str,
                'app_password': str
            }
        
        Returns:
            dict: {
                'success': bool,
                'message': str,
                'details': dict
            }
        """
        try:
            client = self._get_client(config)
            result = client.test_connection()
            
            return {
                'success': result.get('success', False),
                'message': result.get('message', ''),
                'details': {
                    'wp_version': result.get('wp_version')
                }
            }
        except Exception as e:
            logger.error(
                f"[WordPressAdapter] Connection test failed: {str(e)}",
                exc_info=True
            )
            return {
                'success': False,
                'message': str(e),
                'details': {}
            }
    
    def get_status(
        self,
        published_id: str,
        config: Dict[str, Any]
    ) -> Dict[str, Any]:
        """
        Get publishing status for published content.
        
        Args:
            published_id: WordPress post ID
            config: WordPress configuration
        
        Returns:
            dict: {
                'status': str,  # 'published', 'draft', 'deleted', etc.
                'url': str,
                'updated_at': datetime,
                'metadata': dict
            }
        """
        try:
            client = self._get_client(config)
            
            # Fetch post from WordPress
            response = client.session.get(
                f"{client.api_base}/posts/{published_id}"
            )
            
            if response.status_code == 200:
                data = response.json()
                return {
                    'status': data.get('status', 'unknown'),
                    'url': data.get('link'),
                    'updated_at': datetime.fromisoformat(
                        data.get('modified', '').replace('Z', '+00:00')
                    ) if data.get('modified') else None,
                    'metadata': {
                        'title': data.get('title', {}).get('rendered'),
                        'author': data.get('author'),
                    }
                }
            else:
                return {
                    'status': 'deleted' if response.status_code == 404 else 'unknown',
                    'url': None,
                    'updated_at': None,
                    'metadata': {
                        'error': f"HTTP {response.status_code}"
                    }
                }
                
        except Exception as e:
            logger.error(
                f"[WordPressAdapter] Error getting status: {str(e)}",
                exc_info=True
            )
            return {
                'status': 'unknown',
                'url': None,
                'updated_at': None,
                'metadata': {
                    'error': str(e)
                }
            }
    
    def validate_config(
        self,
        config: Dict[str, Any]
    ) -> tuple:
        """
        Validate WordPress configuration.
        
        Args:
            config: WordPress configuration
        
        Returns:
            tuple: (is_valid, error_message)
        """
        required_fields = ['site_url']
        
        for field in required_fields:
            if field not in config or not config[field]:
                return False, f"Missing required field: {field}"
        
        # Validate URL format
        site_url = config.get('site_url', '')
        if not site_url.startswith(('http://', 'https://')):
            return False, "site_url must start with http:// or https://"
        
        return True, None
    
    def _get_client(self, config: Dict[str, Any]) -> WordPressClient:
        """
        Get WordPress client from configuration.
        
        Args:
            config: WordPress configuration
        
        Returns:
            WordPressClient instance
        """
        site_url = config.get('site_url')
        username = config.get('username')
        app_password = config.get('app_password')
        
        return WordPressClient(site_url, username, app_password)

