from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
from django.core.paginator import Paginator
from django.db.models import Q, Count, Sum
from django.views.decorators.http import require_http_methods
from django.db import transaction
from django.contrib.auth.models import User

from apps.advertisers.models import Advertiser, AdvertiserContact, UserAdvertiser, AdvertiserBilling, AdvertiserNote
from apps.core.models import ActivityLog
from apps.campaigns.models import Campaign


@login_required
def advertiser_list(request):
    """List all advertisers with filtering and pagination."""
    advertisers = Advertiser.objects.select_related('account_manager').all()
    
    # Check user permissions
    if not request.user.profile.can_manage_users():
        # Show only advertisers the user has access to
        user_advertiser_ids = request.user.advertiser_access.values_list('advertiser_id', flat=True)
        advertisers = advertisers.filter(id__in=user_advertiser_ids)
    
    # Filtering
    search = request.GET.get('search')
    if search:
        advertisers = advertisers.filter(
            Q(name__icontains=search) |
            Q(company_name__icontains=search) |
            Q(contact_person__icontains=search) |
            Q(email__icontains=search)
        )
    
    advertiser_type = request.GET.get('type')
    if advertiser_type:
        advertisers = advertisers.filter(advertiser_type=advertiser_type)
    
    is_active = request.GET.get('active')
    if is_active == 'true':
        advertisers = advertisers.filter(is_active=True)
    elif is_active == 'false':
        advertisers = advertisers.filter(is_active=False)
    
    # Annotate with campaign counts
    advertisers = advertisers.annotate(
        total_campaigns=Count('brands__campaigns'),
        active_campaigns=Count('brands__campaigns', filter=Q(brands__campaigns__status='active'))
    )
    
    # Pagination
    paginator = Paginator(advertisers, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'page_obj': page_obj,
        'advertiser_types': Advertiser.ADVERTISER_TYPES,
        'current_search': search,
        'current_type': advertiser_type,
        'current_active': is_active,
    }
    
    return render(request, 'advertisers/advertiser_list.html', context)


@login_required
def advertiser_detail(request, advertiser_id):
    """Advertiser detail view with campaigns and contacts."""
    advertiser = get_object_or_404(
        Advertiser.objects.select_related('account_manager', 'parent_agency'),
        id=advertiser_id
    )
    
    # Check user permissions
    if not request.user.profile.can_manage_users():
        try:
            user_access = UserAdvertiser.objects.get(
                user=request.user,
                advertiser=advertiser
            )
        except UserAdvertiser.DoesNotExist:
            messages.error(request, 'You do not have access to this advertiser.')
            return redirect('advertisers:list')
    
    # Get related data
    contacts = advertiser.contacts.all().order_by('contact_type', 'last_name')
    campaigns = Campaign.objects.filter(
        brand__in=advertiser.brands.all()
    ).select_related('brand').order_by('-created_at')[:10]
    
    user_access = advertiser.user_access.select_related('user').all()
    notes = advertiser.notes.select_related('user').order_by('-created_at')[:10]
    
    # Calculate metrics
    total_campaigns = advertiser.get_total_campaigns()
    active_campaigns = advertiser.get_active_campaigns()
    
    # Recent activity
    recent_activity = ActivityLog.objects.filter(
        content_type__model='advertiser',
        object_id=advertiser.id
    ).select_related('user').order_by('-created_at')[:10]
    
    context = {
        'advertiser': advertiser,
        'contacts': contacts,
        'campaigns': campaigns,
        'user_access': user_access,
        'notes': notes,
        'total_campaigns': total_campaigns,
        'active_campaigns': active_campaigns,
        'recent_activity': recent_activity,
    }
    
    return render(request, 'advertisers/advertiser_detail.html', context)


@login_required
def advertiser_create(request):
    """Create a new advertiser."""
    if not request.user.profile.can_manage_users():
        messages.error(request, 'You do not have permission to create advertisers.')
        return redirect('advertisers:list')
    
    if request.method == 'POST':
        try:
            with transaction.atomic():
                advertiser = Advertiser.objects.create(
                    name=request.POST['name'],
                    company_name=request.POST.get('company_name', ''),
                    advertiser_type=request.POST.get('advertiser_type', 'direct'),
                    contact_person=request.POST.get('contact_person', ''),
                    email=request.POST.get('email', ''),
                    phone=request.POST.get('phone', ''),
                    website=request.POST.get('website', ''),
                    address_line1=request.POST.get('address_line1', ''),
                    address_line2=request.POST.get('address_line2', ''),
                    city=request.POST.get('city', ''),
                    state=request.POST.get('state', ''),
                    postal_code=request.POST.get('postal_code', ''),
                    country=request.POST.get('country', ''),
                    tax_id=request.POST.get('tax_id', ''),
                    industry=request.POST.get('industry', ''),
                    credit_limit=request.POST.get('credit_limit') or None,
                    payment_terms=request.POST.get('payment_terms', ''),
                    account_manager_id=request.POST.get('account_manager') or None,
                )
                
                # Create billing record
                AdvertiserBilling.objects.create(advertiser=advertiser)
                
                # Log activity
                ActivityLog.objects.create(
                    user=request.user,
                    action='CREATE',
                    content_type='Advertiser',
                    object_id=advertiser.id,
                    description=f'Created advertiser: {advertiser.name}'
                )
                
                messages.success(request, f'Advertiser "{advertiser.name}" created successfully.')
                return redirect('advertisers:detail', advertiser_id=advertiser.id)
                
        except Exception as e:
            messages.error(request, f'Error creating advertiser: {str(e)}')
    
    # Get form data
    account_managers = User.objects.filter(
        profile__user_type__in=['admin', 'manager']
    ).order_by('first_name', 'last_name')
    
    context = {
        'advertiser_types': Advertiser.ADVERTISER_TYPES,
        'account_managers': account_managers,
    }
    
    return render(request, 'advertisers/advertiser_form.html', context)


@login_required
def advertiser_edit(request, advertiser_id):
    """Edit an existing advertiser."""
    advertiser = get_object_or_404(Advertiser, id=advertiser_id)
    
    # Check permissions
    if not request.user.profile.can_manage_users():
        try:
            user_access = UserAdvertiser.objects.get(
                user=request.user,
                advertiser=advertiser
            )
            if user_access.permission_level not in ['edit', 'manage']:
                messages.error(request, 'You do not have permission to edit this advertiser.')
                return redirect('advertisers:detail', advertiser_id=advertiser.id)
        except UserAdvertiser.DoesNotExist:
            messages.error(request, 'You do not have access to this advertiser.')
            return redirect('advertisers:list')
    
    if request.method == 'POST':
        try:
            with transaction.atomic():
                advertiser.name = request.POST['name']
                advertiser.company_name = request.POST.get('company_name', '')
                advertiser.advertiser_type = request.POST.get('advertiser_type', 'direct')
                advertiser.contact_person = request.POST.get('contact_person', '')
                advertiser.email = request.POST.get('email', '')
                advertiser.phone = request.POST.get('phone', '')
                advertiser.website = request.POST.get('website', '')
                advertiser.address_line1 = request.POST.get('address_line1', '')
                advertiser.address_line2 = request.POST.get('address_line2', '')
                advertiser.city = request.POST.get('city', '')
                advertiser.state = request.POST.get('state', '')
                advertiser.postal_code = request.POST.get('postal_code', '')
                advertiser.country = request.POST.get('country', '')
                advertiser.tax_id = request.POST.get('tax_id', '')
                advertiser.industry = request.POST.get('industry', '')
                advertiser.credit_limit = request.POST.get('credit_limit') or None
                advertiser.payment_terms = request.POST.get('payment_terms', '')
                advertiser.account_manager_id = request.POST.get('account_manager') or None
                advertiser.save()
                
                # Log activity
                ActivityLog.objects.create(
                    user=request.user,
                    action='UPDATE',
                    content_type='Advertiser',
                    object_id=advertiser.id,
                    description=f'Updated advertiser: {advertiser.name}'
                )
                
                messages.success(request, f'Advertiser "{advertiser.name}" updated successfully.')
                return redirect('advertisers:detail', advertiser_id=advertiser.id)
                
        except Exception as e:
            messages.error(request, f'Error updating advertiser: {str(e)}')
    
    # Get form data
    account_managers = User.objects.filter(
        profile__user_type__in=['admin', 'manager']
    ).order_by('first_name', 'last_name')
    
    context = {
        'advertiser': advertiser,
        'advertiser_types': Advertiser.ADVERTISER_TYPES,
        'account_managers': account_managers,
        'is_edit': True,
    }
    
    return render(request, 'advertisers/advertiser_form.html', context)


@login_required
def add_contact(request, advertiser_id):
    """Add a new contact to an advertiser."""
    advertiser = get_object_or_404(Advertiser, id=advertiser_id)
    
    if request.method == 'POST':
        try:
            contact = AdvertiserContact.objects.create(
                advertiser=advertiser,
                contact_type=request.POST['contact_type'],
                first_name=request.POST['first_name'],
                last_name=request.POST['last_name'],
                title=request.POST.get('title', ''),
                email=request.POST['email'],
                phone=request.POST.get('phone', ''),
                mobile=request.POST.get('mobile', ''),
                is_primary=request.POST.get('is_primary') == 'on',
                receive_reports=request.POST.get('receive_reports') == 'on',
                receive_notifications=request.POST.get('receive_notifications') == 'on',
            )
            
            # Log activity
            ActivityLog.objects.create(
                user=request.user,
                action='CREATE',
                content_type='AdvertiserContact',
                object_id=contact.id,
                description=f'Added contact {contact.full_name} to {advertiser.name}'
            )
            
            messages.success(request, f'Contact "{contact.full_name}" added successfully.')
            
        except Exception as e:
            messages.error(request, f'Error adding contact: {str(e)}')
    
    return redirect('advertisers:detail', advertiser_id=advertiser.id)


@login_required
def manage_user_access(request, advertiser_id):
    """Manage user access to an advertiser."""
    advertiser = get_object_or_404(Advertiser, id=advertiser_id)
    
    if not request.user.profile.can_manage_users():
        messages.error(request, 'You do not have permission to manage user access.')
        return redirect('advertisers:detail', advertiser_id=advertiser.id)
    
    if request.method == 'POST':
        try:
            user_id = request.POST['user']
            user = get_object_or_404(User, id=user_id)
            
            user_access, created = UserAdvertiser.objects.get_or_create(
                user=user,
                advertiser=advertiser,
                defaults={
                    'permission_level': request.POST['permission_level'],
                    'granted_by': request.user,
                }
            )
            
            if not created:
                user_access.permission_level = request.POST['permission_level']
                user_access.save()
            
            # Update specific permissions
            user_access.can_view_campaigns = request.POST.get('can_view_campaigns') == 'on'
            user_access.can_create_campaigns = request.POST.get('can_create_campaigns') == 'on'
            user_access.can_edit_campaigns = request.POST.get('can_edit_campaigns') == 'on'
            user_access.can_approve_campaigns = request.POST.get('can_approve_campaigns') == 'on'
            user_access.can_view_reports = request.POST.get('can_view_reports') == 'on'
            user_access.can_manage_creatives = request.POST.get('can_manage_creatives') == 'on'
            user_access.save()
            
            # Log activity
            ActivityLog.objects.create(
                user=request.user,
                action='UPDATE' if not created else 'CREATE',
                content_type='UserAdvertiser',
                object_id=user_access.id,
                description=f'{"Updated" if not created else "Granted"} access for {user.username} to {advertiser.name}'
            )
            
            action = 'updated' if not created else 'granted'
            messages.success(request, f'Access {action} for {user.username}.')
            
        except Exception as e:
            messages.error(request, f'Error managing user access: {str(e)}')
    
    return redirect('advertisers:detail', advertiser_id=advertiser.id)


@login_required
def advertiser_stats_api(request, advertiser_id):
    """API endpoint for advertiser statistics."""
    advertiser = get_object_or_404(Advertiser, id=advertiser_id)
    
    # Get campaigns data
    campaigns = Campaign.objects.filter(brand__in=advertiser.brands.all())
    
    stats = {
        'total_campaigns': campaigns.count(),
        'active_campaigns': campaigns.filter(status='active').count(),
        'total_brands': advertiser.brands.count(),
        'total_contacts': advertiser.contacts.count(),
        'campaign_status_breakdown': {},
    }
    
    # Campaign status breakdown
    for status, label in Campaign.STATUS_CHOICES:
        count = campaigns.filter(status=status).count()
        if count > 0:
            stats['campaign_status_breakdown'][status] = {
                'label': label,
                'count': count
            }
    
    return JsonResponse(stats)