from rest_framework import serializers
from django.db import models
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.conf import settings
from .models import Tasks, Images, Content
from igny8_core.business.planning.models import Clusters
from igny8_core.business.content.models import ContentTaxonomy


class TasksSerializer(serializers.ModelSerializer):
    """Serializer for Tasks model - Stage 1 refactored"""
    cluster_name = serializers.SerializerMethodField()
    sector_name = serializers.SerializerMethodField()
    site_id = serializers.IntegerField(write_only=True, required=False)
    sector_id = serializers.IntegerField(write_only=True, required=False)
    
    class Meta:
        model = Tasks
        fields = [
            'id',
            'title',
            'description',
            'cluster_id',
            'cluster_name',
            'content_type',
            'content_structure',
            'taxonomy_term_id',
            'word_count',
            'status',
            'sector_name',
            'site_id',
            'sector_id',
            'account_id',
            'created_at',
            'updated_at',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at', 'account_id']
    
    def validate(self, attrs):
        """Ensure required fields for Task creation"""
        if self.instance is None:  # Create operation
            if not attrs.get('cluster_id') and not attrs.get('cluster'):
                raise ValidationError({'cluster': 'Cluster is required'})
            if not attrs.get('content_type'):
                raise ValidationError({'content_type': 'Content type is required'})
            if not attrs.get('content_structure'):
                raise ValidationError({'content_structure': 'Content structure is required'})
            # Default status to queued if not provided
            if 'status' not in attrs:
                attrs['status'] = 'queued'
        return attrs
    
    def get_cluster_name(self, obj):
        """Get cluster name from Clusters model"""
        if obj.cluster_id:
            try:
                cluster = Clusters.objects.get(id=obj.cluster_id)
                return cluster.name
            except Clusters.DoesNotExist:
                return None
        return None
    
    def get_sector_name(self, obj):
        """Get sector name from Sector model"""
        if obj.sector_id:
            try:
                from igny8_core.auth.models import Sector
                sector = Sector.objects.get(id=obj.sector_id)
                return sector.name
            except Sector.DoesNotExist:
                return None
        return None


class ImagesSerializer(serializers.ModelSerializer):
    """Serializer for Images model"""
    task_title = serializers.SerializerMethodField()
    content_title = serializers.SerializerMethodField()
    
    class Meta:
        model = Images
        fields = [
            'id',
            'task_id',
            'task_title',
            'content_id',
            'content_title',
            'image_type',
            'image_url',
            'image_path',
            'prompt',
            'status',
            'position',
            'created_at',
            'updated_at',
            'account_id',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at', 'account_id']
    
    def get_task_title(self, obj):
        """Get task title"""
        if obj.task_id:
            try:
                task = Tasks.objects.get(id=obj.task_id)
                return task.title
            except Tasks.DoesNotExist:
                return None
        return None
    
    def get_content_title(self, obj):
        """Get content title"""
        if obj.content:
            return obj.content.title or obj.content.meta_title
        return None


class ContentImageSerializer(serializers.ModelSerializer):
    """Serializer for individual image in grouped content images"""
    image_url = serializers.SerializerMethodField()
    
    class Meta:
        model = Images
        fields = [
            'id',
            'image_type',
            'image_url',
            'image_path',
            'prompt',
            'status',
            'position',
            'created_at',
            'updated_at',
        ]
    
    def get_image_url(self, obj):
        """
        Return original image_url from database (Runware/OpenAI URL).
        No transformation - returns the exact value stored in image_url field.
        """
        return obj.image_url


class ContentImagesGroupSerializer(serializers.Serializer):
    """Serializer for grouped content images - one row per content"""
    content_id = serializers.IntegerField()
    content_title = serializers.CharField()
    content_status = serializers.CharField()  # draft, review, publish
    featured_image = ContentImageSerializer(allow_null=True)
    in_article_images = ContentImageSerializer(many=True)
    overall_status = serializers.CharField()  # 'pending', 'partial', 'complete', 'failed'


class ContentSerializer(serializers.ModelSerializer):
    """Serializer for Content model - Stage 1 refactored"""
    cluster_name = serializers.SerializerMethodField()
    sector_name = serializers.SerializerMethodField()
    taxonomy_terms_data = serializers.SerializerMethodField()
    tags = serializers.SerializerMethodField()
    categories = serializers.SerializerMethodField()
    has_image_prompts = serializers.SerializerMethodField()
    image_status = serializers.SerializerMethodField()
    has_generated_images = serializers.SerializerMethodField()
    site_id = serializers.IntegerField(write_only=True, required=False)
    sector_id = serializers.IntegerField(write_only=True, required=False)
    
    class Meta:
        model = Content
        fields = [
            'id',
            'title',
            'content_html',
            'meta_title',
            'meta_description',
            'primary_keyword',
            'secondary_keywords',
            'cluster_id',
            'cluster_name',
            'content_type',
            'content_structure',
            'taxonomy_terms_data',
            'tags',
            'categories',
            'external_id',
            'external_url',
            'source',
            'status',
            'word_count',
            'sector_name',
            'site_id',
            'sector_id',
            'account_id',
            'has_image_prompts',
            'image_status',
            'has_generated_images',
            'created_at',
            'updated_at',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at', 'account_id']
    
    def validate(self, attrs):
        """Ensure required fields for Content creation"""
        if self.instance is None:  # Create operation
            if not attrs.get('cluster_id') and not attrs.get('cluster'):
                raise ValidationError({'cluster': 'Cluster is required'})
            if not attrs.get('content_type'):
                raise ValidationError({'content_type': 'Content type is required'})
            if not attrs.get('content_structure'):
                raise ValidationError({'content_structure': 'Content structure is required'})
            if not attrs.get('title'):
                raise ValidationError({'title': 'Title is required'})
            # Default source to igny8 if not provided
            if 'source' not in attrs:
                attrs['source'] = 'igny8'
            # Default status to draft if not provided
            if 'status' not in attrs:
                attrs['status'] = 'draft'
        return attrs
    
    def get_cluster_name(self, obj):
        """Get cluster name"""
        if obj.cluster_id:
            try:
                cluster = Clusters.objects.get(id=obj.cluster_id)
                return cluster.name
            except Clusters.DoesNotExist:
                return None
        return None
    
    def get_sector_name(self, obj):
        """Get sector name"""
        if obj.sector_id:
            try:
                from igny8_core.auth.models import Sector
                sector = Sector.objects.get(id=obj.sector_id)
                return sector.name
            except Sector.DoesNotExist:
                return None
        return None
    
    def get_taxonomy_terms_data(self, obj):
        """Get taxonomy terms with details"""
        return [
            {
                'id': term.id,
                'name': term.name,
                'slug': term.slug,
                'taxonomy_type': term.taxonomy_type,
                'external_id': term.external_id,
                'external_taxonomy': term.external_taxonomy,
            }
            for term in obj.taxonomy_terms.all()
        ]
    
    def get_tags(self, obj):
        """Get only tags (taxonomy_type='tag')"""
        return [
            term.name
            for term in obj.taxonomy_terms.filter(taxonomy_type='tag')
        ]
    
    def get_categories(self, obj):
        """Get only categories (taxonomy_type='category')"""
        return [
            term.name
            for term in obj.taxonomy_terms.filter(taxonomy_type='category')
        ]
    
    def get_has_image_prompts(self, obj):
        """Check if content has any image prompts (images with prompts)"""
        return obj.images.filter(prompt__isnull=False).exclude(prompt='').exists()
    
    def get_image_status(self, obj):
        """Get image generation status: 'generated', 'pending', 'failed', or None"""
        images = obj.images.all()
        if not images.exists():
            return None
        
        # Check statuses
        has_failed = images.filter(status='failed').exists()
        has_generated = images.filter(status='generated').exists()
        has_pending = images.filter(status='pending').exists()
        
        # Priority: failed > pending > generated
        if has_failed:
            return 'failed'
        elif has_pending:
            return 'pending'
        elif has_generated:
            return 'generated'
        
        return None
    
    def get_has_generated_images(self, obj):
        """Check if content has any successfully generated images"""
        return obj.images.filter(status='generated', image_url__isnull=False).exclude(image_url='').exists()


class ContentTaxonomySerializer(serializers.ModelSerializer):
    """Serializer for ContentTaxonomy model - Stage 1 refactored"""
    content_count = serializers.SerializerMethodField()
    site_id = serializers.IntegerField(write_only=True, required=False)
    sector_id = serializers.IntegerField(write_only=True, required=False)
    
    class Meta:
        model = ContentTaxonomy
        fields = [
            'id',
            'name',
            'slug',
            'taxonomy_type',
            'external_id',
            'external_taxonomy',
            'content_count',
            'site_id',
            'sector_id',
            'account_id',
            'created_at',
            'updated_at',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at', 'account_id']
    
    def get_content_count(self, obj):
        """Get count of content using this taxonomy"""
        return obj.contents.count()


# ContentAttributeSerializer and ContentTaxonomyRelationSerializer removed in Stage 1
# These models no longer exist - simplified to direct M2M relationships

# UpdatedTasksSerializer removed - duplicate of TasksSerializer which is already refactored
