import os
import datetime
import mimetypes
import xlsxwriter
import pandas as pd

from django.shortcuts import render, redirect
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.views import View 
from django.db import connection
from django.utils import timezone
from django.contrib.auth.decorators import login_required

from django.db.models import Count, Sum, F, Q
from django.db.models.functions import Substr


from apps.common.utils import get_client_ip 
from apps.campaigns.utils import NoVastResult, VastResult

from apps.playlists.models import Verifs 
from apps.activities.models import Activity
from apps.channels.models import Channel, ChannelZone, ChannelZoneRelation
from apps.reports.models import Impressions, Analytics, AnalyticsSource
from apps.agencies.models import Brand, Agency, Advertiser
from apps.campaigns.models import Campaigns, CampaignStatus, Adspots, DayTime, Placement, AdspotsStatusChoices





class CampaignsListView(LoginRequiredMixin, View):
    """
    Campaigns List View

    This view is responsible for rendering the campaigns list page of the application.
    It extends the Django View class and defines the HTTP GET method to handle
    the request and return the rendered campaigns list page template.

    Methods:
        get(request): Handles the HTTP GET request and returns the rendered
            campaigns list page template.

    Template:
        - 'index.html': The HTML template used to render the dashboard page.

    """
    http_method_names = ["get"]
    template_name = "campaigns/campaign/list.html"
    extra_context = {
        "title": "Campaigns - Adtlas",
        "author": " Adtlas Development Team", 
        "description": "Campaigns for Adtlas TV advertising solutions. This page provides insights into your TV advertising campaigns.",
        "keywords": "Adtlas, campaigns, TV advertising solutions, campaign insights, data visualization",
        "active_menu": "campaigns",
    }  

    def get_context_data(self, **kwargs):
        """
        Add dashboard page context data.
        """
        context = super().get_context_data(**kwargs)
        context.update({
            "title": _("Campaigns"),
        })
        return context  

    def get(self, request, *args, **kwargs):
        """
        Handles the HTTP GET request and returns the rendered dashboard page template.

        Args:
            request (HttpRequest): The HTTP request object.

        Returns:
            HttpResponse: The rendered dashboard page template.
        """

         # Check for AJAX requests
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return self._handle_ajax_request(request)
        
        # Get filtered queryset
        # queryset = self._get_filtered_queryset(request)
        queryset = Campaigns.objects.filter(
            campaign_manager=request.user
        ).order_by('-created_at')
        
        # Apply pagination
        paginator = Paginator(queryset, self._get_items_per_page(request))
        page_number = request.GET.get('page', 1)
        
        try:
            page_obj = paginator.get_page(page_number)
        except PageNotAnInteger:
            page_obj = paginator.get_page(1)
        except EmptyPage:
            page_obj = paginator.get_page(paginator.num_pages)
        
        # Log user activity for auditing
        self._log_user_activity(request)
        
        # Build context
        context = self._build_context(request, page_obj, paginator)
        
        return render(request, self.template_name, context)

    def _build_context(self, request, page_obj, paginator):
        """
        Build template context with all necessary data.
        
        Args:
            request: Django HTTP request object
            page_obj: Paginated page object
            paginator: Paginator instance
            
        Returns:
            dict: Template context
        """
        user = request.user
        
        context = {
            # Pagination data
            'campaigns': page_obj.object_list,
            'page_obj': page_obj,
            'paginator': paginator,
            'is_paginated': paginator.num_pages > 1,
            
            # Filter data
            'channels': self._get_user_channels(user),
            'zones': self._get_available_zones(user),
            'agencies': self._get_agencies(user),
            'advertisers': self._get_advertisers(user),
            'filter_params': self._get_current_filters(request),
            'sort_options': self._get_sort_options(),
            
            # Statistics
            'stats': self._get_stats(user),
            
            # # Additional data
            'date_range': self._get_date_range(),
            'total_results': paginator.count,
            'current_page': page_obj.number,
            'total_pages': paginator.num_pages,
        }
        
        return context

    def _get_available_zones(self, user):
        """
        Get zones available to the current user.
        
        Args:
            user: Current user object
            
        Returns:
            QuerySet: Available zones
        """
        return ChannelZone.objects.filter(
            is_active=True
        ).distinct().order_by('name', 'code')

    def _get_user_channels(self, user):
        """
        Get channels available to the current user.
        
        Args:
            user: Current user object
            
        Returns:
            QuerySet: User's channels
        """
        # return Channel.objects.filter(user=user).order_by('name')
        return Channel.objects.all().order_by('name')

    def _get_agencies(self, user):
        """
        Get agencies available to the current user.
        
        Args:
            user: Current user object
            
        Returns:
            QuerySet: Available agencies
        """
        return Agency.objects.filter(owner=user).order_by('name')

    def _get_advertisers(self, user):
        """
        Get advertisers available to the current user.
        
        Args:
            user: Current user object
            
        Returns:
            QuerySet: Available advertisers
        """
        return Advertiser.objects.filter(user=user).order_by('brand__name')

    def _get_current_filters(self, request):
        """
        Get current filter parameters for template.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            dict: Current filter values
        """
        return {
            'search': request.GET.get('search', ''),
            'channel': request.GET.get('channel', 'all'),
            'agency': request.GET.get('agency', 'all'),
            'advertiser': request.GET.get('advertiser', 'all'),
            'zone': request.GET.get('zone', 'all'),
            'status': request.GET.get('status', 'all'),
            'date_from': request.GET.get('date_from', ''),
            'date_to': request.GET.get('date_to', ''),
            'date_range': request.GET.get('date_range', ''),
            'sort_by': request.GET.get('sort_by', '-created_at'),
            'per_page': request.GET.get('per_page', '20'),
        }

    def _get_sort_options(self):
        """
        Get available sorting options.
        
        Returns:
            list: Sort options for template
        """
        return [
            {'value': '-created_at', 'label': 'Newest First'},
            {'value': 'created_at', 'label': 'Oldest First'},
            
        ]
        
    def _get_stats(self, user):
        """
            Get campaigns statistics for dashboard.

            Args:
            user: Current user object

            Returns:
            dict: Campaigns statistics
        """

        base_queryset = Campaigns.objects.filter(campaign_manager=user)
        today = timezone.now().date()
        week_ago = today - datetime.timedelta(days=7)

        return {   
            'total_campaigns': base_queryset.count(),
            'active_campaigns': base_queryset.filter(
                status=CampaignStatus.In_progress,
                end_date__gte=today
            ).count(),
            'pending_campaigns': base_queryset.filter(
                status=CampaignStatus.Prebooked,
                end_date__gte=today
            ).count(),
            'expired_campaigns': base_queryset.filter( 
                end_date__lt=today
            ).count(), 
            'todays_campaigns': base_queryset.filter(end_date=today).count(),
            'recent_campaigns': base_queryset.filter(
                end_date__gte=week_ago
            ).count(),
            'upcoming_campaigns': base_queryset.filter(
                status=CampaignStatus.In_progress,
                end_date__gt=today, 
            ).count(),
            'past_campaigns': base_queryset.filter(
                end_date__lt=today
            ).count(),
        } 

    def _get_date_range(self):
        """
        Get date range information for filtering.
        
        Returns:
            dict: Date range options
        """
        today = timezone.now().date()
        
        return {
            'today': today,
            'yesterday': today - datetime.timedelta(days=1),
            'week_start': today - datetime.timedelta(days=today.weekday()),
            'month_start': today.replace(day=1),
            'min_date': today - datetime.timedelta(days=365),  # One year ago
            'max_date': today + datetime.timedelta(days=365),  # One year ahead
        }
    
    def _handle_ajax_request(self, request):
        """
        Handle AJAX requests for dynamic updates.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with data
        """
        action = request.GET.get('action')
        
        if action == 'get_zones':
            return self._get_zones_for_channel_ajax(request)
        elif action == 'get_agencies':
            return self._get_agencies_ajax(request)
        elif action == 'get_advertisers':
            return self._get_advertisers_for_agency_ajax(request)
        elif action == 'quick_stats':
            return self._get_quick_stats_ajax(request)
        # elif action == 'export_data':
        #     return self._export_campaigns_data_ajax(request)
        # elif action == 'load_more':
        #     return self._load_more_campaigns_ajax(request)
        
        # # Default: return filtered campaign data
        # return self._get_filtered_campaigns_ajax(request)

    def _get_zones_for_channel_ajax(self, request):
        """
        Get zones for a specific channel via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with zone data
        """
        channel_id = request.GET.get('channel_id')
        
        if not channel_id:
            return JsonResponse({'success': False, 'error': 'Channel ID required'})
        
        try:
            channel_id = int(channel_id)
            zones = ChannelZone.objects.filter(
                id_channel_id=channel_id
            ).values('id_zone_channel', 'networkname', 'region')
            
            return JsonResponse({
                'success': True,
                'zones': list(zones)
            })
        except (ValueError, TypeError):
            return JsonResponse({'success': False, 'error': 'Invalid channel ID'})

    def _get_agencies_ajax(self, request):
        """
        Get agencies available to the current user via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with agency data
        """
        user = request.user
        agencies = self._get_available_agencies(user)
        
        return JsonResponse({
            'success': True,
            'agencies': list(agencies.values('id_agency', 'name'))
        })

    def _get_available_agencies(self, user):
        """
        Get agencies available to the current user.
        
        Args:
            user: Current user object
            
        Returns:
            QuerySet: QuerySet of available agencies
        """
        return Agency.objects.filter(user=user)

    def _get_advertisers_for_agency_ajax(self, request):
        """
        Get advertisers available to the current user via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with advertiser data
        """
        user = request.user
        agency_id = request.GET.get('agency_id')
        
        if not agency_id:
            return JsonResponse({'success': False, 'error': 'Agency ID required'})

        try:
            agency_id = int(agency_id)
            advertisers = Advertiser.objects.filter(brand__agency__id=agency_id)
            
            return JsonResponse({
                'success': True,
                'advertisers': list(advertisers.values('id', 'name'))
            })
        except (ValueError, TypeError):
            return JsonResponse({'success': False, 'error': 'Invalid agency ID'})

    def _get_quick_stats_ajax(self, request):
        """
        Get quick statistics via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with statistics
        """
        user = request.user
        stats = self._get_stats(user)
        
        return JsonResponse({
            'success': True,
            'stats': stats
        })

    def _export_campaigns_data_ajax(self, request):
        """
        Export playlist data via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with export status
        """
        # Get filtered queryset for export
        queryset = self._get_filtered_queryset(request)
        
        # For now, return success with count
        # In a real implementation, you would generate a file and return the URL
        return JsonResponse({
            'success': True,
            'message': f'Export prepared for {queryset.count()} playlists',
            'download_url': '#',  # Replace with actual download URL
            'count': queryset.count()
        })
    
    def _get_items_per_page(self, request):
        """
        Get number of items per page from request or default.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            int: Items per page
        """
        try:
            per_page = int(request.GET.get('per_page', 20))
            # Limit to reasonable range
            return max(10, min(per_page, 100))
        except (ValueError, TypeError):
            return 20
 
    def _log_user_activity(self, request: HttpRequest) -> None:
        """
        Log user activity for auditing purposes.
        
        Records the user's action with relevant metadata including IP address,
        user agent, and timestamp for security and analytics purposes.
        
        Args:
            request (HttpRequest): The HTTP request object
            
        Returns:
            None
        """
        user = request.user
        
        Activity.log_activity(
            user=user,
            action="views_campaigns",
            description=f"User {user.email if user else 'System'} performed views_campaigns",
            request=request,
            ip_address=get_client_ip(request),
            user_agent=request.META.get("HTTP_USER_AGENT", ""),
            metadata={}
        )

    def dispatch(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        """
        Override dispatch method for additional request processing.
        
        This method is called before any HTTP method handler. Useful for
        adding common logic like additional authentication checks, rate limiting,
        or request preprocessing.
        
        Args:
            request (HttpRequest): The HTTP request object
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            HttpResponse: Result from the appropriate HTTP method handler
        """
        # Add any additional preprocessing here
        # Example: Rate limiting, additional auth checks, etc.
        
        return super().dispatch(request, *args, **kwargs)



@login_required
def add_campaign(request): 
    # Get the user from the request
    user = request.user
    # 
    channels = Channel.objects.all()
    # check request method
    if request.method == 'POST':
        # campaign info:
        name = request.POST.get('campaign_name')             # campaign name
        id_agency = request.POST.get('id_agency')            # campaign agency 
        id_brand = request.POST.get('id_brand')              # campaign Advertiser
        product = request.POST.get('product_name')           # campaign product
        category = request.POST.get('id_category')           # campaign product
        country = request.POST.get('id_country')             # campaign product
        # campaign periode info:  Part date (start_end)      #
        start_date = request.POST.get('start_day')           # campaign start date
        end_date = request.POST.get('end_day')               # campaign end date
        # # campaign cpm info:                               #
        budget = request.POST.get('budget')                  # campaign budget
        volume = request.POST.get('volume')                  # campaign target impression
        cpm = request.POST.get('cpm')                        # campaign cpm
        broadcasts_day = request.POST.get('broadcasts_day')  # campaign min broadcasts pre day
        # campaign media planning info:                      #
        rotation = request.POST.get('general_rotation')      # campaign media planning rotation aliatoire
        media_type = request.POST.get('media_type')          # campaign media planning media type
        program_category = request.POST.getlist('program_categories') # campaign media planning program category
        pacing  = request.POST.get('pacing')                 # campaign media planning pacing 
        datetime = timezone.now()
        delivery = ""
        if pacing == "0":
            delivery = 0
        else:
            #
            start_date1 = datetime.strptime(str(start_date), '%Y-%m-%d')
            end_date1 = datetime.strptime(str(end_date), '%Y-%m-%d') 
            #
            delivery = int(volume)/int(str((end_date1-start_date1).days))

        campaign = Campaigns(
            name=name,
            id_brand = Brand.objects.get(pk=id_brand),
            id_agency = Agency.objects.get(pk=id_agency),
            product = product,
            category = category,
            country = country,
            start_day = start_date,
            end_day = end_date,
            budget = float(budget),
            volume = int(volume),
            delivery = float(delivery),
            cpm = float(cpm),
            broadcasts_day = int(broadcasts_day),
            media_type = media_type,
            program_category = program_category,
            pacing=pacing,
            general_rotation=int(rotation),
            user=user,
            booked="0", 
            status=CampaignStatus.Prebooked
        )
        campaign.save()
 
        if(rotation=='0'):
            for channel in channels:
                channel_placements = request.POST.getlist('check_placement_'+str(channel.id_channel))
                if channel_placements != None:
                    for placement_of_channel in channel_placements:
                        time = DayTime.objects.get(pk=int(placement_of_channel))
                        placement = Placement(id_time=time ,id_campaign=campaign , id_channel=channel)
                        placement.save()
 
            # Log user activity 
            Activity.log_activity(
                user=user,
                action="add_campaign",
                description=f"User {user.email if user else 'System'} performed add_campaign",
                request=request,
                ip_address=get_client_ip(request),
                user_agent=request.META.get("HTTP_USER_AGENT", ""),
                metadata={
                    "id_campaign":campaign.id_campaign
                }
            )     
            return redirect("campaigns:views_campaigns")
        else:
            channels_checked = request.POST.getlist('channels_checked')
            if channels_checked != None:
                for channel in channels_checked:
                    time = DayTime.objects.get(id_time=13)
                    placement = Placement(id_time=time,id_campaign=campaign , id_channel_id=channel)
                    placement.save()  
            return redirect("campaigns:views_campaigns")

    agencies = Agency.objects.filter(owner=user, is_deleted=0)
    adspots = Adspots.objects.filter(channel__in=channels) 
      
    advertisers = Brand.objects.filter(agency__owner=user, agency__is_deleted=0) 
    advertisers_for_creative = Advertiser.objects.filter(user=user).filter(status="1").select_related('id_brand').all()
    
    datetime = DayTime.objects.exclude(id_time = 13) 
    data = {
        'brands'  : advertisers,
        'agency'  : agencies,
        'adspots' : adspots,
        'channels': channels,
        'datetime': datetime,
        'advertisers_for_creative':advertisers_for_creative
    }
    return render(request,'campaigns/campaign/add_new.html', {'data':data})


@login_required
def view_campaign(request, id_campaign=None):
    # Get the user from the request
    user = request.user
    if id_campaign == None or id_campaign == "":
        return redirect("campaigns:views_campaigns")

    campaign = Campaigns.objects.get(pk=id_campaign)
    brands_for_agency = Brand.objects.get(id=campaign.id_brand.id)
    agency_by_brand = Agency.objects.get(id=brands_for_agency.agency.id)

    channels= Channel.objects.filter(user=user)
    adspots = Adspots.objects.filter(channel__in=channels)
    datetime = DayTime.objects.exclude(id_time = 13)
    placement_channel = Placement.objects.filter(id_campaign=campaign.id_campaign).values_list('id_channel')
    placement_channel = [x[0] for x in list(placement_channel)]

    channels_and_placement = {} # or []
    tab_channels_and_placement = []
    ch_n = 0
    for channel in channels:
        # we will get the placement of 1 channel here:
        placement = Placement.objects.filter(id_campaign=campaign.id_campaign, id_channel=channel).values_list('id_time')
        placement = [x[0] for x in list(placement)]
        # here will append the array channels_and_placement with the value of the channel and the placement to use it in the html
        channels_and_placement[ch_n] = {"channel_name":channel.channel_name, "channel_id": channel.id_channel, "placement": placement}
        tab_channels_and_placement.append(channels_and_placement[ch_n])
        ch_n +=1

    placement = Placement.objects.filter(id_campaign=campaign.id_campaign).values_list('id_time')
    placement = [x[0] for x in list(placement)] 

    data = {
        'campaign':campaign,
        'agency_by_brand':agency_by_brand,
        'channels':channels,
        'datetime':datetime,
        'placement_channel':placement_channel,
        'channels_and_placement':tab_channels_and_placement,
        'placement':placement
    }
    return render(request , 'campaigns/campaign/view_id.html',{'data':data})


@login_required
def edit_campaign(request, id_campaign=None): 
    # Get the user from the request
    user = request.user
    # 
    if request.method == 'POST':  
        # campaign data inserted
        name = request.POST.get('campaign_name')             # campaign name
        id_agency = request.POST.get('id_agency')            # campaign agency
        id_brand = request.POST.get('id_brand')              # campaign Advertiser
        product = request.POST.get('product_name')           # campaign product
        category = request.POST.get('id_category')           # campaign product
        country = request.POST.get('id_country')             # campaign product
        # campaign periode info:  Part date (start_end)      #
        start_date = request.POST.get('start_day')           # campaign start date
        end_date = request.POST.get('end_day')               # campaign end date
        # # campaign cpm info:                               #
        budget = request.POST.get('budget')                  # campaign budget
        volume = request.POST.get('volume')                  # campaign target impression
        cpm = request.POST.get('cpm')                        # campaign cpm
        broadcasts_day = request.POST.get('broadcasts_day')  # campaign min broadcasts pre day
        # campaign media planning info:                      #
        rotation = request.POST.get('general_rotation')      # campaign media planning rotation aliatoire
        media_type = request.POST.get('media_type')          # campaign media planning media type
        program_category = request.POST.getlist('program_categories') # campaign media planning program category
        pacing  = request.POST.get('pacing')                 # campaign media planning pacing

        delivery = ""
        if pacing == "1" and start_date != None and end_date != None :
            start_date1 = datetime.strptime(str(start_date), '%Y-%m-%d')
            end_date1 = datetime.strptime(str(end_date), '%Y-%m-%d')  
            delivery = int(volume)/int(str((end_date1-start_date1).days))
        else:
            delivery = 0

        # campaign data in db
        campaign = Campaigns.objects.get(pk=id_campaign)
        
        campaign.delivery = delivery if delivery and delivery != campaign.delivery else campaign.delivery
        campaign.name = name if name != "" and name != None and name != campaign.name else campaign.name
        campaign.id_brand = Brand.objects.get(pk=id_brand) if id_brand != "" and id_brand != None and id_brand != campaign.id_brand.id else campaign.id_brand
        campaign.id_agency = Agency.objects.get(pk=id_agency) if id_agency != "" and id_agency != None and id_agency != campaign.id_agency.id else campaign.id_agency
        campaign.product = product if product != "" and product != None and product != campaign.product else campaign.product
        campaign.category = category if category != "" and category != None and category != campaign.category else campaign.category
        campaign.country = country if country != "" and country != None and country != campaign.country else campaign.country
        campaign.start_day = start_date if start_date != "" and start_date != None and start_date != campaign.start_day else campaign.start_day
        campaign.end_day = end_date if end_date != "" and end_date != None and end_date != campaign.end_day else campaign.end_day
        campaign.budget = float(budget) if budget != "" and budget != None and float(budget) and float(budget) != campaign.budget else campaign.budget
        campaign.volume = int(volume) if volume != "" and volume != None and int(volume) and int(volume) != campaign.volume else campaign.volume
        campaign.delivery = float(delivery) if delivery != "" and delivery != None and float(delivery) and float(delivery) != campaign.delivery else campaign.delivery
        campaign.cpm = float(cpm) if cpm != "" and cpm != None and float(cpm) and float(cpm) != campaign.cpm else campaign.cpm
        campaign.broadcasts_day = int(broadcasts_day) if broadcasts_day != "" and broadcasts_day != None and int(broadcasts_day) and int(broadcasts_day) != campaign.broadcasts_day else campaign.broadcasts_day
        campaign.media_type = media_type if media_type != "" and media_type != None and media_type != campaign.media_type else campaign.media_type
        campaign.program_category = program_category if program_category != "" and program_category != None and program_category != campaign.program_category else campaign.program_categorys
        campaign.pacing = pacing if pacing != "" and pacing != None and pacing != campaign.pacing else campaign.pacing
        campaign.general_rotation = int(rotation) if rotation != "" and rotation != None and int(rotation) and int(rotation) != campaign.general_rotation else campaign.general_rotation
        campaign.save()


        brands_for_agency = Brand.objects.get(id=campaign.id_brand.id)
        agency_by_brand = Agency.objects.get(id=brands_for_agency.agency.id)

        channels= Channel.objects.filter(user=user)
        adspots = Adspots.objects.filter(channel__in=channels)
        datetime1 = DayTime.objects.exclude(id_time = 13)
        placement_channel = Placement.objects.filter(id_campaign=campaign.id_campaign).values_list('id_channel')
        placement_channel = [x[0] for x in list(placement_channel)]

        channels_and_placement = {} # or []
        tab_channels_and_placement = []
        ch_n = 0
        for channel in channels:
            # we will get the placement of 1 channel here:
            placement = Placement.objects.filter(id_campaign=campaign.id_campaign, id_channel=channel).values_list('id_time')
            placement = [x[0] for x in list(placement)]
            # here will append the array channels_and_placement with the value of the channel and the placement to use it in the html
            channels_and_placement[ch_n] = {"channel_name":channel.channel_name, "channel_id": channel.id_channel, "placement": placement}
            tab_channels_and_placement.append(channels_and_placement[ch_n])
            ch_n +=1

        placement = Placement.objects.filter(id_campaign=campaign.id_campaign).values_list('id_time')
        placement = [x[0] for x in list(placement)]


        # Log user activity 
        Activity.log_activity(
            user=user,
            action="edit_campaign",
            description=f"User {user.email if user else 'System'} performed edit_campaign",
            request=request,
            ip_address=get_client_ip(request),
            user_agent=request.META.get("HTTP_USER_AGENT", ""),
            metadata={
                "id_campaign":campaign.id_campaign
            }
        )      

        data = {
            'campaign':campaign,
            'agency_by_brand':agency_by_brand,
            'channels':channels,
            'datetime':datetime1,
            'placement_channel':placement_channel,
            'channels_and_placement':tab_channels_and_placement,
            'placement':placement,
            'agencies': Agency.objects.filter(owner=user,is_deleted=0),
            'advertisers': Brand.objects.filter(agency__owner=user, agency__is_deleted=0)   
        }
        # 
        return render(
            request , 
            "campaigns/campaign/edit_id.html",
            {"data": data}
        )
 

    campaigns = Campaigns.objects.filter(user=user).order_by('-id_campaign')
 
    # no_vast_results = Campaigns.objects.select_related().prefetch_related(
    #         'adspots__verifs'
    #     ).annotate(
    #         # Extract date and time parts for joining conditions
    #         verif_date=Substr('adspots__verifs__airTime', 1, 10),
    #         verif_time=Substr('adspots__verifs__airTime', 12, 5),
            
    #         # Count total ads with airStatusCode = 0001
    #         total_ads=Count(
    #             'adspots__verifs__airStatusCode',
    #             filter=Q(adspots__verifs__airStatusCode='0001')
    #         ),
            
    #         # Calculate total impressions
    #         total_impressions=Sum(
    #             F('adspots__verifs__sfr_analytics__purcent') * 1.25 * 4500000 / 17,
    #             filter=Q(
    #                 adspots__verifs__sfr_analytics__sfr_channel_name='2M Maroc',
    #                 adspots__verifs__airStatusCode='0001'
    #             )
    #         )
    #     ).filter(
    #         # Main filter conditions
    #         adspots__isnull=False,
    #         adspots__verifs__airStatusCode='0001',
            
    #         # Date range filters using extracted date parts
    #         adspots__verifs__airTime__date__gt=F('start_day'),
    #         adspots__verifs__airTime__date__lt=F('end_day'),
            
    #         # Join condition with SFR_analytics
    #         adspots__verifs__sfr_analytics__minute__startswith=F('verif_time'),
    #         adspots__verifs__sfr_analytics__day__startswith=F('verif_date'),
    #         adspots__verifs__sfr_analytics__sfr_channel_name='2M Maroc'
    #     ).values(
    #         'id_campaign',
    #         'total_ads', 
    #         'total_impressions'
    #     ).distinct()

    # vast_results = Campaigns.objects.select_related().prefetch_related(
    #         'adspots__verifs',
    #         'vast_response_set'
    #     ).annotate(
    #         # Count total ads with airStatusCode = 0001
    #         total_ads=Count(
    #             'adspots__verifs__airStatusCode',
    #             filter=Q(
    #                 adspots__isnull=False,
    #                 adspots__verifs__airStatusCode='0001',
    #                 adspots__verifs__airTime__date__gt=F('start_day'),
    #                 adspots__verifs__airTime__date__lt=F('end_day')
    #             )
    #         ),
    #         # Count total impressions from VAST_response
    #         total_impressions=Count(
    #             'vast_response__AD_id',
    #             filter=Q(
    #                 vast_data__isnull=False,
    #                 vast_response__vast_url=F('vast_data'),
    #                 vast_response__datetime_timestamp__date__gt=F('start_day'),
    #                 vast_response__datetime_timestamp__date__lt=F('end_day')
    #             )
    #         )
    #     ).filter(
    #         vast_data__isnull=False
    #     ).values(
    #         'id_campaign',
    #         'total_ads',
    #         'total_impressions'
    #     ).distinct()
 
    now =datetime.datetime.now()

    start = []

    for i in campaigns:
        try :
            date = datetime.strptime(i.start_day , '%Y-%m-%d')
            if now > date:
                start.append(i.id_campaign)
        except :
            pass
    
    return render(
        request ,
        'campaigns/campaign/edit.html',
        {
            'campaigns':campaigns ,
            'start' : start,
            # 'vast_results': vast_results,
            # 'no_vast_results': no_vast_results
        }
    )


@login_required
def update_campaign(request, id_campaign=None):
    if request.method == 'POST':
        campaign = Campaigns.objects.get(pk=id_campaign)
        # Part 1
        name = request.POST.get('campaign_name')
        id_agency = request.POST.get("id_agency")
        id_brand = request.POST.get('id_brand')
        id_adpost = request.POST.get('id_adpost')

        # pacing = request.POST.get('pacing')

        # Part data
        start_date = request.POST.get('start_day')
        end_date = request.POST.get('end_day')

        pacing  = request.POST.get('pacing')
        volume  = request.POST.get('volume')
        delivery  = request.POST.get('delivery')
        cpm     = request.POST.get('cpm') 
        rotation = request.POST.get('general_rotation')

        # Part placement

        #Insert

        brand = Brand.objects.get(pk=id_brand)
        # adpost = Adspots.objects.get(pk=id_adpost)
        adpost = 31
        agency =  Agency.objects.get(pk=id_agency)

        campaign.name=name
        campaign.id_advertiser=adpost
        campaign.id_brand=brand
        campaign.pacing=pacing
        campaign.start_day=start_date
        campaign.end_day=end_date
        campaign.volume=int(volume)
        campaign.general_rotation = rotation

        try :
            campaign.delivery=int(delivery)
        except:
            campaign.delivery=0


        campaign.cpm=float(cpm)
        campaign.save()
        now = datetime.datetime.now()
        activite = 'Edite Campaign'
        desc = 'Admin Edit Campaign  id: ' + str(id_campaign)
        activity = Activity(activity=activite , date=now ,description=desc )
        activity.save()


        channels = Channel.objects.filter(user=request.user)
        if(rotation=='0'):
            p = Placement.objects.filter(id_campaign=campaign)
            p.delete()
            for channel in channels:
                channel_placements = request.POST.getlist('check_placement_'+str(channel.id_channel))
                if channel_placements != None:
                    for placement_of_channel in channel_placements:
                        time = DayTime.objects.get(pk=int(placement_of_channel))
                        placement = Placement(id_time=time ,id_campaign=campaign , id_channel=channel)
                        placement.save()
        else:
            channels_checked = request.POST.getlist('channels_checked')
            print(channels_checked)
            p = Placement.objects.filter(id_campaign=campaign)
            p.delete()
            if channels_checked != None:

                for channel in channels_checked:
                    time = DayTime.objects.get(id_time=13)

                    # p = [x[0] for x in list(p)]

                    # if channel not in p:
                    placement = Placement(id_time=time ,id_campaign=campaign,id_channel_id=channel)
                    placement.save()
                    # else:
                    #         placement = Placement.objects.get(id_time=time,id_campaign=campaign,id_channel_id=channel)
                    #         placement.id_time = time
                    #         placement.id_channel_id = channel
                    #         placement.save()

        # campaign = Campaigns.objects.filter(user_id=request.session['user'])
        return redirect("campaigns:view_campaign", id_campaign=id_campaign)


@login_required
def disable_campaign(request,id_campaign=""):

    if request.method == 'POST' :
        campaign = Campaigns.objects.get(pk=id_campaign)
        campaign.booked = campaign.booked == False
        campaign.save()
        now = datetime.datetime.now()
        activite = 'Disable Campaign'
        desc = 'Admin Disable Campaign  id: ' + str(id_campaign)
        activity = Activity(activity=activite , date=now ,description=desc )
        activity.save()
    campaigns = Campaigns.objects.filter(user=request.user).order_by('-id_campaign')
    return render(request,'core/disable_campaign.html',{'campaigns':campaigns})


@login_required
def load_creatives(request):
    advertiser_id = request.GET.get('advertiser')
    # advertiser_id = '28'
    # adspots = Adspots.objects.filter(id_brand=advertiser_id)
    adspots = Adspots.objects.raw('SELECT * FROM Adspots where id_brand = "'+advertiser_id+'" GROUP BY ad_group')


    return render(request,'core/dropdown_adspots_campaign.html',{'adspots': adspots})


@login_required
def load_adspots(request):
    channel_id = request.GET.get('channel')

    adspots = Adspots.objects.filter(channel=channel_id, status=AdspotsStatusChoices.ACTIVE).select_related("brand").all()

    return render(request, "campaigns/dropdown_adspots.html", {"adspots": adspots})


@login_required
def campaign_report(request, data=""):

    paris_tz = pytz.timezone('Europe/Paris')
    paris_time = datetime.datetime.now(paris_tz)
    utc_offset = paris_time.utcoffset().total_seconds() / 3600

    # if utc_offset == 1:
    if 0==1:

        # *************************************
        # * for when France timezone is GMT+1 *
        # *************************************

        query = """
        SELECT networkname, spotId, airTime, airStatusCode, purcent AS sfr_percentage, purcent*1.25*4500000/17 AS total_volume, Epg.emission_name
        FROM Verifs
        inner JOIN SFR_analytics ON SUBSTRING(Verifs.airTime, 12, 5) = SUBSTRING(SFR_analytics.`minute`, 1, 5)
        AND SUBSTRING(Verifs.airTime, 1, 10) = SUBSTRING(SFR_analytics.`day`, 1, 10)
        AND SFR_analytics.sfr_channel_name = '2M Maroc'
        inner JOIN Epg ON (Verifs.airTime < Epg.End_time AND Verifs.airTime > Epg.Start_time)
        WHERE Verifs.spotId LIKE %s AND Verifs.airStatusCode = '0001' AND Verifs.broadcastDate > %s AND Verifs.broadcastDate < %s
        GROUP BY networkname, spotId, airTime, airStatusCode, purcent, Epg.emission_name ORDER BY airTime
        """

    # if utc_offset == 2:
    if 1==1:

        # *************************************
        # * for when France timezone is GMT+2 *
        # *************************************

        query = """
        SELECT networkname, spotId, airTime, airStatusCode, purcent AS sfr_percentage, purcent*1.25*4500000/17 AS total_volume, Epg.emission_name
        FROM Verifs
        inner JOIN SFR_analytics ON SUBSTRING(Verifs.airTime, 12, 5) = SUBSTRING(SFR_analytics.`minute`, 1, 5)
        AND SUBSTRING(Verifs.airTime, 1, 10) = SUBSTRING(SFR_analytics.`day`, 1, 10)
        AND SFR_analytics.sfr_channel_name = '2M Maroc'
        inner JOIN Epg ON (Verifs.airTime < DATE_ADD(Epg.End_time, INTERVAL 1 HOUR) AND Verifs.airTime > DATE_ADD(Epg.Start_time, INTERVAL 1 HOUR))
        WHERE Verifs.spotId LIKE %s AND Verifs.airStatusCode = '0001' AND Verifs.broadcastDate > %s AND Verifs.broadcastDate < %s
        GROUP BY networkname, spotId, airTime, airStatusCode, purcent, Epg.emission_name ORDER BY airTime
        """

    def dictfetchall(cursor):
        "Return all rows from a cursor as a dict"
        columns = [col[0] for col in cursor.description]
        return [
            dict(zip(columns, row))
            for row in cursor.fetchall()
        ]

    if data != "":
        campaign = Campaigns.objects.get(pk=data)

        # Your logic to process the request and prepare data
        # data = {
        #     'start_date': campaign.start_day,
        #     'end_date': campaign.end_day,
        #     'id_brand': campaign.id_brand.id_brand
        # }

        from django.db import connection

        cursor = connection.cursor()

        data_tuple=(
            f"%{campaign.id_brand.brand_name}%",
            (campaign.start_day).replace("-", ""),
            (campaign.end_day).replace("-", "")
        )

        cursor.execute(query,data_tuple)
        # data = cursor.fetchall()
        total = 0

        data = dictfetchall(cursor)

        for row in data:
            if row['total_volume'] == None:
                print(row)
            else:
                total += int(row['total_volume'])

        # Return a JsonResponse with the data
        return render(
            request,
            "core/report_campaign.html",
            {
                'data': data,
                'total':total
            }
        )
    else:
        return redirect("campaigns:edit_campaign")


@login_required
def channels_campaigns(request):
    from datetime import datetime
    now = datetime.now()
    channel = request.GET.get('channel')
    campaigns = Placement.objects.filter(id_channel=channel).values_list('id_campaign')
    channel = Channel.objects.get(id_channel=request.GET.get('channel'))
    campaigns = [i[0] for i in campaigns ]
    campaigns = Campaigns.objects.filter(id_campaign__in = campaigns , end_day__lt=now)
    data = {"campaigns":campaigns}
    return render(request,'core/dropdown_compaigns.html',{"campaigns":campaigns})


@login_required
def statscampaign(request):
    campaign = Campaigns.objects.filter(user=request.user ).values_list('name','volume').order_by('-volume')
    pacing = campaign_pacing(request)
    brands = campign_brand(request)
    active = campaign_avtive(request)
    cpms = Campaigns.objects.filter(user=request.user).order_by('-cpm')[:4]
    return render(request ,'core/stats_campaign.html',{'pacing' : pacing , 'active':active  , 'brands':brands , 'cpms' : cpms })
 




@login_required
def views_creative(request):
    user = request.user
    adspots = Adspots.objects.all()
    
    # Log user activity 
    Activity.log_activity(
        user=user,
        action="views_creative",
        description=f"User {user.email if user else 'System'} performed views_creative",
        request=request,
        ip_address=get_client_ip(request),
        user_agent=request.META.get("HTTP_USER_AGENT", ""),
        metadata={ }
    )     
    return render(request , 'campaigns/creative/views.html',{'adspots':adspots})
 
 
@login_required
def add_creative(request):
    """
    View to handle adding new ad spots/creatives.
    Updated to work with the new Adspots model structure.
    """
    user = request.user
    
    if request.method == 'POST':
        try:
            # Get form data
            campaign_id = request.POST.get('campaign_id')
            name = request.POST.get('name', '')  # Updated field name 
            vast_url = request.POST.get('vast_url', '')  # Updated field name
            
            # Validate required fields
            if not campaign_id:
                messages.error(request, 'Campaign is required.')
                return redirect('campaigns:add_creative')
            
            # Get campaign object
            try:
                campaign = Campaigns.objects.get(pk=campaign_id)
            except Campaigns.DoesNotExist:
                messages.error(request, 'Selected campaign does not exist.')
                return redirect('campaigns:add_creative')
                       
            # Handle file upload
            original_file = None
            if 'adspot_file' in request.FILES:
                uploaded_file = request.FILES['adspot_file'] 
                # Save file using Django's file handling
                original_file = uploaded_file 
                        
            # Create the Adspots instance
            adspot = Adspots(
                name=name,
                campaign=campaign,
                brand=campaign.brand if hasattr(campaign, 'brand') else None,  # Assuming campaign has brand
                channel=None,  # Set based on your business logic
                original_file=original_file, 
                status=AdspotsStatusChoices.DRAFT,
                url_from_vast=vast_url if vast_url else None,
                is_active=True
            ) 
            # Set MIME type if file was uploaded
            if original_file:
                mime_type, _ = mimetypes.guess_type(original_file.name)
                adspot.mime_type = mime_type
            
            adspot.save() 
            # Log activity (assuming you have an Activity model)
            try: 
                # Log user activity 
                Activity.log_activity(
                    user=user,
                    action="add_creative",
                    description=f"User {user.email if user else 'System'} performed add_creative",
                    request=request,
                    ip_address=get_client_ip(request),
                    user_agent=request.META.get("HTTP_USER_AGENT", ""),
                    metadata={ 
                        "adspot": adspot.id
                    }
                )   
            except:
                # Handle case where Activity model might not exist or have different structure
                pass
            # 
            messages.success(request, f'Creative "{adspot.name or f"Ad Spot {adspot.id}"}" has been created successfully.')
            return redirect("campaigns:views_creative")  
        except Exception as e:
            messages.error(request, f'Error creating creative: {str(e)}')
            return redirect('campaigns:add_creative')
    else:
        # GET request - show the form
        campaigns = Campaigns.objects.filter( user=user ).select_related('id_brand')  # Optimize query
        
        context = {
            'data': {
                'campaigns': campaigns
            }
        }
        return render(request, "campaigns/creative/add.html", context)


@login_required
def edit_creative(request, id_adpost=None):
    # 
    user = request.user
    # 
    if request.method =='POST':
        adpost = Adspots.objects.get(pk=id_adpost)

        # channels=Channel.objects.filter(user=request.session['user']).order_by('-id_channel')
        # advertisers = Advertiser.objects.filter(user=request.session['user']).filter(status="1").select_related('id_brand').all().order_by('-user_advertiser')
        campaigns = Campaigns.objects.filter(user=user)
        return render(
            request,
            "campaigns/creative/edit_id.html",
            {
                'adspost' : adpost,
                'campaigns': campaigns
            }
        )
    else :

        # channels = Channels.objects.filter(user=id_session).order_by('-id_channel').values_list('id_channel',flat=True)
        # brands = Advertisers.objects.filter(user=id_session).order_by('-user_advertiser').values_list('id_brand',flat=True)
        # adspots = Adspots.objects.filter(id_channel__in=channels).filter(id_brand__in=brands).order_by('-id_adpost')
        # =======================================================
        campaigns = Campaigns.objects.filter(user=request.session['user']).values_list('id_campaign', flat=True)
        adspots = Adspots.objects.filter(campaign__in=campaigns).order_by('-id_adpost')
        # =======================================================
        return render(
            request ,
            "campaigns/creative/edit.html",
            {'adspots': adspots}
        )


@login_required
def update_creative(request, id_adpost=None):
    if request.method == "POST":
        creative = Adspots.objects.get(pk=id_adpost)

        campaign_id = request.POST.get('campaign_id')              # campaign id
        adspot_name = request.POST.get('adspot_name')              # creative name
        adspot_duration = request.POST.get('adspot_duration')      # creative duration
        active_0_1 = request.POST.get('active_0_1')                # creative status
        vast_info = request.POST.get('creative_id')                # creative vast_id

        channel_id = request.POST.get('channel_id')
        advertiser_id = request.POST.get('advertiser_id')
        adspot_name = request.POST.get('adspot_name')
        adspot_duration = request.POST.get('adspot_duration')
        active_0_1 = request.POST.get('active_0_1')

        #
        campaign = Campaigns.objects.get(pk=campaign_id)
        #
        now = datetime.datetime.now()
        now_infile = str(now).replace(" ", "_").replace(":", "-")
        #
        path = "adspots/user_"+str(request.session['user'])+"/campaign_"+str(channel_id)
        filename = "campaign_"+str(channel_id)+"__"+slugify(adspot_name)+"__"+str(adspot_duration)+"sec__"+now_infile+".ts"
        filename_m3u8 = "campaign_"+str(channel_id)+"__"+adspot_name+"__"+str(adspot_duration)+"sec__"+now_infile+".m3u8"
        #
        os.makedirs("static/" + path, exist_ok=True)
        #
        if 'adspot_file' in request.FILES:
            try :
                #
                handle_uploaded_file(request.FILES['adspot_file'], "static/"+path, filename)
                #
                f = open("static/"+path+"/"+filename_m3u8, "a")
                f.write("#EXTM3U \n")
                f.write("#EXT-X-VERSION:3 \n")
                f.write("#EXT-X-MEDIA-SEQUENCE:0 \n")
                f.write("#EXTINF:"+adspot_duration+", \n")
                f.write(filename)
                f.close()
            except :
                import shutil
                if os.path.exists("static/"+ creative.original_filepath):
                    shutil.move("static/"+ creative.original_filepath, "static/"+path+"/"+filename)
        else:
            # Handle the case when 'adspot_file' is not present in the request
            filename = ""  # or set it to some default value or raise an error

        creative.original_filepath = path+"/"+filename

        #! Need to be re-coded
        # channel_name = Channels.objects.get(pk=channel_id)
        # DST_FOLDER = channel_name.channel_name +'/'+'spots'
        # SRC_FILEPATH = "static/"+path+'/'+ filename
        # send_adspot(DST_FOLDER,SRC_FILEPATH)


@login_required
def update(request , id_adpost  ):
    if request.method == "POST":
        creative = Adspots.objects.get(pk=id_adpost)

        campaign_id = request.POST.get('campaign_id')              # campaign id
        adspot_name = request.POST.get('adspot_name')              # creative name
        adspot_duration = request.POST.get('adspot_duration')      # creative duration
        active_0_1 = request.POST.get('active_0_1')                # creative status
        vast_info = request.POST.get('creative_id')                # creative vast_id

        # channel_id = request.POST.get('channel_id')
        # advertiser_id = request.POST.get('advertiser_id')
        # adspot_name = request.POST.get('adspot_name')
        # adspot_duration = request.POST.get('adspot_duration')
        # active_0_1 = request.POST.get('active_0_1')

        #
        campaign = Campaigns.objects.get(pk=campaign_id)
        #
        now = datetime.datetime.now()
        now_infile = str(now).replace(" ", "_").replace(":", "-")
        #
        path = "adspots/user_"+str(request.session['user'])+"/campaign_"+str(campaign_id)
        filename = "campaign_"+str(campaign_id)+"__"+slugify(adspot_name)+"__"+str(adspot_duration)+"sec__"+now_infile+".ts"
        filename_m3u8 = "campaign_"+str(campaign_id)+"__"+adspot_name+"__"+str(adspot_duration)+"sec__"+now_infile+".m3u8"
        #
        os.makedirs("static/" + path, exist_ok=True)
        #
        if 'adspot_file' in request.FILES:
            try :
                #
                handle_uploaded_file(request.FILES['adspot_file'], "static/"+path, filename)
                #
                f = open("static/"+path+"/"+filename_m3u8, "a")
                f.write("#EXTM3U \n")
                f.write("#EXT-X-VERSION:3 \n")
                f.write("#EXT-X-MEDIA-SEQUENCE:0 \n")
                f.write("#EXTINF:"+adspot_duration+", \n")
                f.write(filename)
                f.close()
            except :
                import shutil
                if os.path.exists("static/"+ creative.original_filepath):
                    shutil.move("static/"+ creative.original_filepath, "static/"+path+"/"+filename)
        else:
            # Handle the case when 'adspot_file' is not present in the request
            filename = creative.filename  # or set it to some default value or raise an error

        creative.original_filepath = path+"/"+filename

        #! Need to be re-coded
        # channel_name = Channels.objects.get(pk=channel_id)
        # DST_FOLDER = channel_name.channel_name +'/'+'spots'
        # SRC_FILEPATH = "static/"+path+'/'+ filename
        # send_adspot(DST_FOLDER,SRC_FILEPATH)

        if creative.id_campaign.id_campaign != campaign_id:
            creative.id_campaign = campaign
        if creative.adspot_name != adspot_name:
            creative.adspot_name = adspot_name
        if creative.duration != adspot_duration:
            creative.duration = adspot_duration
        if creative.status != active_0_1:
            creative.status = active_0_1
        if creative.creative_id != vast_info:
            creative.creative_id = vast_info
        creative.datetime=now

        activite = 'Edit Creative'
        desc = 'Admin Edit creative  id: ' + str(creative.id_brand)
        activity = Activity(activity=activite , date=now ,description=desc )
        activity.save()

        creative.save()
        return redirect("campaigns:edit_creative")




@login_required
def genExcel(request, id_campaign):
    info = Campaigns.objects.get(pk=id_campaign)
    now = datetime.datetime.now()

    path = f"excel/user_{str(request.user.id)}"
    
    if not os.path.exists(path):
        os.makedirs(path)
    path+= '/'+info.name+now.strftime('%d_%m_%Y')+'.xlsx'

    response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = "attachment; filename="+info.name+now.strftime('%d_%m_%Y')+'.xlsx'
    workbook = xlsxwriter.Workbook(response, {'in_memory': True})
    worksheet = workbook.add_worksheet()

    cell_format = workbook.add_format()

    cell_format.set_pattern(1)  # This is optional when using a solid fill.
    cell_format.set_bg_color('#acbbfe')

    info = Campaigns.objects.get(pk=id_campaign)

    worksheet.write(1, 1,'Adtlas Reporting | ' +info.name+ ' cash [ ' +info.start_day + ' to ' + info.end_day + ' ] ' )

    ###################################################
    #############           INFO           ############
    ###################################################

    worksheet.write(7, 1, 'INFO' , cell_format)

    worksheet.write(8, 1, 'Campaign Name')
    worksheet.write(8, 2, info.name)

    worksheet.write(9, 1, 'Agency')
    worksheet.write(9, 2, info.id_brand.agency.name)

    worksheet.write(10, 1, 'Advertiser')
    worksheet.write(10, 2, info.id_brand.name)

    worksheet.write(11, 1, 'Creative')
    worksheet.write(11, 2, info.id_adpost.adspot_name if info.id_adpost else "")

    #####################################################
    #############           PERIOD           ############
    #####################################################
    worksheet.write(13, 1, 'PERIOD' ,cell_format)

    worksheet.write(14, 1, 'Start date')
    worksheet.write(14, 2, info.start_day)

    worksheet.write(15, 1, 'End date')
    worksheet.write(15, 2, info.end_day)

    #####################################################
    #############           BOOKED           ############
    #####################################################

    worksheet.write(17, 1, 'BOOKED' ,cell_format)

    worksheet.write(18, 1, 'Volume')
    worksheet.write(18, 2, info.volume)

    worksheet.write(19, 1, 'Pacing')
    worksheet.write(19, 2, info.pacing == True)

    worksheet.write(20, 1, 'CPM')
    worksheet.write(20, 2, info.cpm)

    ########################################################
    #############           PLACEMENT           ############
    ########################################################

    worksheet.write(22, 1, 'PLACEMENT',cell_format)

    worksheet.write(23, 1, 'General Retation')
    worksheet.write(23, 2, info.general_rotation == 1)

    placement_channel = Placement.objects.filter(id_campaign=id_campaign).values_list('id_channel')
    placement_channel = [x[0] for x in list(placement_channel)]
    channels = Channel.objects.filter(id_channel__in =placement_channel ).values_list('channel_name', 'sfr_channel_name')
    channels_name = [i[0] for i in channels]
    channels_sfr = [i[1] for i in channels]
    worksheet.write(24, 1, 'Channels')
    worksheet.write(24, 2, str(channels_name).replace('\'' , ''))

    ########################################################
    #############           Tables              ############
    ########################################################
    worksheet.write(7, 6, 'CHANNEL' ,cell_format)
    worksheet.write(7, 7, 'REGION',cell_format)
    worksheet.write(7, 8, 'DAY',cell_format)
    worksheet.write(7, 9, 'MINUTE',cell_format)
    worksheet.write(7, 10, 'IMPRESSIONS',cell_format)
    


    if info.id_adpost:
        name = info.id_adpost.adspot_name
        verifs = Verifs.objects.filter(spotId=name ,airStatuscode='0001').values_list('networkname','zonename','airTime')
        df= pd.DataFrame(verifs,columns=['Channel','Region','Time'])   
        region = [ ChannelZone.objects.get(zonename=i).region for i in df['Region']]
        channels = [Channel.objects.get(channel_name=i[0]).sfr_channel_name for i in df[['Channel','Region']].values ] 
        df['Channel'] = channels
        df['Region'] = region


        day = [i.split(' ')[0] for i in df['Time']]
        minute = [i.split(' ')[1] for i in df['Time']]

        df['Day']=day
        df['Minute']=minute
        df.drop('Time' , axis='columns',inplace=True)
        df['Minute'] = [i[:-2]+'00' for i in df['Minute']]

        purcent=[]

        for i in df.values:
            purcent.append(SfrAnalytics.objects.get(sfr_channel_name=i[0],region=i[1],day=i[2],minute=i[3]).purcent) 
        purcent = [float(i) for i in purcent] 
        df['Purcent'] = purcent

        imp = Impressions.objects.get(pk='1')

        purcent = [float(i) * float(imp.total_users) / float(imp.market_share_purcent) for i in df['Purcent']]

        df['Purcent'] = purcent

        j=0
        for i in df.values:
            worksheet.write(8+j, 6, i[0])
            worksheet.write(8+j, 7, i[1])
            worksheet.write(8+j, 8, i[2])
            worksheet.write(8+j, 9, i[3])
            worksheet.write(8+j, 10, i[4])
            j+=1

        worksheet.write(7, 13, 'TOTAL IMPRESSIONS',cell_format)
        worksheet.write(8, 13, int(sum(purcent)))

    workbook.close()
    return response


@login_required
def statscreative(request ):
    print('jjjjjjjjjjjjjjjjjjjjjjjjjj')
    from django.db.models import Count
    channel = Channel.objects.filter(user=request.session['user']).values_list('channel_name')
    channel = [ch[0] for ch in channel]
    adspot = Verifs.objects.filter(networkname__in = channel ,    airStatuscode='0001' ).values('spotId').annotate(dcount=Count("spotId")).order_by('-dcount')
    import random
    chars = '0123456789ABCDEF'
    color = ['#'+''.join(random.sample(chars,6)) for i in range(len(adspot))]
    label =[]
    data = []

    for ad in adspot :
        label.append(ad['spotId'])
        data.append(ad['dcount'])
    print(label)
    print(data)
    verifs = {  'lebel' : label ,
                'data'  : data ,
                'color' : color
            }
    brands = ads_brand(request.session['user'] )
    return render(request,'campaigns/creative/stats.html',{'verifs':verifs  , 'brands':brands})


@login_required
def load_creative(request):
    channels= Channel.objects.filter(user=request.session['user'])
    adspots = Adspots.objects.filter(id_channel__in=channels)
    return render(request,'core/dropdown_creative_campaign.html',{'adspots': adspots})


@login_required
def send_creative(request):
    channel_id = request.POST.get('channel_id')
    advertiser_id = request.POST.get('advertiser_id')
    adspot_name = request.POST.get('adspot_name')
    adspot_duration = request.POST.get('adspot_duration')
    active_0_1 = request.POST.get('active_0_1')
    now = datetime.datetime.now()
    now_infile = str(now).replace(" ", "_")
    now_infile = now_infile.replace(":", "-")
    path = "adspots/user_"+str(request.session['user'])+"/ch_"+str(channel_id)
    if not os.path.exists("static/"+path):
        os.makedirs("static/"+path)

    new_now_infile = now_infile.replace(".","-")
    filename = "ch_"+str(channel_id)+"__"+adspot_name+"__"+str(adspot_duration)+"sec__"+new_now_infile+".ts"
    print(filename)
    handle_uploaded_file(request.FILES['adspot_file'], "static/"+path, filename)
    creative = Adspots(id_channel_id=channel_id ,id_brand_id=advertiser_id, adspot_name=adspot_name, duration=adspot_duration, status=active_0_1, original_filepath=path+'/'+filename ,  datetime=now,filename=filename)
    creative.save()
    return render(request,'core/dropdown_agency_campaign.html')


@login_required
def add_campaign_old(request):
    # Get the user from the request
    user = request.user
    # check request method
    if request.method == 'POST':
        # Part 1
        name = request.POST.get('campaign_name')
        id_brand = request.POST.get('id_brand')
        id_adpost = request.POST.get('id_adpost')
        pacing = request.POST.get('pacing')

        # Part data
        start_date = request.POST.get('start_day')
        end_date = request.POST.get('end_day')

        # part cpm
        pacing  = request.POST.get('pacing')
        volume  = request.POST.get('volume')

        delivery  = request.POST.get('delivery')
        if delivery == None:
            delivery = 0
        cpm     = request.POST.get('cpm')

        # Part placement
        placement = []
        time = DayTime.objects.all()
        for i in time:
            placement.append(request.POST.get(i.name))


        #Insert
        brand = Brand.objects.get(pk=id_brand)
        adpost = Adspots.objects.get(pk=id_adpost)

        campaign = Campaigns(
            name=name,
            id_advertiser=adpost,
            id_brand=brand,
            pacing=pacing,
            start_day=start_date,
            end_day=end_date,
            volume=int(volume), 
            delivery=int(delivery), 
            cpm=float(cpm)
        )
        campaign.save()

        now = datetime.datetime.now()
        activite = 'Add Campaign'
        desc = 'Admin Add Campaign  id: ' + str(campaign.id_campaign)
        activity = Activity(activity=activite , date=now ,description=desc )
        activity.save()

        print(campaign.id_campaign)
        
        campaign = Campaigns.objects.get(pk=str(campaign.id_campaign))
        for i in placement :
            if i != None:
                time = DayTime.objects.get(pk=i) 
                p = Placement(id_time=time ,id_campaign=campaign)
                p.save()
        campaign = Campaigns.objects.all()
        return render(request, "campaigns/campaign/viwes_.html", {"campaigns": campaign})

    #brands = Brand.objects.all()
    brands = Advertiser.objects.filter(user=request.session['user']).filter(status="1")
    channels= Channel.objects.filter(user=request.session['user'])
    adspots = Adspots.objects.filter(id_channel__in=channels)
    print(len(adspots))
    datetime = DayTime.objects.all()
    data = {
        'brands'  : brands,
        'adspots' : adspots,
        'datetime': datetime
    }
    return render(request,'core/add_campaign.html', {'data':data})
