from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.contrib import messages
from django.http import JsonResponse
from django.core.paginator import Paginator
from django.db.models import Q, Sum, Count, Avg
from django.utils import timezone
from django.views.decorators.http import require_http_methods
from django.db import transaction
from django.urls import reverse_lazy, reverse
from datetime import datetime, timedelta
import json
import logging

from apps.campaigns.models import Campaign, Brand, Agency, Creative, AdSpot, CampaignReport, AdBreakHistory
from apps.core.models import ActivityLog

logger = logging.getLogger(__name__)


# Dashboard View
@login_required
def dashboard(request):
    """
    Campaign management dashboard with statistics
    """
    # Get dashboard statistics
    total_campaigns = Campaign.objects.count()
    active_campaigns = Campaign.objects.filter(status='active').count()
    total_brands = Brand.objects.count()
    total_agencies = Agency.objects.count()
    
    # Recent campaigns
    recent_campaigns = Campaign.objects.select_related(
        'brand', 'agency'
    ).order_by('-created_at')[:5]
    
    # Performance metrics
    campaign_performance = Campaign.objects.aggregate(
        total_budget=Sum('budget'),
        avg_budget=Avg('budget')
    )
    
    context = {
        'total_campaigns': total_campaigns,
        'active_campaigns': active_campaigns,
        'total_brands': total_brands,
        'total_agencies': total_agencies,
        'recent_campaigns': recent_campaigns,
        'campaign_performance': campaign_performance,
    }
    
    return render(request, 'campaigns/dashboard.html', context)


# Brand Views
class BrandListView(LoginRequiredMixin, ListView):
    """
    List all brands with search and filtering
    """
    model = Brand
    template_name = 'campaigns/brand_list.html'
    context_object_name = 'brands'
    paginate_by = 20
    
    def get_queryset(self):
        queryset = Brand.objects.all()
        search = self.request.GET.get('search')
        
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) |
                Q(description__icontains=search)
            )
        
        return queryset.order_by('-created_at')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['search'] = self.request.GET.get('search', '')
        return context


class BrandDetailView(LoginRequiredMixin, DetailView):
    """
    Brand detail view with related campaigns
    """
    model = Brand
    template_name = 'campaigns/brand_detail.html'
    context_object_name = 'brand'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        brand = self.get_object()
        
        # Get related campaigns
        campaigns = Campaign.objects.filter(
            brand=brand
        ).select_related('agency').order_by('-created_at')
        
        context['campaigns'] = campaigns
        context['campaign_count'] = campaigns.count()
        
        return context


class BrandCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """
    Create new brand
    """
    model = Brand
    fields = ['name', 'description', 'logo', 'website', 'contact_email', 'contact_phone', 'is_active']
    template_name = 'campaigns/brand_form.html'
    permission_required = 'campaigns.add_brand'
    success_url = reverse_lazy('campaigns:brand_list')
    
    def form_valid(self, form):
        messages.success(self.request, 'Brand created successfully!')
        return super().form_valid(form)


class BrandUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """
    Update existing brand
    """
    model = Brand
    fields = ['name', 'description', 'logo', 'website', 'contact_email', 'contact_phone', 'is_active']
    template_name = 'campaigns/brand_form.html'
    permission_required = 'campaigns.change_brand'
    
    def get_success_url(self):
        return reverse('campaigns:brand_detail', kwargs={'pk': self.object.pk})
    
    def form_valid(self, form):
        messages.success(self.request, 'Brand updated successfully!')
        return super().form_valid(form)


class BrandDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """
    Delete brand
    """
    model = Brand
    template_name = 'campaigns/brand_confirm_delete.html'
    permission_required = 'campaigns.delete_brand'
    success_url = reverse_lazy('campaigns:brand_list')
    
    def delete(self, request, *args, **kwargs):
        messages.success(request, 'Brand deleted successfully!')
        return super().delete(request, *args, **kwargs)


# Agency Views
class AgencyListView(LoginRequiredMixin, ListView):
    """
    List all agencies with search and filtering
    """
    model = Agency
    template_name = 'campaigns/agency_list.html'
    context_object_name = 'agencies'
    paginate_by = 20
    
    def get_queryset(self):
        queryset = Agency.objects.all()
        search = self.request.GET.get('search')
        
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) |
                Q(description__icontains=search)
            )
        
        return queryset.order_by('-created_at')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['search'] = self.request.GET.get('search', '')
        return context


class AgencyDetailView(LoginRequiredMixin, DetailView):
    """
    Agency detail view with related campaigns
    """
    model = Agency
    template_name = 'campaigns/agency_detail.html'
    context_object_name = 'agency'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        agency = self.get_object()
        
        # Get related campaigns
        campaigns = Campaign.objects.filter(
            agency=agency
        ).select_related('brand').order_by('-created_at')
        
        context['campaigns'] = campaigns
        context['campaign_count'] = campaigns.count()
        
        return context


class AgencyCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """
    Create new agency
    """
    model = Agency
    fields = ['name', 'description', 'logo', 'website', 'contact_email', 'contact_phone', 'is_active']
    template_name = 'campaigns/agency_form.html'
    permission_required = 'campaigns.add_agency'
    success_url = reverse_lazy('campaigns:agency_list')
    
    def form_valid(self, form):
        messages.success(self.request, 'Agency created successfully!')
        return super().form_valid(form)


class AgencyUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """
    Update existing agency
    """
    model = Agency
    fields = ['name', 'description', 'logo', 'website', 'contact_email', 'contact_phone', 'is_active']
    template_name = 'campaigns/agency_form.html'
    permission_required = 'campaigns.change_agency'
    
    def get_success_url(self):
        return reverse('campaigns:agency_detail', kwargs={'pk': self.object.pk})
    
    def form_valid(self, form):
        messages.success(self.request, 'Agency updated successfully!')
        return super().form_valid(form)


class AgencyDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """
    Delete agency
    """
    model = Agency
    template_name = 'campaigns/agency_confirm_delete.html'
    permission_required = 'campaigns.delete_agency'
    success_url = reverse_lazy('campaigns:agency_list')
    
    def delete(self, request, *args, **kwargs):
        messages.success(request, 'Agency deleted successfully!')
        return super().delete(request, *args, **kwargs)


@login_required
def campaign_list(request):
    """List all campaigns with filtering and pagination."""
    campaigns = Campaign.objects.select_related('brand', 'agency', 'created_by').all()
    
    # Filtering
    search = request.GET.get('search')
    if search:
        campaigns = campaigns.filter(
            Q(name__icontains=search) |
            Q(brand__name__icontains=search) |
            Q(description__icontains=search)
        )
    
    status = request.GET.get('status')
    if status:
        campaigns = campaigns.filter(status=status)
    
    brand_id = request.GET.get('brand')
    if brand_id:
        campaigns = campaigns.filter(brand_id=brand_id)
    
    # Pagination
    paginator = Paginator(campaigns, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    # Get filter options
    brands = Brand.objects.filter(is_active=True).order_by('name')
    status_choices = Campaign.STATUS_CHOICES
    
    context = {
        'page_obj': page_obj,
        'brands': brands,
        'status_choices': status_choices,
        'current_search': search,
        'current_status': status,
        'current_brand': brand_id,
    }
    
    return render(request, 'campaigns/campaign_list.html', context)


@login_required
def campaign_detail(request, campaign_id):
    """Campaign detail view with performance metrics."""
    campaign = get_object_or_404(
        Campaign.objects.select_related('brand', 'agency', 'created_by', 'approved_by'),
        id=campaign_id
    )
    
    # Get ad spots
    adspots = campaign.adspots.select_related('creative').order_by('position')
    
    # Calculate metrics
    total_impressions = adspots.aggregate(Sum('impressions'))['impressions__sum'] or 0
    total_clicks = adspots.aggregate(Sum('clicks'))['clicks__sum'] or 0
    
    ctr = (total_clicks / total_impressions * 100) if total_impressions > 0 else 0
    
    # Recent activity
    recent_activity = ActivityLog.objects.filter(
        content_type__model='campaign',
        object_id=campaign.id
    ).select_related('user').order_by('-created_at')[:10]
    
    context = {
        'campaign': campaign,
        'adspots': adspots,
        'total_impressions': total_impressions,
        'total_clicks': total_clicks,
        'ctr': round(ctr, 2),
        'recent_activity': recent_activity,
    }
    
    return render(request, 'campaigns/campaign_detail.html', context)


@login_required
def campaign_create(request):
    """Create a new campaign."""
    if request.method == 'POST':
        try:
            with transaction.atomic():
                campaign = Campaign.objects.create(
                    name=request.POST['name'],
                    description=request.POST.get('description', ''),
                    brand_id=request.POST['brand'],
                    agency_id=request.POST.get('agency') or None,
                    campaign_type=request.POST.get('campaign_type', 'standard'),
                    start_date=request.POST['start_date'],
                    end_date=request.POST['end_date'],
                    budget=request.POST.get('budget') or None,
                    target_impressions=request.POST.get('target_impressions') or None,
                    created_by=request.user
                )
                
                # Log activity
                ActivityLog.objects.create(
                    user=request.user,
                    action='CREATE',
                    content_type='Campaign',
                    object_id=campaign.id,
                    description=f'Created campaign: {campaign.name}'
                )
                
                messages.success(request, f'Campaign "{campaign.name}" created successfully.')
                return redirect('campaigns:detail', campaign_id=campaign.id)
                
        except Exception as e:
            messages.error(request, f'Error creating campaign: {str(e)}')
    
    # Get form data
    brands = Brand.objects.filter(is_active=True).order_by('name')
    agencies = Agency.objects.filter(is_active=True).order_by('name')
    
    context = {
        'brands': brands,
        'agencies': agencies,
        'campaign_types': Campaign.CAMPAIGN_TYPES,
    }
    
    return render(request, 'campaigns/campaign_form.html', context)


@login_required
def campaign_edit(request, campaign_id):
    """Edit an existing campaign."""
    campaign = get_object_or_404(Campaign, id=campaign_id)
    
    if request.method == 'POST':
        try:
            with transaction.atomic():
                campaign.name = request.POST['name']
                campaign.description = request.POST.get('description', '')
                campaign.brand_id = request.POST['brand']
                campaign.agency_id = request.POST.get('agency') or None
                campaign.campaign_type = request.POST.get('campaign_type', 'standard')
                campaign.start_date = request.POST['start_date']
                campaign.end_date = request.POST['end_date']
                campaign.budget = request.POST.get('budget') or None
                campaign.target_impressions = request.POST.get('target_impressions') or None
                campaign.save()
                
                # Log activity
                ActivityLog.objects.create(
                    user=request.user,
                    action='UPDATE',
                    content_type='Campaign',
                    object_id=campaign.id,
                    description=f'Updated campaign: {campaign.name}'
                )
                
                messages.success(request, f'Campaign "{campaign.name}" updated successfully.')
                return redirect('campaigns:detail', campaign_id=campaign.id)
                
        except Exception as e:
            messages.error(request, f'Error updating campaign: {str(e)}')
    
    # Get form data
    brands = Brand.objects.filter(is_active=True).order_by('name')
    agencies = Agency.objects.filter(is_active=True).order_by('name')
    
    context = {
        'campaign': campaign,
        'brands': brands,
        'agencies': agencies,
        'campaign_types': Campaign.CAMPAIGN_TYPES,
        'is_edit': True,
    }
    
    return render(request, 'campaigns/campaign_form.html', context)


@login_required
@require_http_methods(["POST"])
def campaign_approve(request, campaign_id):
    """Approve a campaign."""
    campaign = get_object_or_404(Campaign, id=campaign_id)
    
    if not request.user.profile.can_manage_campaigns():
        messages.error(request, 'You do not have permission to approve campaigns.')
        return redirect('campaigns:detail', campaign_id=campaign.id)
    
    campaign.approve(request.user)
    
    # Log activity
    ActivityLog.objects.create(
        user=request.user,
        action='APPROVE',
        content_type='Campaign',
        object_id=campaign.id,
        description=f'Approved campaign: {campaign.name}'
    )
    
    messages.success(request, f'Campaign "{campaign.name}" approved successfully.')
    return redirect('campaigns:detail', campaign_id=campaign.id)


@login_required
def creative_list(request):
    """List all creatives with filtering."""
    creatives = Creative.objects.all()
    
    # Filtering
    search = request.GET.get('search')
    if search:
        creatives = creatives.filter(name__icontains=search)
    
    creative_type = request.GET.get('type')
    if creative_type:
        creatives = creatives.filter(creative_type=creative_type)
    
    approved = request.GET.get('approved')
    if approved == 'true':
        creatives = creatives.filter(is_approved=True)
    elif approved == 'false':
        creatives = creatives.filter(is_approved=False)
    
    # Pagination
    paginator = Paginator(creatives, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'page_obj': page_obj,
        'creative_types': Creative.CREATIVE_TYPES,
        'current_search': search,
        'current_type': creative_type,
        'current_approved': approved,
    }
    
    return render(request, 'campaigns/creative_list.html', context)


@login_required
def creative_upload(request):
    """Upload a new creative."""
    if request.method == 'POST':
        try:
            creative = Creative.objects.create(
                name=request.POST['name'],
                creative_type=request.POST['creative_type'],
                file=request.FILES['file'],
                duration=request.POST.get('duration') or None,
                width=request.POST.get('width') or None,
                height=request.POST.get('height') or None,
                bitrate=request.POST.get('bitrate') or None,
            )
            
            # Auto-approve if user has permission
            if request.user.profile.can_manage_campaigns():
                creative.is_approved = True
                creative.approved_by = request.user
                creative.approved_at = timezone.now()
                creative.save()
            
            # Log activity
            ActivityLog.objects.create(
                user=request.user,
                action='CREATE',
                content_type='Creative',
                object_id=creative.id,
                description=f'Uploaded creative: {creative.name}'
            )
            
            messages.success(request, f'Creative "{creative.name}" uploaded successfully.')
            return redirect('campaigns:creative_list')
            
        except Exception as e:
            messages.error(request, f'Error uploading creative: {str(e)}')
    
    context = {
        'creative_types': Creative.CREATIVE_TYPES,
    }
    
    return render(request, 'campaigns/creative_upload.html', context)


@login_required
def campaign_stats_api(request, campaign_id):
    """API endpoint for campaign statistics."""
    campaign = get_object_or_404(Campaign, id=campaign_id)
    
    # Get date range
    days = int(request.GET.get('days', 30))
    end_date = timezone.now().date()
    start_date = end_date - timezone.timedelta(days=days)
    
    # Get daily stats
    daily_stats = []
    current_date = start_date
    
    while current_date <= end_date:
        day_impressions = campaign.adspots.filter(
            history__executed_at__date=current_date
        ).aggregate(Sum('history__impressions'))['history__impressions__sum'] or 0
        
        daily_stats.append({
            'date': current_date.isoformat(),
            'impressions': day_impressions,
        })
        
        current_date += timezone.timedelta(days=1)
    
    return JsonResponse({
        'daily_stats': daily_stats,
        'total_impressions': campaign.total_impressions,
        'total_adspots': campaign.adspots.count(),
    })


# Additional Creative Views
class CreativeDetailView(LoginRequiredMixin, DetailView):
    """
    Creative detail view
    """
    model = Creative
    template_name = 'campaigns/creative_detail.html'
    context_object_name = 'creative'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        creative = self.get_object()
        
        # Get related ad spots
        ad_spots = AdSpot.objects.filter(
            creative=creative
        ).select_related('campaign')
        
        context['ad_spots'] = ad_spots
        context['ad_spot_count'] = ad_spots.count()
        
        return context


@login_required
@require_http_methods(["POST"])
def creative_approve(request, creative_id):
    """
    Approve a creative
    """
    creative = get_object_or_404(Creative, pk=creative_id)
    
    if not request.user.profile.can_manage_campaigns():
        messages.error(request, 'You do not have permission to approve creatives.')
        return redirect('campaigns:creative_list')
    
    creative.is_approved = True
    creative.approved_by = request.user
    creative.approved_at = timezone.now()
    creative.save()
    
    # Log activity
    ActivityLog.objects.create(
        user=request.user,
        action='APPROVE',
        content_type='Creative',
        object_id=creative.id,
        description=f'Approved creative: {creative.name}'
    )
    
    messages.success(request, f'Creative "{creative.name}" has been approved.')
    return redirect('campaigns:creative_list')


@login_required
@require_http_methods(["POST"])
def creative_reject(request, creative_id):
    """
    Reject a creative
    """
    creative = get_object_or_404(Creative, pk=creative_id)
    
    if not request.user.profile.can_manage_campaigns():
        messages.error(request, 'You do not have permission to reject creatives.')
        return redirect('campaigns:creative_list')
    
    rejection_reason = request.POST.get('rejection_reason', '')
    
    creative.is_approved = False
    creative.rejection_reason = rejection_reason
    creative.approved_by = request.user
    creative.approved_at = timezone.now()
    creative.save()
    
    # Log activity
    ActivityLog.objects.create(
        user=request.user,
        action='REJECT',
        content_type='Creative',
        object_id=creative.id,
        description=f'Rejected creative: {creative.name}. Reason: {rejection_reason}'
    )
    
    messages.success(request, f'Creative "{creative.name}" has been rejected.')
    return redirect('campaigns:creative_list')


# AdSpot Views
@login_required
def adspot_list(request):
    """
    List all ad spots with filtering
    """
    ad_spots = AdSpot.objects.select_related('campaign', 'creative')
    
    # Filtering
    search = request.GET.get('search')
    if search:
        ad_spots = ad_spots.filter(
            Q(name__icontains=search) |
            Q(description__icontains=search)
        )
    
    campaign_id = request.GET.get('campaign')
    if campaign_id:
        ad_spots = ad_spots.filter(campaign_id=campaign_id)
    
    status = request.GET.get('status')
    if status:
        ad_spots = ad_spots.filter(status=status)
    
    # Pagination
    paginator = Paginator(ad_spots, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'page_obj': page_obj,
        'campaigns': Campaign.objects.filter(status='active'),
        'current_search': search,
        'current_campaign': campaign_id,
        'current_status': status,
    }
    
    return render(request, 'campaigns/adspot_list.html', context)


@login_required
def adspot_detail(request, adspot_id):
    """
    AdSpot detail view with performance metrics
    """
    ad_spot = get_object_or_404(AdSpot, pk=adspot_id)
    
    # Calculate performance metrics
    ctr = ad_spot.ctr
    total_impressions = ad_spot.impressions
    total_clicks = ad_spot.clicks
    
    context = {
        'ad_spot': ad_spot,
        'ctr': ctr,
        'total_impressions': total_impressions,
        'total_clicks': total_clicks,
    }
    
    return render(request, 'campaigns/adspot_detail.html', context)


@login_required
def adspot_create(request):
    """
    Create new ad spot
    """
    if request.method == 'POST':
        try:
            ad_spot = AdSpot.objects.create(
                campaign_id=request.POST['campaign'],
                creative_id=request.POST.get('creative') or None,
                name=request.POST['name'],
                description=request.POST.get('description', ''),
                position=request.POST.get('position', 0),
                start_time=request.POST.get('start_time') or None,
                end_time=request.POST.get('end_time') or None,
                targeting_criteria=request.POST.get('targeting_criteria', '{}'),
                max_impressions=request.POST.get('max_impressions') or None,
                max_clicks=request.POST.get('max_clicks') or None,
            )
            
            # Log activity
            ActivityLog.objects.create(
                user=request.user,
                action='CREATE',
                content_type='AdSpot',
                object_id=ad_spot.id,
                description=f'Created ad spot: {ad_spot.name}'
            )
            
            messages.success(request, f'Ad spot "{ad_spot.name}" created successfully.')
            return redirect('campaigns:adspot_detail', adspot_id=ad_spot.id)
            
        except Exception as e:
            messages.error(request, f'Error creating ad spot: {str(e)}')
    
    context = {
        'campaigns': Campaign.objects.filter(status='active'),
        'creatives': Creative.objects.filter(is_approved=True),
    }
    
    return render(request, 'campaigns/adspot_form.html', context)


@login_required
def adspot_edit(request, adspot_id):
    """
    Update existing ad spot
    """
    ad_spot = get_object_or_404(AdSpot, pk=adspot_id)
    
    if request.method == 'POST':
        try:
            ad_spot.name = request.POST['name']
            ad_spot.description = request.POST.get('description', '')
            ad_spot.position = request.POST.get('position', 0)
            ad_spot.start_time = request.POST.get('start_time') or None
            ad_spot.end_time = request.POST.get('end_time') or None
            ad_spot.targeting_criteria = request.POST.get('targeting_criteria', '{}')
            ad_spot.max_impressions = request.POST.get('max_impressions') or None
            ad_spot.max_clicks = request.POST.get('max_clicks') or None
            ad_spot.status = request.POST.get('status', 'active')
            ad_spot.save()
            
            # Log activity
            ActivityLog.objects.create(
                user=request.user,
                action='UPDATE',
                content_type='AdSpot',
                object_id=ad_spot.id,
                description=f'Updated ad spot: {ad_spot.name}'
            )
            
            messages.success(request, f'Ad spot "{ad_spot.name}" updated successfully.')
            return redirect('campaigns:adspot_detail', adspot_id=ad_spot.id)
            
        except Exception as e:
            messages.error(request, f'Error updating ad spot: {str(e)}')
    
    context = {
        'ad_spot': ad_spot,
        'campaigns': Campaign.objects.filter(status='active'),
        'creatives': Creative.objects.filter(is_approved=True),
        'is_edit': True,
    }
    
    return render(request, 'campaigns/adspot_form.html', context)


# Campaign Report Views
@login_required
def report_list(request):
    """
    List all campaign reports
    """
    reports = CampaignReport.objects.select_related('campaign')
    
    # Filtering
    campaign_id = request.GET.get('campaign')
    if campaign_id:
        reports = reports.filter(campaign_id=campaign_id)
    
    report_type = request.GET.get('type')
    if report_type:
        reports = reports.filter(report_type=report_type)
    
    # Pagination
    paginator = Paginator(reports, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'page_obj': page_obj,
        'campaigns': Campaign.objects.all(),
        'current_campaign': campaign_id,
        'current_type': report_type,
    }
    
    return render(request, 'campaigns/report_list.html', context)


@login_required
def report_detail(request, report_id):
    """
    Campaign report detail view
    """
    report = get_object_or_404(CampaignReport, pk=report_id)
    
    # Calculate additional metrics
    ctr = report.ctr
    cpm = report.cpm
    cpc = report.cpc
    
    context = {
        'report': report,
        'ctr': ctr,
        'cpm': cpm,
        'cpc': cpc,
    }
    
    return render(request, 'campaigns/report_detail.html', context)


@login_required
def generate_report(request, campaign_id):
    """
    Generate a new campaign report
    """
    campaign = get_object_or_404(Campaign, pk=campaign_id)
    
    if not request.user.profile.can_manage_campaigns():
        messages.error(request, 'You do not have permission to generate reports.')
        return redirect('campaigns:detail', campaign_id=campaign_id)
    
    if request.method == 'POST':
        report_type = request.POST.get('report_type', 'performance')
        start_date = request.POST.get('start_date')
        end_date = request.POST.get('end_date')
        
        if start_date:
            start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
        else:
            start_date = campaign.start_date
        
        if end_date:
            end_date = datetime.strptime(end_date, '%Y-%m-%d').date()
        else:
            end_date = campaign.end_date or timezone.now().date()
        
        # Calculate metrics from ad spots
        ad_spots = AdSpot.objects.filter(
            campaign=campaign,
            created_at__date__gte=start_date,
            created_at__date__lte=end_date
        )
        
        total_impressions = ad_spots.aggregate(Sum('impressions'))['impressions__sum'] or 0
        total_clicks = ad_spots.aggregate(Sum('clicks'))['clicks__sum'] or 0
        total_spend = campaign.budget or 0
        
        # Create report
        report = CampaignReport.objects.create(
            campaign=campaign,
            report_type=report_type,
            start_date=start_date,
            end_date=end_date,
            impressions=total_impressions,
            clicks=total_clicks,
            spend=total_spend,
            generated_by=request.user
        )
        
        # Log activity
        ActivityLog.objects.create(
            user=request.user,
            action='CREATE',
            content_type='CampaignReport',
            object_id=report.id,
            description=f'Generated report for campaign: {campaign.name}'
        )
        
        messages.success(request, 'Campaign report generated successfully!')
        return redirect('campaigns:report_detail', report_id=report.id)
    
    context = {
        'campaign': campaign,
    }
    
    return render(request, 'campaigns/generate_report.html', context)


# AJAX Views
@login_required
def campaign_search_ajax(request):
    """
    AJAX search for campaigns
    """
    query = request.GET.get('q', '')
    campaigns = Campaign.objects.filter(
        Q(name__icontains=query) |
        Q(description__icontains=query)
    )[:10]
    
    results = []
    for campaign in campaigns:
        results.append({
            'id': campaign.id,
            'name': campaign.name,
            'status': campaign.status,
            'brand': campaign.brand.name if campaign.brand else '',
            'agency': campaign.agency.name if campaign.agency else ''
        })
    
    return JsonResponse({'results': results})


@login_required
def brand_search_ajax(request):
    """
    AJAX search for brands
    """
    query = request.GET.get('q', '')
    brands = Brand.objects.filter(
        Q(name__icontains=query)
    )[:10]
    
    results = []
    for brand in brands:
        results.append({
            'id': brand.id,
            'name': brand.name,
            'is_active': brand.is_active
        })
    
    return JsonResponse({'results': results})


@login_required
def agency_search_ajax(request):
    """
    AJAX search for agencies
    """
    query = request.GET.get('q', '')
    agencies = Agency.objects.filter(
        Q(name__icontains=query)
    )[:10]
    
    results = []
    for agency in agencies:
        results.append({
            'id': agency.id,
            'name': agency.name,
            'is_active': agency.is_active
        })
    
    return JsonResponse({'results': results})


@login_required
def campaign_performance_ajax(request, campaign_id):
    """
    AJAX endpoint for campaign performance data
    """
    campaign = get_object_or_404(Campaign, pk=campaign_id)
    
    # Get performance data from ad spots
    ad_spots = AdSpot.objects.filter(campaign=campaign)
    
    total_impressions = ad_spots.aggregate(Sum('impressions'))['impressions__sum'] or 0
    total_clicks = ad_spots.aggregate(Sum('clicks'))['clicks__sum'] or 0
    
    # Calculate CTR
    ctr = (total_clicks / total_impressions * 100) if total_impressions > 0 else 0
    
    # Get daily performance for the last 30 days
    end_date = timezone.now().date()
    start_date = end_date - timedelta(days=30)
    
    daily_performance = []
    current_date = start_date
    while current_date <= end_date:
        day_spots = ad_spots.filter(created_at__date=current_date)
        day_impressions = day_spots.aggregate(Sum('impressions'))['impressions__sum'] or 0
        day_clicks = day_spots.aggregate(Sum('clicks'))['clicks__sum'] or 0
        
        daily_performance.append({
            'date': current_date.strftime('%Y-%m-%d'),
            'impressions': day_impressions,
            'clicks': day_clicks
        })
        
        current_date += timedelta(days=1)
    
    return JsonResponse({
        'total_impressions': total_impressions,
        'total_clicks': total_clicks,
        'ctr': round(ctr, 2),
        'daily_performance': daily_performance
    })