"""Creative Management Filters

Django Filter classes for creative asset management.
Provides comprehensive filtering capabilities for API endpoints and list views.

Features:
- Text search across multiple fields
- Date range filtering
- Status and type filtering
- Relationship filtering
- Performance metrics filtering
- Custom filter methods
- Boolean filtering
- Numerical range filtering

Filters:
- CreativeFilter: Main creative filtering
- CreativeTemplateFilter: Template filtering
- CreativeApprovalFilter: Approval workflow filtering
- CreativePerformanceFilter: Performance data filtering
- CreativeVersionFilter: Version filtering
- CreativeAssetFilter: Asset filtering
- CreativeComplianceFilter: Compliance filtering

Usage:
- API endpoint filtering
- Admin interface filtering
- List view filtering
- Search functionality
- Performance analytics
"""

import django_filters
from django import forms
from django.db.models import Q, Count, Sum, Avg
from django.utils import timezone
from datetime import datetime, timedelta

from .models import (
    Creative, CreativeVersion, CreativeFormat, CreativeTemplate,
    CreativeAsset, CreativeApproval, CreativePerformance,
    CreativeTag, CreativeCompliance, CreativeVariant
)
from apps.campaigns.models import Campaign
from apps.authentication.models import User


class CreativeFilter(django_filters.FilterSet):
    """Creative filtering with comprehensive search and filter options."""
    
    # Text search
    search = django_filters.CharFilter(
        method='filter_search',
        label='Search',
        widget=forms.TextInput(attrs={
            'placeholder': 'Search creatives...',
            'class': 'form-control'
        })
    )
    
    # Basic filters
    name = django_filters.CharFilter(
        lookup_expr='icontains',
        label='Name contains',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    creative_type = django_filters.ChoiceFilter(
        choices=Creative.CREATIVE_TYPES,
        label='Creative Type',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    creative_status = django_filters.ChoiceFilter(
        choices=Creative.CREATIVE_STATUS,
        label='Status',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    # Relationship filters
    campaign = django_filters.ModelChoiceFilter(
        queryset=Campaign.objects.all(),
        label='Campaign',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    campaign_name = django_filters.CharFilter(
        field_name='campaign__name',
        lookup_expr='icontains',
        label='Campaign Name',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    created_by = django_filters.ModelChoiceFilter(
        queryset=User.objects.all(),
        label='Created By',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    # Date filters
    created_at = django_filters.DateFromToRangeFilter(
        label='Created Date Range',
        widget=django_filters.widgets.RangeWidget(attrs={'class': 'form-control'})
    )
    
    created_date = django_filters.DateFilter(
        field_name='created_at__date',
        label='Created Date',
        widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
    )
    
    deadline = django_filters.DateFromToRangeFilter(
        label='Deadline Range',
        widget=django_filters.widgets.RangeWidget(attrs={'class': 'form-control'})
    )
    
    # Performance filters
    min_impressions = django_filters.NumberFilter(
        field_name='impressions',
        lookup_expr='gte',
        label='Min Impressions',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    max_impressions = django_filters.NumberFilter(
        field_name='impressions',
        lookup_expr='lte',
        label='Max Impressions',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    min_clicks = django_filters.NumberFilter(
        field_name='clicks',
        lookup_expr='gte',
        label='Min Clicks',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    min_conversions = django_filters.NumberFilter(
        field_name='conversions',
        lookup_expr='gte',
        label='Min Conversions',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    # File properties
    file_size_min = django_filters.NumberFilter(
        field_name='file_size',
        lookup_expr='gte',
        label='Min File Size (bytes)',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    file_size_max = django_filters.NumberFilter(
        field_name='file_size',
        lookup_expr='lte',
        label='Max File Size (bytes)',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    duration_min = django_filters.NumberFilter(
        field_name='duration',
        lookup_expr='gte',
        label='Min Duration (seconds)',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    duration_max = django_filters.NumberFilter(
        field_name='duration',
        lookup_expr='lte',
        label='Max Duration (seconds)',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    # Boolean filters
    has_file = django_filters.BooleanFilter(
        method='filter_has_file',
        label='Has File',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    is_compliant = django_filters.BooleanFilter(
        label='Is Compliant',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    has_deadline = django_filters.BooleanFilter(
        method='filter_has_deadline',
        label='Has Deadline',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    # Priority filter
    priority = django_filters.ChoiceFilter(
        choices=Creative.PRIORITY_CHOICES,
        label='Priority',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    priority_min = django_filters.NumberFilter(
        field_name='priority',
        lookup_expr='gte',
        label='Min Priority',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    # Compliance filters
    compliance_score_min = django_filters.NumberFilter(
        field_name='compliance_score',
        lookup_expr='gte',
        label='Min Compliance Score',
        widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.1'})
    )
    
    compliance_score_max = django_filters.NumberFilter(
        field_name='compliance_score',
        lookup_expr='lte',
        label='Max Compliance Score',
        widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.1'})
    )
    
    # Tag filters
    tags = django_filters.ModelMultipleChoiceFilter(
        queryset=CreativeTag.objects.all(),
        label='Tags',
        widget=forms.SelectMultiple(attrs={'class': 'form-control'})
    )
    
    has_tags = django_filters.BooleanFilter(
        method='filter_has_tags',
        label='Has Tags',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    # Time-based filters
    created_today = django_filters.BooleanFilter(
        method='filter_created_today',
        label='Created Today',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    created_this_week = django_filters.BooleanFilter(
        method='filter_created_this_week',
        label='Created This Week',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    created_this_month = django_filters.BooleanFilter(
        method='filter_created_this_month',
        label='Created This Month',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    # Advanced filters
    has_versions = django_filters.BooleanFilter(
        method='filter_has_versions',
        label='Has Versions',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    has_approvals = django_filters.BooleanFilter(
        method='filter_has_approvals',
        label='Has Approvals',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    has_performance_data = django_filters.BooleanFilter(
        method='filter_has_performance_data',
        label='Has Performance Data',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    class Meta:
        model = Creative
        fields = [
            'search', 'name', 'creative_type', 'creative_status',
            'campaign', 'campaign_name', 'created_by', 'priority',
            'is_compliant', 'tags'
        ]
    
    def filter_search(self, queryset, name, value):
        """Global search across multiple fields."""
        if not value:
            return queryset
        
        return queryset.filter(
            Q(name__icontains=value) |
            Q(description__icontains=value) |
            Q(campaign__name__icontains=value) |
            Q(created_by__first_name__icontains=value) |
            Q(created_by__last_name__icontains=value) |
            Q(tags__name__icontains=value)
        ).distinct()
    
    def filter_has_file(self, queryset, name, value):
        """Filter by presence of primary file."""
        if value is True:
            return queryset.exclude(primary_file='')
        elif value is False:
            return queryset.filter(primary_file='')
        return queryset
    
    def filter_has_deadline(self, queryset, name, value):
        """Filter by presence of deadline."""
        if value is True:
            return queryset.exclude(deadline__isnull=True)
        elif value is False:
            return queryset.filter(deadline__isnull=True)
        return queryset
    
    def filter_has_tags(self, queryset, name, value):
        """Filter by presence of tags."""
        if value is True:
            return queryset.filter(tags__isnull=False).distinct()
        elif value is False:
            return queryset.filter(tags__isnull=True)
        return queryset
    
    def filter_created_today(self, queryset, name, value):
        """Filter creatives created today."""
        if value is True:
            today = timezone.now().date()
            return queryset.filter(created_at__date=today)
        return queryset
    
    def filter_created_this_week(self, queryset, name, value):
        """Filter creatives created this week."""
        if value is True:
            week_start = timezone.now().date() - timedelta(days=7)
            return queryset.filter(created_at__date__gte=week_start)
        return queryset
    
    def filter_created_this_month(self, queryset, name, value):
        """Filter creatives created this month."""
        if value is True:
            month_start = timezone.now().date().replace(day=1)
            return queryset.filter(created_at__date__gte=month_start)
        return queryset
    
    def filter_has_versions(self, queryset, name, value):
        """Filter by presence of versions."""
        if value is True:
            return queryset.filter(versions__isnull=False).distinct()
        elif value is False:
            return queryset.filter(versions__isnull=True)
        return queryset
    
    def filter_has_approvals(self, queryset, name, value):
        """Filter by presence of approvals."""
        if value is True:
            return queryset.filter(approvals__isnull=False).distinct()
        elif value is False:
            return queryset.filter(approvals__isnull=True)
        return queryset
    
    def filter_has_performance_data(self, queryset, name, value):
        """Filter by presence of performance data."""
        if value is True:
            return queryset.filter(performance_data__isnull=False).distinct()
        elif value is False:
            return queryset.filter(performance_data__isnull=True)
        return queryset


class CreativeTemplateFilter(django_filters.FilterSet):
    """Creative template filtering."""
    
    search = django_filters.CharFilter(
        method='filter_search',
        label='Search',
        widget=forms.TextInput(attrs={
            'placeholder': 'Search templates...',
            'class': 'form-control'
        })
    )
    
    name = django_filters.CharFilter(
        lookup_expr='icontains',
        label='Name contains',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    template_type = django_filters.ChoiceFilter(
        choices=CreativeTemplate.TEMPLATE_TYPES,
        label='Template Type',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    is_active = django_filters.BooleanFilter(
        label='Is Active',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    created_by = django_filters.ModelChoiceFilter(
        queryset=User.objects.all(),
        label='Created By',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    usage_count_min = django_filters.NumberFilter(
        field_name='usage_count',
        lookup_expr='gte',
        label='Min Usage Count',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    created_at = django_filters.DateFromToRangeFilter(
        label='Created Date Range',
        widget=django_filters.widgets.RangeWidget(attrs={'class': 'form-control'})
    )
    
    class Meta:
        model = CreativeTemplate
        fields = ['search', 'name', 'template_type', 'is_active', 'created_by']
    
    def filter_search(self, queryset, name, value):
        """Search across template fields."""
        if not value:
            return queryset
        
        return queryset.filter(
            Q(name__icontains=value) |
            Q(description__icontains=value) |
            Q(created_by__first_name__icontains=value) |
            Q(created_by__last_name__icontains=value)
        ).distinct()


class CreativeApprovalFilter(django_filters.FilterSet):
    """Creative approval filtering."""
    
    creative_name = django_filters.CharFilter(
        field_name='creative__name',
        lookup_expr='icontains',
        label='Creative Name',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    approval_status = django_filters.ChoiceFilter(
        choices=CreativeApproval.APPROVAL_STATUS,
        label='Approval Status',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    reviewer = django_filters.ModelChoiceFilter(
        queryset=User.objects.all(),
        label='Reviewer',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    reviewed_at = django_filters.DateFromToRangeFilter(
        label='Reviewed Date Range',
        widget=django_filters.widgets.RangeWidget(attrs={'class': 'form-control'})
    )
    
    created_at = django_filters.DateFromToRangeFilter(
        label='Created Date Range',
        widget=django_filters.widgets.RangeWidget(attrs={'class': 'form-control'})
    )
    
    has_comments = django_filters.BooleanFilter(
        method='filter_has_comments',
        label='Has Comments',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    class Meta:
        model = CreativeApproval
        fields = ['creative_name', 'approval_status', 'reviewer']
    
    def filter_has_comments(self, queryset, name, value):
        """Filter by presence of comments."""
        if value is True:
            return queryset.exclude(comments='')
        elif value is False:
            return queryset.filter(comments='')
        return queryset


class CreativePerformanceFilter(django_filters.FilterSet):
    """Creative performance filtering."""
    
    creative_name = django_filters.CharFilter(
        field_name='creative__name',
        lookup_expr='icontains',
        label='Creative Name',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    date = django_filters.DateFromToRangeFilter(
        label='Date Range',
        widget=django_filters.widgets.RangeWidget(attrs={'class': 'form-control'})
    )
    
    impressions_min = django_filters.NumberFilter(
        field_name='impressions',
        lookup_expr='gte',
        label='Min Impressions',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    impressions_max = django_filters.NumberFilter(
        field_name='impressions',
        lookup_expr='lte',
        label='Max Impressions',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    clicks_min = django_filters.NumberFilter(
        field_name='clicks',
        lookup_expr='gte',
        label='Min Clicks',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    conversions_min = django_filters.NumberFilter(
        field_name='conversions',
        lookup_expr='gte',
        label='Min Conversions',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    spend_min = django_filters.NumberFilter(
        field_name='spend',
        lookup_expr='gte',
        label='Min Spend',
        widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
    )
    
    spend_max = django_filters.NumberFilter(
        field_name='spend',
        lookup_expr='lte',
        label='Max Spend',
        widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
    )
    
    revenue_min = django_filters.NumberFilter(
        field_name='revenue',
        lookup_expr='gte',
        label='Min Revenue',
        widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
    )
    
    high_performance = django_filters.BooleanFilter(
        method='filter_high_performance',
        label='High Performance',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    class Meta:
        model = CreativePerformance
        fields = ['creative_name', 'date']
    
    def filter_high_performance(self, queryset, name, value):
        """Filter high-performing creatives."""
        if value is True:
            # Define high performance criteria
            return queryset.filter(
                Q(clicks__gte=100) |
                Q(conversions__gte=10) |
                Q(revenue__gte=1000)
            )
        return queryset


class CreativeVersionFilter(django_filters.FilterSet):
    """Creative version filtering."""
    
    creative_name = django_filters.CharFilter(
        field_name='creative__name',
        lookup_expr='icontains',
        label='Creative Name',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    version_number = django_filters.NumberFilter(
        label='Version Number',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    created_by = django_filters.ModelChoiceFilter(
        queryset=User.objects.all(),
        label='Created By',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    created_at = django_filters.DateFromToRangeFilter(
        label='Created Date Range',
        widget=django_filters.widgets.RangeWidget(attrs={'class': 'form-control'})
    )
    
    has_changes = django_filters.BooleanFilter(
        method='filter_has_changes',
        label='Has Changes',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    class Meta:
        model = CreativeVersion
        fields = ['creative_name', 'version_number', 'created_by']
    
    def filter_has_changes(self, queryset, name, value):
        """Filter by presence of change description."""
        if value is True:
            return queryset.exclude(changes='')
        elif value is False:
            return queryset.filter(changes='')
        return queryset


class CreativeAssetFilter(django_filters.FilterSet):
    """Creative asset filtering."""
    
    creative_name = django_filters.CharFilter(
        field_name='creative__name',
        lookup_expr='icontains',
        label='Creative Name',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    asset_type = django_filters.ChoiceFilter(
        choices=CreativeAsset.ASSET_TYPES,
        label='Asset Type',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    name = django_filters.CharFilter(
        lookup_expr='icontains',
        label='Asset Name',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    file_size_min = django_filters.NumberFilter(
        field_name='file_size',
        lookup_expr='gte',
        label='Min File Size',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    file_size_max = django_filters.NumberFilter(
        field_name='file_size',
        lookup_expr='lte',
        label='Max File Size',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    created_at = django_filters.DateFromToRangeFilter(
        label='Created Date Range',
        widget=django_filters.widgets.RangeWidget(attrs={'class': 'form-control'})
    )
    
    class Meta:
        model = CreativeAsset
        fields = ['creative_name', 'asset_type', 'name']


class CreativeComplianceFilter(django_filters.FilterSet):
    """Creative compliance filtering."""
    
    creative_name = django_filters.CharFilter(
        field_name='creative__name',
        lookup_expr='icontains',
        label='Creative Name',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    compliance_status = django_filters.ChoiceFilter(
        choices=CreativeCompliance.COMPLIANCE_STATUS,
        label='Compliance Status',
        widget=forms.Select(attrs={'class': 'form-control'})
    )
    
    compliance_score_min = django_filters.NumberFilter(
        field_name='compliance_score',
        lookup_expr='gte',
        label='Min Compliance Score',
        widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.1'})
    )
    
    compliance_score_max = django_filters.NumberFilter(
        field_name='compliance_score',
        lookup_expr='lte',
        label='Max Compliance Score',
        widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.1'})
    )
    
    checked_at = django_filters.DateFromToRangeFilter(
        label='Checked Date Range',
        widget=django_filters.widgets.RangeWidget(attrs={'class': 'form-control'})
    )
    
    has_issues = django_filters.BooleanFilter(
        method='filter_has_issues',
        label='Has Issues',
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
    )
    
    class Meta:
        model = CreativeCompliance
        fields = ['creative_name', 'compliance_status']
    
    def filter_has_issues(self, queryset, name, value):
        """Filter by presence of compliance issues."""
        if value is True:
            return queryset.exclude(issues={})
        elif value is False:
            return queryset.filter(issues={})
        return queryset


class CreativeTagFilter(django_filters.FilterSet):
    """Creative tag filtering."""
    
    name = django_filters.CharFilter(
        lookup_expr='icontains',
        label='Tag Name',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    color = django_filters.CharFilter(
        label='Color',
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    
    usage_count = django_filters.NumberFilter(
        method='filter_usage_count',
        label='Min Usage Count',
        widget=forms.NumberInput(attrs={'class': 'form-control'})
    )
    
    class Meta:
        model = CreativeTag
        fields = ['name', 'color']
    
    def filter_usage_count(self, queryset, name, value):
        """Filter by tag usage count."""
        if value is not None:
            return queryset.annotate(
                usage_count=Count('creative')
            ).filter(usage_count__gte=value)
        return queryset