from django.db import models
from django.core.validators import MinValueValidator
from igny8_core.auth.models import SiteSectorBaseModel
from igny8_core.common.soft_delete import SoftDeletableModel, SoftDeleteManager


class Tasks(SoftDeletableModel, SiteSectorBaseModel):
    """Tasks model for content generation queue"""
    
    STATUS_CHOICES = [
        ('queued', 'Queued'),
        ('completed', 'Completed'),
    ]
    
    CONTENT_TYPE_CHOICES = [
        ('post', 'Post'),
        ('page', 'Page'),
        ('product', 'Product'),
        ('taxonomy', 'Taxonomy'),
    ]
    
    CONTENT_STRUCTURE_CHOICES = [
        # Post structures
        ('article', 'Article'),
        ('guide', 'Guide'),
        ('comparison', 'Comparison'),
        ('review', 'Review'),
        ('listicle', 'Listicle'),
        # Page structures
        ('landing_page', 'Landing Page'),
        ('business_page', 'Business Page'),
        ('service_page', 'Service Page'),
        ('general', 'General'),
        ('cluster_hub', 'Cluster Hub'),
        # Product structures
        ('product_page', 'Product Page'),
        # Taxonomy structures
        ('category_archive', 'Category Archive'),
        ('tag_archive', 'Tag Archive'),
        ('attribute_archive', 'Attribute Archive'),
    ]
    
    title = models.CharField(max_length=255, db_index=True)
    description = models.TextField(blank=True, null=True)
    cluster = models.ForeignKey(
        'planner.Clusters',
        on_delete=models.SET_NULL,
        null=True,
        blank=False,
        related_name='tasks',
        limit_choices_to={'sector': models.F('sector')},
        help_text="Parent cluster (required)"
    )
    idea = models.ForeignKey(
        'planner.ContentIdeas',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='tasks',
        help_text="Optional content idea reference",
        db_column='idea_id'
    )
    content_type = models.CharField(
        max_length=100,
        db_index=True,
        help_text="Content type: post, page, product, taxonomy",
        choices=CONTENT_TYPE_CHOICES,
        default='post',
        blank=True,
        null=True
    )
    content_structure = models.CharField(
        max_length=100,
        db_index=True,
        help_text="Content structure: article, guide, comparison, review, listicle, landing_page, etc.",
        choices=CONTENT_STRUCTURE_CHOICES,
        default='article',
        blank=True,
        null=True
    )
    taxonomy_term = models.ForeignKey(
        'ContentTaxonomy',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='tasks',
        help_text="Optional taxonomy term assignment",
        db_column='taxonomy_id'
    )
    keywords = models.TextField(
        blank=True,
        null=True,
        help_text="Comma-separated keywords for this task"
    )
    word_count = models.IntegerField(
        default=1000,
        validators=[MinValueValidator(100)],
        help_text="Target word count for content generation"
    )
    status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='queued')
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        app_label = 'writer'
        db_table = 'igny8_tasks'
        ordering = ['-created_at']
        verbose_name = 'Task'
        verbose_name_plural = 'Tasks'
        indexes = [
            models.Index(fields=['title']),
            models.Index(fields=['status']),
            models.Index(fields=['cluster']),
            models.Index(fields=['content_type']),
            models.Index(fields=['content_structure']),
            models.Index(fields=['site', 'sector']),
        ]
    
    objects = SoftDeleteManager()
    all_objects = models.Manager()
    
    def __str__(self):
        return self.title


class ContentTaxonomyRelation(models.Model):
    """Through model for Content-Taxonomy many-to-many relationship"""
    content = models.ForeignKey('Content', on_delete=models.CASCADE, db_column='content_id')
    taxonomy = models.ForeignKey('ContentTaxonomy', on_delete=models.CASCADE, db_column='taxonomy_id')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        app_label = 'writer'
        db_table = 'igny8_content_taxonomy_relations'
        unique_together = [['content', 'taxonomy']]


class Content(SoftDeletableModel, SiteSectorBaseModel):
    """
    Content model for AI-generated or WordPress-imported content.
    Final architecture: simplified content management.
    """
    
    CONTENT_TYPE_CHOICES = [
        ('post', 'Post'),
        ('page', 'Page'),
        ('product', 'Product'),
        ('taxonomy', 'Taxonomy'),
    ]
    
    CONTENT_STRUCTURE_CHOICES = [
        # Post structures
        ('article', 'Article'),
        ('guide', 'Guide'),
        ('comparison', 'Comparison'),
        ('review', 'Review'),
        ('listicle', 'Listicle'),
        # Page structures
        ('landing_page', 'Landing Page'),
        ('business_page', 'Business Page'),
        ('service_page', 'Service Page'),
        ('general', 'General'),
        ('cluster_hub', 'Cluster Hub'),
        # Product structures
        ('product_page', 'Product Page'),
        # Taxonomy structures
        ('category_archive', 'Category Archive'),
        ('tag_archive', 'Tag Archive'),
        ('attribute_archive', 'Attribute Archive'),
    ]
    
    # Core content fields
    title = models.CharField(max_length=255, db_index=True)
    content_html = models.TextField(help_text="Final HTML content")
    word_count = models.IntegerField(
        default=0,
        help_text="Actual word count of content (calculated from HTML)"
    )
    
    # SEO fields
    meta_title = models.CharField(max_length=255, blank=True, null=True, help_text="SEO meta title")
    meta_description = models.TextField(blank=True, null=True, help_text="SEO meta description")
    primary_keyword = models.CharField(max_length=255, blank=True, null=True, help_text="Primary SEO keyword")
    secondary_keywords = models.JSONField(default=list, blank=True, help_text="Secondary SEO keywords")
    
    cluster = models.ForeignKey(
        'planner.Clusters',
        on_delete=models.SET_NULL,
        null=True,
        blank=False,
        related_name='contents',
        help_text="Parent cluster (required)"
    )
    content_type = models.CharField(
        max_length=50,
        choices=CONTENT_TYPE_CHOICES,
        default='post',
        db_index=True,
        help_text="Content type: post, page, product, taxonomy"
    )
    content_structure = models.CharField(
        max_length=50,
        choices=CONTENT_STRUCTURE_CHOICES,
        default='article',
        db_index=True,
        help_text="Content structure/format based on content type"
    )
    
    # Taxonomy relationships
    taxonomy_terms = models.ManyToManyField(
        'ContentTaxonomy',
        through='ContentTaxonomyRelation',
        blank=True,
        related_name='contents',
        help_text="Associated taxonomy terms (categories, tags, attributes)"
    )
    
    # External platform fields (WordPress integration)
    external_id = models.CharField(max_length=255, blank=True, null=True, db_index=True, help_text="WordPress/external platform post ID")
    external_url = models.URLField(blank=True, null=True, help_text="WordPress/external platform URL")
    external_type = models.CharField(max_length=100, blank=True, null=True, help_text="WordPress post type (post, page, product, etc.)")
    external_metadata = models.JSONField(blank=True, null=True, default=dict, help_text="External platform metadata (WordPress term IDs, etc.)")
    sync_status = models.CharField(max_length=50, blank=True, null=True, help_text="Sync status with WordPress")
    
    # Source tracking
    SOURCE_CHOICES = [
        ('igny8', 'IGNY8 Generated'),
        ('wordpress', 'WordPress Imported'),
    ]
    source = models.CharField(
        max_length=50,
        choices=SOURCE_CHOICES,
        default='igny8',
        db_index=True,
        help_text="Content source"
    )
    
    # Status tracking
    STATUS_CHOICES = [
        ('draft', 'Draft'),
        ('review', 'Review'),
        ('published', 'Published'),
    ]
    status = models.CharField(
        max_length=50,
        choices=STATUS_CHOICES,
        default='draft',
        db_index=True,
        help_text="Content status"
    )
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        app_label = 'writer'
        db_table = 'igny8_content'
        ordering = ['-created_at']
        verbose_name = 'Content'
        verbose_name_plural = 'Contents'
        indexes = [
            models.Index(fields=['title']),
            models.Index(fields=['cluster']),
            models.Index(fields=['content_type']),
            models.Index(fields=['content_structure']),
            models.Index(fields=['source']),
            models.Index(fields=['status']),
            models.Index(fields=['external_id']),
            models.Index(fields=['site', 'sector']),
        ]
    
    objects = SoftDeleteManager()
    all_objects = models.Manager()
    
    def __str__(self):
        return self.title or f"Content {self.id}"
    
    def save(self, *args, **kwargs):
        """Override save to auto-calculate word_count from content_html"""
        is_new = self.pk is None
        old_word_count = 0
        
        # Get old word count if updating
        if not is_new and self.content_html:
            try:
                old_instance = Content.objects.get(pk=self.pk)
                old_word_count = old_instance.word_count or 0
            except Content.DoesNotExist:
                pass
        
        # Auto-calculate word count if content_html has changed
        if self.content_html:
            from igny8_core.utils.word_counter import calculate_word_count
            calculated_count = calculate_word_count(self.content_html)
            # Only update if different to avoid unnecessary saves
            if self.word_count != calculated_count:
                self.word_count = calculated_count
        
        super().save(*args, **kwargs)
        
        # Increment usage for new content or if word count increased
        if self.content_html and self.word_count:
            # Only count newly generated words
            new_words = self.word_count - old_word_count if not is_new else self.word_count
            
            if new_words > 0:
                from igny8_core.business.billing.services.limit_service import LimitService
                try:
                    # Get account from site
                    account = self.site.account if self.site else None
                    if account:
                        LimitService.increment_usage(
                            account=account,
                            limit_type='content_words',
                            amount=new_words,
                            metadata={
                                'content_id': self.id,
                                'content_title': self.title,
                                'site_id': self.site.id if self.site else None,
                            }
                        )
                except Exception as e:
                    import logging
                    logger = logging.getLogger(__name__)
                    logger.error(f"Error incrementing word usage for content {self.id}: {str(e)}")


class ContentTaxonomy(SiteSectorBaseModel):
    """
    Simplified taxonomy model for AI-generated categories and tags.
    Directly linked to Content via many-to-many relationship.
    """

    TAXONOMY_TYPE_CHOICES = [
        ('category', 'Category'),
        ('tag', 'Tag'),
    ]

    name = models.CharField(max_length=255, db_index=True, help_text="Term name")
    slug = models.SlugField(max_length=255, db_index=True, help_text="URL slug")
    taxonomy_type = models.CharField(
        max_length=50,
        choices=TAXONOMY_TYPE_CHOICES,
        db_index=True,
        help_text="Type of taxonomy (category or tag)"
    )
    
    # WordPress/external platform sync fields
    external_taxonomy = models.CharField(
        max_length=100,
        blank=True,
        default='',
        help_text="WordPress taxonomy slug (category, post_tag)"
    )
    external_id = models.IntegerField(
        null=True,
        blank=True,
        db_index=True,
        help_text="WordPress term_id for sync"
    )
    sync_status = models.CharField(
        max_length=50,
        blank=True,
        default='',
        help_text="Sync status with external platform"
    )
    description = models.TextField(
        blank=True,
        default='',
        help_text="Taxonomy term description"
    )
    count = models.IntegerField(
        default=0,
        help_text="Number of times this term is used"
    )
    metadata = models.JSONField(
        default=dict,
        blank=True,
        help_text="Additional metadata (AI generation details, etc.)"
    )
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        app_label = 'writer'
        db_table = 'igny8_content_taxonomy_terms'
        verbose_name = 'Content Taxonomy'
        verbose_name_plural = 'Content Taxonomies'
        unique_together = [
            ['site', 'slug', 'taxonomy_type'],
            ['site', 'external_id', 'external_taxonomy'],
        ]
        indexes = [
            models.Index(fields=['name']),
            models.Index(fields=['slug']),
            models.Index(fields=['taxonomy_type']),
            models.Index(fields=['external_id', 'external_taxonomy']),
            models.Index(fields=['site', 'taxonomy_type']),
            models.Index(fields=['site', 'sector']),
        ]

    def __str__(self):
        return f"{self.name} ({self.get_taxonomy_type_display()})"


class Images(SoftDeletableModel, SiteSectorBaseModel):
    """Images model for content-related images (featured, desktop, mobile, in-article)"""
    
    IMAGE_TYPE_CHOICES = [
        ('featured', 'Featured Image'),
        ('desktop', 'Desktop Image'),
        ('mobile', 'Mobile Image'),
        ('in_article', 'In-Article Image'),
    ]
    
    content = models.ForeignKey(
        Content,
        on_delete=models.CASCADE,
        related_name='images',
        null=True,
        blank=True,
        help_text="The content this image belongs to (preferred)"
    )
    task = models.ForeignKey(
        Tasks,
        on_delete=models.CASCADE,
        related_name='images',
        null=True,
        blank=True,
        help_text="The task this image belongs to (legacy, use content instead)"
    )
    image_type = models.CharField(max_length=50, choices=IMAGE_TYPE_CHOICES, default='featured')
    image_url = models.CharField(max_length=500, blank=True, null=True, help_text="URL of the generated/stored image")
    image_path = models.CharField(max_length=500, blank=True, null=True, help_text="Local path if stored locally")
    prompt = models.TextField(blank=True, null=True, help_text="Image generation prompt used")
    caption = models.TextField(blank=True, null=True, help_text="Image caption (40-60 words) to display with the image")
    status = models.CharField(max_length=50, default='pending', help_text="Status: pending, generated, failed")
    position = models.IntegerField(default=0, help_text="Position for in-article images ordering")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        app_label = 'writer'
        db_table = 'igny8_images'
        ordering = ['content', 'position', '-created_at']
        verbose_name = 'Image'
        verbose_name_plural = 'Images'
        indexes = [
            models.Index(fields=['content', 'image_type']),
            models.Index(fields=['task', 'image_type']),
            models.Index(fields=['status']),
            models.Index(fields=['content', 'position']),
            models.Index(fields=['task', 'position']),
        ]
    
    objects = SoftDeleteManager()
    all_objects = models.Manager()
    
    def save(self, *args, **kwargs):
        """Track image usage when creating new images"""
        is_new = self.pk is None
        
        # Automatically set account, site, and sector from content or task
        if self.content:
            self.account = self.content.account
            self.site = self.content.site
            self.sector = self.content.sector
        elif self.task:
            self.account = self.task.account
            self.site = self.task.site
            self.sector = self.task.sector
        
        super().save(*args, **kwargs)
        
        # Increment usage for new images
        if is_new:
            from igny8_core.business.billing.services.limit_service import LimitService
            try:
                account = self.account
                if account:
                    # Track image prompt usage
                    if self.prompt:
                        LimitService.increment_usage(
                            account=account,
                            limit_type='image_prompts',
                            amount=1,
                            metadata={
                                'image_id': self.id,
                                'image_type': self.image_type,
                                'content_id': self.content.id if self.content else None,
                            }
                        )
                    
                    # Track basic image usage (for now, all images are counted as basic)
                    # TODO: Implement premium image tracking when premium models are used
                    LimitService.increment_usage(
                        account=account,
                        limit_type='images_basic',
                        amount=1,
                        metadata={
                            'image_id': self.id,
                            'image_type': self.image_type,
                            'content_id': self.content.id if self.content else None,
                        }
                    )
            except Exception as e:
                import logging
                logger = logging.getLogger(__name__)
                logger.error(f"Error incrementing image usage for image {self.id}: {str(e)}")
    
    def __str__(self):
        content_title = self.content.title if self.content else None
        task_title = self.task.title if self.task else None
        title = content_title or task_title or 'Unknown'
        return f"{title} - {self.image_type}"


class ContentClusterMap(SiteSectorBaseModel):
    """Associates generated content with planner clusters + roles."""

    ROLE_CHOICES = [
        ('hub', 'Hub Page'),
        ('supporting', 'Supporting Page'),
        ('attribute', 'Attribute Page'),
    ]

    SOURCE_CHOICES = [
        ('blueprint', 'Blueprint'),
        ('manual', 'Manual'),
        ('import', 'Import'),
    ]

    content = models.ForeignKey(
        Content,
        on_delete=models.CASCADE,
        related_name='cluster_mappings',
        null=True,
        blank=True,
    )
    task = models.ForeignKey(
        Tasks,
        on_delete=models.CASCADE,
        related_name='cluster_mappings',
        null=True,
        blank=True,
    )
    cluster = models.ForeignKey(
        'planner.Clusters',
        on_delete=models.CASCADE,
        related_name='content_mappings',
    )
    role = models.CharField(max_length=50, choices=ROLE_CHOICES, default='hub')
    source = models.CharField(max_length=50, choices=SOURCE_CHOICES, default='blueprint')
    metadata = models.JSONField(default=dict, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        app_label = 'writer'
        db_table = 'igny8_content_cluster_map'
        unique_together = [['content', 'cluster', 'role']]
        indexes = [
            models.Index(fields=['cluster', 'role']),
            models.Index(fields=['content', 'role']),
            models.Index(fields=['task', 'role']),
        ]

    def save(self, *args, **kwargs):
        provider = self.content or self.task
        if provider:
            self.account = provider.account
            self.site = provider.site
            self.sector = provider.sector
        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.cluster.name} ({self.get_role_display()})"




class ContentAttribute(SiteSectorBaseModel):
    """
    Unified attribute storage for products, services, and semantic facets.
    Replaces ContentAttributeMap with enhanced WP sync support.
    """

    ATTRIBUTE_TYPE_CHOICES = [
        ('product_spec', 'Product Specification'),
        ('service_modifier', 'Service Modifier'),
        ('semantic_facet', 'Semantic Facet'),
    ]

    SOURCE_CHOICES = [
        ('blueprint', 'Blueprint'),
        ('manual', 'Manual'),
        ('import', 'Import'),
        ('wordpress', 'WordPress'),
    ]

    content = models.ForeignKey(
        Content,
        on_delete=models.CASCADE,
        related_name='attributes',
        null=True,
        blank=True,
    )
    task = models.ForeignKey(
        Tasks,
        on_delete=models.CASCADE,
        related_name='attribute_mappings',
        null=True,
        blank=True,
    )
    cluster = models.ForeignKey(
        'planner.Clusters',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='attributes',
        help_text="Optional cluster association for semantic attributes"
    )
    
    attribute_type = models.CharField(
        max_length=50,
        choices=ATTRIBUTE_TYPE_CHOICES,
        default='product_spec',
        db_index=True,
        help_text="Type of attribute"
    )
    name = models.CharField(max_length=120, help_text="Attribute name (e.g., Color, Material)")
    value = models.CharField(max_length=255, blank=True, null=True, help_text="Attribute value (e.g., Blue, Cotton)")
    
    # WordPress/WooCommerce sync fields
    external_id = models.IntegerField(null=True, blank=True, help_text="WP attribute term ID")
    external_attribute_name = models.CharField(
        max_length=100,
        blank=True,
        help_text="WP attribute slug (e.g., pa_color, pa_size)"
    )
    
    source = models.CharField(max_length=50, choices=SOURCE_CHOICES, default='manual')
    metadata = models.JSONField(default=dict, blank=True, help_text="Additional metadata")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        app_label = 'writer'
        db_table = 'igny8_content_attributes'
        verbose_name = 'Content Attribute'
        verbose_name_plural = 'Content Attributes'
        indexes = [
            models.Index(fields=['name']),
            models.Index(fields=['attribute_type']),
            models.Index(fields=['content', 'name']),
            models.Index(fields=['content', 'attribute_type']),
            models.Index(fields=['cluster', 'attribute_type']),
            models.Index(fields=['external_id']),
        ]

    def save(self, *args, **kwargs):
        provider = self.content or self.task
        if provider:
            self.account = provider.account
            self.site = provider.site
            self.sector = provider.sector
        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.name}: {self.value}"


# Backward compatibility alias
ContentAttributeMap = ContentAttribute
