# -*- coding: utf-8 -*-
"""
This module contains Django forms for the advertisers app.
Handles form validation and rendering for agency and brand management.

Forms:
    - AgencyForm: Form for creating and editing agencies
    - BrandForm: Form for creating and editing brands
    - BrandCategoryForm: Form for managing brand categories
    - UserAdvertiserForm: Form for managing user-brand relationships
    - BulkUserAdvertiserForm: Form for bulk user-brand assignments
    - AgencySearchForm: Form for searching agencies
    - BrandSearchForm: Form for searching brands
"""

from django import forms
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _

from .models import Agency, Brand, BrandCategory, UserAdvertiser


User = get_user_model()


class AgencyForm(forms.ModelForm):
    """Form for creating and editing agencies.
    
    Includes validation for email uniqueness and proper field widgets.
    """
    
    class Meta:
        model = Agency
        fields = [
            'name', 'description', 'email', 'phone', 'website',
            'address', 'city', 'country', 'logo', 'contact_person', 'status'
        ]
        
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter agency name',
                'required': True
            }),
            'description': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 4,
                'placeholder': 'Enter agency description'
            }),
            'email': forms.EmailInput(attrs={
                'class': 'form-control',
                'placeholder': 'agency@example.com'
            }),
            'phone': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': '+1 (555) 123-4567'
            }),
            'website': forms.URLInput(attrs={
                'class': 'form-control',
                'placeholder': 'https://www.agency.com'
            }),
            'address': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter street address'
            }),
            'city': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter city'
            }),
            'country': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter country'
            }),
            'contact_person': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter contact person name'
            }),
            'logo': forms.ClearableFileInput(attrs={
                'class': 'form-control',
                'accept': 'image/*'
            }),
            'status': forms.Select(attrs={
                'class': 'form-select'
            })
        }
        
        labels = {
            'name': _('Agency Name'),
            'description': _('Description'),
            'email': _('Email Address'),
            'phone': _('Phone Number'),
            'website': _('Website URL'),
            'address': _('Street Address'),
            'city': _('City'),
            'country': _('Country'),
            'contact_person': _('Contact Person'),
            'logo': _('Agency Logo'),
            'status': _('Status')
        }
        
        help_texts = {
            'email': _('This email will be used for agency communications.'),
            'website': _('Include http:// or https://'),
            'logo': _('Upload agency logo (max 2MB, JPG/PNG format)'),
        }
    
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        
        # Make certain fields required
        self.fields['name'].required = True
        self.fields['email'].required = True
        
        # Add custom validation messages
        self.fields['email'].error_messages = {
            'invalid': _('Please enter a valid email address.'),
            'required': _('Email address is required.')
        }
    
    def clean_email(self):
        """Validate email uniqueness."""
        email = self.cleaned_data.get('email')
        if email:
            # Check if email already exists (excluding current instance)
            existing_agency = Agency.objects.filter(email=email)
            if self.instance and self.instance.pk:
                existing_agency = existing_agency.exclude(pk=self.instance.pk)
            
            if existing_agency.exists():
                raise ValidationError(
                    _('An agency with this email address already exists.')
                )
        
        return email
    
    def clean_logo(self):
        """Validate logo file."""
        logo = self.cleaned_data.get('logo')
        if logo:
            # Check file size (max 2MB)
            if logo.size > 2 * 1024 * 1024:
                raise ValidationError(
                    _('Logo file size must be less than 2MB.')
                )
            
            # Check file type
            allowed_types = ['image/jpeg', 'image/png', 'image/gif']
            if logo.content_type not in allowed_types:
                raise ValidationError(
                    _('Logo must be a JPEG, PNG, or GIF image.')
                )
        
        return logo
    
    def save(self, commit=True):
        """Save agency with owner assignment."""
        agency = super().save(commit=False)
        
        # Set owner if creating new agency
        if not agency.pk and self.user:
            agency.owner = self.user
        
        if commit:
            agency.save()
        
        return agency


class BrandForm(forms.ModelForm):
    """Form for creating and editing brands.
    
    Includes dynamic agency filtering and validation.
    """
    
    class Meta:
        model = Brand
        fields = [
            'name', 'description', 'category', 'agency', 'logo',
            'website', 'contact_email', 'contact_phone', 'industry',
            'target_audience', 'annual_budget', 'status'
        ]
        
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter brand name',
                'required': True
            }),
            'description': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 4,
                'placeholder': 'Enter brand description'
            }),
            'category': forms.Select(attrs={
                'class': 'form-select'
            }),
            'agency': forms.Select(attrs={
                'class': 'form-select',
                'required': True
            }),
            'logo': forms.ClearableFileInput(attrs={
                'class': 'form-control',
                'accept': 'image/*'
            }),
            'website': forms.URLInput(attrs={
                'class': 'form-control',
                'placeholder': 'https://www.brand.com'
            }),
            'contact_email': forms.EmailInput(attrs={
                'class': 'form-control',
                'placeholder': 'contact@brand.com'
            }),
            'contact_phone': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': '+1 (555) 123-4567'
            }),
            'industry': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'e.g., Technology, Healthcare, Retail'
            }),
            'target_audience': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': 'Describe your target audience'
            }),
            'annual_budget': forms.NumberInput(attrs={
                'class': 'form-control',
                'placeholder': '0.00',
                'step': '0.01',
                'min': '0'
            }),
            'status': forms.Select(attrs={
                'class': 'form-select'
            })
        }
        
        labels = {
            'name': _('Brand Name'),
            'description': _('Description'),
            'category': _('Category'),
            'agency': _('Agency'),
            'logo': _('Brand Logo'),
            'website': _('Website URL'),
            'contact_email': _('Contact Email'),
            'contact_phone': _('Contact Phone'),
            'industry': _('Industry'),
            'target_audience': _('Target Audience'),
            'annual_budget': _('Annual Budget'),
            'status': _('Status')
        }
    
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        
        # Filter agencies based on user permissions
        if self.user and not self.user.is_superuser:
            self.fields['agency'].queryset = Agency.objects.filter(
                owner=self.user,
                status='active'
            )
        else:
            self.fields['agency'].queryset = Agency.objects.filter(status='active')
        
        # Set category queryset
        self.fields['category'].queryset = BrandCategory.objects.all()
        self.fields['category'].empty_label = "Select a category"
        
        # Make required fields
        self.fields['name'].required = True
        self.fields['agency'].required = True
    
    def clean(self):
        """Validate brand data."""
        cleaned_data = super().clean()
        name = cleaned_data.get('name')
        agency = cleaned_data.get('agency')
        
        if name and agency:
            # Check if brand name is unique within the agency
            existing_brand = Brand.objects.filter(agency=agency, name=name)
            if self.instance and self.instance.pk:
                existing_brand = existing_brand.exclude(pk=self.instance.pk)
            
            if existing_brand.exists():
                raise ValidationError({
                    'name': _('A brand with this name already exists in this agency.')
                })
        
        return cleaned_data
    
    def clean_logo(self):
        """Validate logo file."""
        logo = self.cleaned_data.get('logo')
        if logo:
            # Check file size (max 2MB)
            if logo.size > 2 * 1024 * 1024:
                raise ValidationError(
                    _('Logo file size must be less than 2MB.')
                )
            
            # Check file type
            allowed_types = ['image/jpeg', 'image/png', 'image/gif']
            if logo.content_type not in allowed_types:
                raise ValidationError(
                    _('Logo must be a JPEG, PNG, or GIF image.')
                )
        
        return logo


class BrandCategoryForm(forms.ModelForm):
    """Form for creating and editing brand categories."""
    
    class Meta:
        model = BrandCategory
        fields = ['name', 'description', 'parent']
        
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter category name',
                'required': True
            }),
            'description': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': 'Enter category description'
            }),
            'parent': forms.Select(attrs={
                'class': 'form-select'
            })
        }
        
        labels = {
            'name': _('Category Name'),
            'description': _('Description'),
            'parent': _('Parent Category')
        }
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        # Set parent category choices (exclude self to prevent circular reference)
        if self.instance and self.instance.pk:
            self.fields['parent'].queryset = BrandCategory.objects.exclude(
                pk=self.instance.pk
            )
        else:
            self.fields['parent'].queryset = BrandCategory.objects.all()
        
        self.fields['parent'].empty_label = "No parent category"
        self.fields['name'].required = True


class UserAdvertiserForm(forms.ModelForm):
    """Form for managing user-brand relationships."""
    
    class Meta:
        model = UserAdvertiser
        fields = ['user', 'brand', 'role', 'is_active']
        
        widgets = {
            'user': forms.Select(attrs={
                'class': 'form-select',
                'required': True
            }),
            'brand': forms.Select(attrs={
                'class': 'form-select',
                'required': True
            }),
            'role': forms.Select(attrs={
                'class': 'form-select'
            }),
            'is_active': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            })
        }
        
        labels = {
            'user': _('User'),
            'brand': _('Brand'),
            'role': _('Role'),
            'is_active': _('Active')
        }
    
    def __init__(self, *args, **kwargs):
        self.current_user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        
        # Filter brands based on user permissions
        if self.current_user and not self.current_user.is_superuser:
            self.fields['brand'].queryset = Brand.objects.filter(
                agency__owner=self.current_user,
                status='active'
            )
        else:
            self.fields['brand'].queryset = Brand.objects.filter(status='active')
        
        # Set user queryset (active users only)
        self.fields['user'].queryset = User.objects.filter(is_active=True)
    
    def clean(self):
        """Validate user-brand relationship."""
        cleaned_data = super().clean()
        user = cleaned_data.get('user')
        brand = cleaned_data.get('brand')
        
        if user and brand:
            # Check if relationship already exists
            existing_relationship = UserAdvertiser.objects.filter(
                user=user, 
                brand=brand
            )
            if self.instance and self.instance.pk:
                existing_relationship = existing_relationship.exclude(
                    pk=self.instance.pk
                )
            
            if existing_relationship.exists():
                raise ValidationError(
                    _('This user-brand relationship already exists.')
                )
        
        return cleaned_data


class BulkUserAdvertiserForm(forms.Form):
    """Form for bulk user-brand relationship creation."""
    
    users = forms.ModelMultipleChoiceField(
        queryset=User.objects.filter(is_active=True),
        widget=forms.SelectMultiple(attrs={
            'class': 'form-select',
            'multiple': True,
            'size': '10'
        }),
        label=_('Users'),
        help_text=_('Select multiple users to assign to brands.')
    )
    
    brands = forms.ModelMultipleChoiceField(
        queryset=Brand.objects.filter(status='active'),
        widget=forms.SelectMultiple(attrs={
            'class': 'form-select',
            'multiple': True,
            'size': '10'
        }),
        label=_('Brands'),
        help_text=_('Select multiple brands to assign users to.')
    )
    
    role = forms.ChoiceField(
        choices=UserAdvertiser.ROLE_CHOICES,
        initial='viewer',
        widget=forms.Select(attrs={
            'class': 'form-select'
        }),
        label=_('Role'),
        help_text=_('Role to assign to all selected user-brand relationships.')
    )
    
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        
        # Filter brands based on user permissions
        if self.user and not self.user.is_superuser:
            self.fields['brands'].queryset = Brand.objects.filter(
                agency__owner=self.user,
                status='active'
            )


class AgencySearchForm(forms.Form):
    """Form for searching agencies."""
    
    search = forms.CharField(
        max_length=255,
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Search agencies...',
            'autocomplete': 'off'
        }),
        label=_('Search')
    )
    
    status = forms.ChoiceField(
        choices=[('', 'All Statuses')] + Agency.STATUS_CHOICES,
        required=False,
        widget=forms.Select(attrs={
            'class': 'form-select'
        }),
        label=_('Status')
    )
    
    country = forms.CharField(
        max_length=100,
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Filter by country'
        }),
        label=_('Country')
    )


class BrandSearchForm(forms.Form):
    """Form for searching brands."""
    
    search = forms.CharField(
        max_length=255,
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Search brands...',
            'autocomplete': 'off'
        }),
        label=_('Search')
    )
    
    agency = forms.ModelChoiceField(
        queryset=Agency.objects.filter(status='active'),
        required=False,
        empty_label='All Agencies',
        widget=forms.Select(attrs={
            'class': 'form-select'
        }),
        label=_('Agency')
    )
    
    category = forms.ModelChoiceField(
        queryset=BrandCategory.objects.all(),
        required=False,
        empty_label='All Categories',
        widget=forms.Select(attrs={
            'class': 'form-select'
        }),
        label=_('Category')
    )
    
    status = forms.ChoiceField(
        choices=[('', 'All Statuses')] + Brand.STATUS_CHOICES,
        required=False,
        widget=forms.Select(attrs={
            'class': 'form-select'
        }),
        label=_('Status')
    )
    
    industry = forms.CharField(
        max_length=100,
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Filter by industry'
        }),
        label=_('Industry')
    )
    
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        
        # Filter agencies based on user permissions
        if self.user and not self.user.is_superuser:
            self.fields['agency'].queryset = Agency.objects.filter(
                owner=self.user,
                status='active'
            )