# -*- coding: utf-8 -*-
"""
Campaigns App Forms

This module contains forms for campaign management functionality.
"""

from django import forms
from django.core.exceptions import ValidationError
from django.utils import timezone
from decimal import Decimal

from .models import Campaign
from apps.advertisers.models import Advertiser


class CampaignForm(forms.ModelForm):
    """
    Form for creating and updating campaigns.
    """
    
    class Meta:
        model = Campaign
        fields = [
            'name', 'description', 'advertiser', 'budget', 
            'start_date', 'end_date', 'status'
        ]
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter campaign name'
            }),
            'description': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 4,
                'placeholder': 'Enter campaign description'
            }),
            'advertiser': forms.Select(attrs={
                'class': 'form-control'
            }),
            'budget': forms.NumberInput(attrs={
                'class': 'form-control',
                'step': '0.01',
                'min': '0',
                'placeholder': '0.00'
            }),
            'start_date': forms.DateInput(attrs={
                'class': 'form-control',
                'type': 'date'
            }),
            'end_date': forms.DateInput(attrs={
                'class': 'form-control',
                'type': 'date'
            }),
            'status': forms.Select(attrs={
                'class': 'form-control'
            })
        }
    
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        
        # Filter advertisers based on user's agency
        if user:
            self.fields['advertiser'].queryset = Advertiser.objects.filter(
                agency__users=user
            )
        
        # Set default start date to today
        if not self.instance.pk:
            self.fields['start_date'].initial = timezone.now().date()
    
    def clean_budget(self):
        """
        Validate budget field.
        """
        budget = self.cleaned_data.get('budget')
        
        if budget is not None and budget <= 0:
            raise ValidationError('Budget must be greater than zero.')
        
        if budget is not None and budget > Decimal('1000000.00'):
            raise ValidationError('Budget cannot exceed $1,000,000.')
        
        return budget
    
    def clean(self):
        """
        Validate form data.
        """
        cleaned_data = super().clean()
        start_date = cleaned_data.get('start_date')
        end_date = cleaned_data.get('end_date')
        
        # Validate date range
        if start_date and end_date:
            if end_date <= start_date:
                raise ValidationError('End date must be after start date.')
            
            # Check if campaign duration is reasonable
            duration = (end_date - start_date).days
            if duration > 365:
                raise ValidationError('Campaign duration cannot exceed 365 days.')
        
        # Validate start date is not in the past (for new campaigns)
        if start_date and not self.instance.pk:
            if start_date < timezone.now().date():
                raise ValidationError('Start date cannot be in the past.')
        
        return cleaned_data


class CampaignSearchForm(forms.Form):
    """
    Form for searching and filtering campaigns.
    """
    
    STATUS_CHOICES = [
        ('', 'All Statuses'),
        ('draft', 'Draft'),
        ('active', 'Active'),
        ('paused', 'Paused'),
        ('completed', 'Completed'),
        ('cancelled', 'Cancelled'),
    ]
    
    search = forms.CharField(
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Search campaigns...'
        })
    )
    
    status = forms.ChoiceField(
        choices=STATUS_CHOICES,
        required=False,
        widget=forms.Select(attrs={
            'class': 'form-control'
        })
    )
    
    advertiser = forms.ModelChoiceField(
        queryset=Advertiser.objects.none(),
        required=False,
        empty_label='All Advertisers',
        widget=forms.Select(attrs={
            'class': 'form-control'
        })
    )
    
    start_date_from = forms.DateField(
        required=False,
        widget=forms.DateInput(attrs={
            'class': 'form-control',
            'type': 'date'
        })
    )
    
    start_date_to = forms.DateField(
        required=False,
        widget=forms.DateInput(attrs={
            'class': 'form-control',
            'type': 'date'
        })
    )
    
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        
        # Filter advertisers based on user's agency
        if user:
            self.fields['advertiser'].queryset = Advertiser.objects.filter(
                agency__users=user
            )


class CampaignBulkActionForm(forms.Form):
    """
    Form for bulk actions on campaigns.
    """
    
    ACTION_CHOICES = [
        ('activate', 'Activate'),
        ('pause', 'Pause'),
        ('complete', 'Mark as Completed'),
        ('delete', 'Delete'),
    ]
    
    action = forms.ChoiceField(
        choices=ACTION_CHOICES,
        widget=forms.Select(attrs={
            'class': 'form-control'
        })
    )
    
    campaign_ids = forms.CharField(
        widget=forms.HiddenInput()
    )
    
    def clean_campaign_ids(self):
        """
        Validate campaign IDs.
        """
        campaign_ids = self.cleaned_data.get('campaign_ids')
        
        if not campaign_ids:
            raise ValidationError('No campaigns selected.')
        
        try:
            ids = [int(id.strip()) for id in campaign_ids.split(',') if id.strip()]
        except ValueError:
            raise ValidationError('Invalid campaign IDs.')
        
        if not ids:
            raise ValidationError('No valid campaign IDs provided.')
        
        return ids


class CampaignImportForm(forms.Form):
    """
    Form for importing campaigns from CSV file.
    """
    
    csv_file = forms.FileField(
        widget=forms.FileInput(attrs={
            'class': 'form-control',
            'accept': '.csv'
        }),
        help_text='Upload a CSV file with campaign data.'
    )
    
    def clean_csv_file(self):
        """
        Validate CSV file.
        """
        csv_file = self.cleaned_data.get('csv_file')
        
        if csv_file:
            # Check file extension
            if not csv_file.name.endswith('.csv'):
                raise ValidationError('File must be a CSV file.')
            
            # Check file size (max 5MB)
            if csv_file.size > 5 * 1024 * 1024:
                raise ValidationError('File size cannot exceed 5MB.')
        
        return csv_file


class CampaignStatusUpdateForm(forms.Form):
    """
    Form for updating campaign status.
    """
    
    STATUS_CHOICES = [
        ('draft', 'Draft'),
        ('active', 'Active'),
        ('paused', 'Paused'),
        ('completed', 'Completed'),
        ('cancelled', 'Cancelled'),
    ]
    
    status = forms.ChoiceField(
        choices=STATUS_CHOICES,
        widget=forms.Select(attrs={
            'class': 'form-control'
        })
    )
    
    reason = forms.CharField(
        required=False,
        widget=forms.Textarea(attrs={
            'class': 'form-control',
            'rows': 3,
            'placeholder': 'Optional reason for status change...'
        })
    )