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, Count, Avg, Sum
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 timedelta, datetime
import json
import logging

from apps.channels.models import Channel, ChannelZone, ChannelCodec, EPGProgram, Jingle, ChannelSchedule
from apps.core.models import ActivityLog

logger = logging.getLogger(__name__)



# =============================================================
# Tv Channels Management Views
# =============================================================

class ChannelListView(LoginRequiredMixin, ListView):
    """
    List all channels
    """
    model = Channel
    template_name = "channels/channel_list.html"
    context_object_name = "channels"
    paginate_by = 20
    
    def get_queryset(self):
        queryset = Channel.objects.select_related("zone", "codec").all()
        
        # Filtering
        search = self.request.GET.get("search")
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) |
                Q(display_name__icontains=search) |
                Q(description__icontains=search)
            )
        
        return queryset.order_by("zone__name", "channel_number")
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["search"] = self.request.GET.get("search", "")
        return context

class ChannelCreateView(LoginRequiredMixin, CreateView):
    model = Channel
    template_name = "channels/channel_create.html"
    fields = ["name", "display_name", "description", "channel_type", "channel_number", "zone", "codec"]
    success_url = reverse_lazy("channels:list")
    
    def form_valid(self, form):
        response = super().form_valid(form)
        messages.success(self.request, "Channel created successfully.")
        return response
    
    def get_success_url(self):
        return reverse("channels:detail", kwargs={"pk": self.object.pk})
    
 

# Dashboard View
@login_required
def dashboard(request):
    """
    Channels management dashboard with statistics
    """
    # Get dashboard statistics
    total_channels = Channel.objects.count()
    active_channels = Channel.objects.filter(status="active").count()
    online_channels = Channel.objects.filter(is_online=True).count()
    total_zones = ChannelZone.objects.count()
    
    # Recent channels
    recent_channels = Channel.objects.select_related(
        "zone", "codec"
    ).order_by("-created_at")[:5]
    
    # Channel statistics
    channel_stats = Channel.objects.aggregate(
        avg_programs=Avg("programs__id"),
        total_jingles=Count("jingles")
    )
    
    # Recent activity
    recent_activity = ActivityLog.objects.filter(
        content_type__model__in=["channel", "epgprogram", "jingle"]
    ).select_related("user").order_by("-created_at")[:10]
    
    context = {
        "total_channels": total_channels,
        "active_channels": active_channels,
        "online_channels": online_channels,
        "total_zones": total_zones,
        "recent_channels": recent_channels,
        "channel_stats": channel_stats,
        "recent_activity": recent_activity,
    }
    
    return render(request, "channels/dashboard.html", context)


@login_required
def channel_list(request):
    """List all channels with filtering and pagination."""
    channels = Channel.objects.select_related("zone", "codec").all()
    
    # Filtering
    search = request.GET.get("search")
    if search:
        channels = channels.filter(
            Q(name__icontains=search) |
            Q(display_name__icontains=search) |
            Q(description__icontains=search)
        )
    
    channel_type = request.GET.get("type")
    if channel_type:
        channels = channels.filter(channel_type=channel_type)
    
    status = request.GET.get("status")
    if status:
        channels = channels.filter(status=status)
    
    zone_id = request.GET.get("zone")
    if zone_id:
        channels = channels.filter(zone_id=zone_id)
    
    # Annotate with program counts
    channels = channels.annotate(
        program_count=Count("programs"),
        jingle_count=Count("jingles")
    )
    
    # Pagination
    paginator = Paginator(channels, 20)
    page_number = request.GET.get("page")
    page_obj = paginator.get_page(page_number)
    
    # Get filter options
    zones = ChannelZone.objects.filter(is_active=True).order_by("name")
    
    context = {
        "page_obj": page_obj,
        "zones": zones,
        "channel_types": Channel.CHANNEL_TYPES,
        "status_choices": Channel.STATUS_CHOICES,
        "current_search": search,
        "current_type": channel_type,
        "current_status": status,
        "current_zone": zone_id,
    }
    
    return render(request, "channels/channel_list.html", context)


# Channel Zone Views
class ChannelZoneListView(LoginRequiredMixin, ListView):
    """
    List all channel zones
    """
    model = ChannelZone
    template_name = "channels/zone_list.html"
    context_object_name = "zones"
    paginate_by = 20
    
    def get_queryset(self):
        queryset = ChannelZone.objects.annotate(
            channel_count=Count("channels")
        )
        search = self.request.GET.get("search")
        
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) |
                Q(description__icontains=search)
            )
        
        return queryset.order_by("name")
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["search"] = self.request.GET.get("search", "")
        return context


class ChannelZoneDetailView(LoginRequiredMixin, DetailView):
    """
    Channel zone detail view with related channels
    """
    model = ChannelZone
    template_name = "channels/zone_detail.html"
    context_object_name = "zone"
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        zone = self.get_object()
        
        # Get related channels
        channels = Channel.objects.filter(
            zone=zone
        ).order_by("channel_number", "name")
        
        context["channels"] = channels
        context["channel_count"] = channels.count()
        context["active_channels"] = channels.filter(status="active").count()
        
        return context


class ChannelZoneCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """
    Create new channel zone
    """
    model = ChannelZone
    fields = ["name", "description", "timezone", "country_code", "is_active"]
    template_name = "channels/zone_form.html"
    permission_required = "channels.add_channelzone"
    success_url = reverse_lazy("channels:zone_list")
    
    def form_valid(self, form):
        messages.success(self.request, "Channel zone created successfully!")
        return super().form_valid(form)


class ChannelZoneUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """
    Update existing channel zone
    """
    model = ChannelZone
    fields = ["name", "description", "timezone", "country_code", "is_active"]
    template_name = "channels/zone_form.html"
    permission_required = "channels.change_channelzone"
    
    def get_success_url(self):
        return reverse("channels:zone_detail", kwargs={"pk": self.object.pk})
    
    def form_valid(self, form):
        messages.success(self.request, "Channel zone updated successfully!")
        return super().form_valid(form)


class ChannelZoneDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """
    Delete channel zone
    """
    model = ChannelZone
    template_name = "channels/zone_confirm_delete.html"
    permission_required = "channels.delete_channelzone"
    success_url = reverse_lazy("channels:zone_list")
    
    def delete(self, request, *args, **kwargs):
        messages.success(request, "Channel zone deleted successfully!")
        return super().delete(request, *args, **kwargs)


# Channel Codec Views
class ChannelCodecListView(LoginRequiredMixin, ListView):
    """
    List all channel codecs
    """
    model = ChannelCodec
    template_name = "channels/codec_list.html"
    context_object_name = "codecs"
    paginate_by = 20
    
    def get_queryset(self):
        queryset = ChannelCodec.objects.annotate(
            channel_count=Count("channels")
        )
        search = self.request.GET.get("search")
        
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) |
                Q(description__icontains=search)
            )
        
        return queryset.order_by("name")
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["search"] = self.request.GET.get("search", "")
        return context


class ChannelCodecDetailView(LoginRequiredMixin, DetailView):
    """
    Channel codec detail view with related channels
    """
    model = ChannelCodec
    template_name = "channels/codec_detail.html"
    context_object_name = "codec"
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        codec = self.get_object()
        
        # Get related channels
        channels = Channel.objects.filter(
            codec=codec
        ).order_by("name")
        
        context["channels"] = channels
        context["channel_count"] = channels.count()
        
        return context


class ChannelCodecCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """
    Create new channel codec
    """
    model = ChannelCodec
    fields = ["name", "description", "codec_type", "parameters"]
    template_name = "channels/codec_form.html"
    permission_required = "channels.add_channelcodec"
    success_url = reverse_lazy("channels:codec_list")
    
    def form_valid(self, form):
        messages.success(self.request, "Channel codec created successfully!")
        return super().form_valid(form)


class ChannelCodecUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """
    Update existing channel codec
    """
    model = ChannelCodec
    fields = ["name", "description", "codec_type", "parameters"]
    template_name = "channels/codec_form.html"
    permission_required = "channels.change_channelcodec"
    
    def get_success_url(self):
        return reverse("channels:codec_detail", kwargs={"pk": self.object.pk})
    
    def form_valid(self, form):
        messages.success(self.request, "Channel codec updated successfully!")
        return super().form_valid(form)


class ChannelCodecDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """
    Delete channel codec
    """
    model = ChannelCodec
    template_name = "channels/codec_confirm_delete.html"
    permission_required = "channels.delete_channelcodec"
    success_url = reverse_lazy("channels:codec_list")
    
    def delete(self, request, *args, **kwargs):
        messages.success(request, "Channel codec deleted successfully!")
        return super().delete(request, *args, **kwargs)





@login_required
def channel_detail(request, channel_id):
    """Channel detail view with EPG and performance metrics."""
    channel = get_object_or_404(
        Channel.objects.select_related("zone", "codec"),
        id=channel_id
    )
    
    # Get current and upcoming programs
    now = timezone.now()
    current_program = channel.programs.filter(
        start_time__lte=now,
        end_time__gte=now
    ).first()
    
    upcoming_programs = channel.programs.filter(
        start_time__gt=now
    ).order_by("start_time")[:5]
    
    # Get recent programs
    recent_programs = channel.programs.filter(
        end_time__lt=now
    ).order_by("-end_time")[:5]
    
    # Get jingles
    jingles = channel.jingles.filter(is_active=True).order_by("-priority", "name")
    
    # Get schedules
    schedules = channel.schedules.filter(
        start_time__gte=now - timedelta(hours=2),
        start_time__lte=now + timedelta(hours=24)
    ).order_by("start_time")
    
    # Recent activity
    recent_activity = ActivityLog.objects.filter(
        content_type__model="channel",
        object_id=channel.id
    ).select_related("user").order_by("-created_at")[:10]
    
    context = {
        "channel": channel,
        "current_program": current_program,
        "upcoming_programs": upcoming_programs,
        "recent_programs": recent_programs,
        "jingles": jingles,
        "schedules": schedules,
        "recent_activity": recent_activity,
    }
    
    return render(request, "channels/channel_detail.html", context)


@login_required
def channel_create(request):
    """Create a new channel."""
    if not request.user.profile.can_manage_campaigns():
        messages.error(request, "You do not have permission to create channels.")
        return redirect("channels:list")
    
    if request.method == "POST":
        try:
            with transaction.atomic():
                channel = Channel.objects.create(
                    name=request.POST["name"],
                    display_name=request.POST.get("display_name", ""),
                    channel_number=request.POST.get("channel_number") or None,
                    channel_type=request.POST.get("channel_type", "tv"),
                    status=request.POST.get("status", "active"),
                    stream_url=request.POST.get("stream_url", ""),
                    backup_stream_url=request.POST.get("backup_stream_url", ""),
                    codec_id=request.POST.get("codec") or None,
                    zone_id=request.POST.get("zone") or None,
                    description=request.POST.get("description", ""),
                    website=request.POST.get("website", ""),
                    language=request.POST.get("language", ""),
                    category=request.POST.get("category", ""),
                    target_audience=request.POST.get("target_audience", ""),
                    supports_dai=request.POST.get("supports_dai") == "on",
                    max_ad_duration=int(request.POST.get("max_ad_duration", 180)),
                    min_ad_gap=int(request.POST.get("min_ad_gap", 300)),
                )
                
                # Handle logo upload
                if "logo" in request.FILES:
                    channel.logo = request.FILES["logo"]
                    channel.save()
                
                # Log activity
                ActivityLog.objects.create(
                    user=request.user,
                    action="CREATE",
                    content_type="Channel",
                    object_id=channel.id,
                    description=f"Created channel: {channel.name}"
                )
                
                messages.success(request, f"Channel {channel.name} created successfully.")
                return redirect("channels:detail", channel_id=channel.id)
                
        except Exception as e:
            messages.error(request, f"Error creating channel: {str(e)}")
    
    # Get form data
    zones = ChannelZone.objects.filter(is_active=True).order_by("name")
    codecs = ChannelCodec.objects.all().order_by("name")
    
    context = {
        "zones": zones,
        "codecs": codecs,
        "channel_types": Channel.CHANNEL_TYPES,
        "status_choices": Channel.STATUS_CHOICES,
    }
    
    return render(request, "channels/channel_form.html", context)


@login_required
def channel_edit(request, channel_id):
    """Edit an existing channel."""
    channel = get_object_or_404(Channel, id=channel_id)
    
    if not request.user.profile.can_manage_campaigns():
        messages.error(request, "You do not have permission to edit channels.")
        return redirect("channels:detail", channel_id=channel.id)
    
    if request.method == "POST":
        try:
            with transaction.atomic():
                channel.name = request.POST["name"]
                channel.display_name = request.POST.get("display_name", "")
                channel.channel_number = request.POST.get("channel_number") or None
                channel.channel_type = request.POST.get("channel_type", "tv")
                channel.status = request.POST.get("status", "active")
                channel.stream_url = request.POST.get("stream_url", "")
                channel.backup_stream_url = request.POST.get("backup_stream_url", "")
                channel.codec_id = request.POST.get("codec") or None
                channel.zone_id = request.POST.get("zone") or None
                channel.description = request.POST.get("description", "")
                channel.website = request.POST.get("website", "")
                channel.language = request.POST.get("language", "")
                channel.category = request.POST.get("category", "")
                channel.target_audience = request.POST.get("target_audience", "")
                channel.supports_dai = request.POST.get("supports_dai") == "on"
                channel.max_ad_duration = int(request.POST.get("max_ad_duration", 180))
                channel.min_ad_gap = int(request.POST.get("min_ad_gap", 300))
                
                # Handle logo upload
                if "logo" in request.FILES:
                    channel.logo = request.FILES["logo"]
                
                channel.save()
                
                # Log activity
                ActivityLog.objects.create(
                    user=request.user,
                    action="UPDATE",
                    content_type="Channel",
                    object_id=channel.id,
                    description=f"Updated channel: {channel.name}"
                )
                
                messages.success(request, f"Channel {channel.name} updated successfully.")
                return redirect("channels:detail", channel_id=channel.id)
                
        except Exception as e:
            messages.error(request, f"Error updating channel: {str(e)}")
    
    # Get form data
    zones = ChannelZone.objects.filter(is_active=True).order_by("name")
    codecs = ChannelCodec.objects.all().order_by("name")
    
    context = {
        "channel": channel,
        "zones": zones,
        "codecs": codecs,
        "channel_types": Channel.CHANNEL_TYPES,
        "status_choices": Channel.STATUS_CHOICES,
        "is_edit": True,
    }
    
    return render(request, "channels/channel_form.html", context)


@login_required
def epg_list(request, channel_id):
    """List EPG programs for a channel."""
    channel = get_object_or_404(Channel, id=channel_id)
    
    programs = channel.programs.all()
    
    # Filtering
    date_filter = request.GET.get("date")
    if date_filter:
        try:
            filter_date = timezone.datetime.strptime(date_filter, "%Y-%m-%d").date()
            programs = programs.filter(
                start_time__date=filter_date
            )
        except ValueError:
            pass
    
    program_type = request.GET.get("type")
    if program_type:
        programs = programs.filter(program_type=program_type)
    
    # Pagination
    paginator = Paginator(programs.order_by("start_time"), 50)
    page_number = request.GET.get("page")
    page_obj = paginator.get_page(page_number)
    
    context = {
        "channel": channel,
        "page_obj": page_obj,
        "program_types": EPGProgram.PROGRAM_TYPES,
        "current_date": date_filter,
        "current_type": program_type,
    }
    
    return render(request, "channels/epg_list.html", context)


@login_required
def jingle_list(request, channel_id):
    """List jingles for a channel."""
    channel = get_object_or_404(Channel, id=channel_id)
    
    jingles = channel.jingles.all()
    
    # Filtering
    jingle_type = request.GET.get("type")
    if jingle_type:
        jingles = jingles.filter(jingle_type=jingle_type)
    
    is_active = request.GET.get("active")
    if is_active == "true":
        jingles = jingles.filter(is_active=True)
    elif is_active == "false":
        jingles = jingles.filter(is_active=False)
    
    # Pagination
    paginator = Paginator(jingles.order_by("-priority", "name"), 20)
    page_number = request.GET.get("page")
    page_obj = paginator.get_page(page_number)
    
    context = {
        "channel": channel,
        "page_obj": page_obj,
        "jingle_types": Jingle.JINGLE_TYPES,
        "current_type": jingle_type,
        "current_active": is_active,
    }
    
    return render(request, "channels/jingle_list.html", context)


@login_required
def jingle_upload(request, channel_id):
    """Upload a new jingle for a channel."""
    channel = get_object_or_404(Channel, id=channel_id)
    
    if request.method == "POST":
        try:
            jingle = Jingle.objects.create(
                channel=channel,
                name=request.POST["name"],
                jingle_type=request.POST["jingle_type"],
                file=request.FILES["file"],
                duration=int(request.POST["duration"]),
                priority=int(request.POST.get("priority", 1)),
                start_date=request.POST.get("start_date") or None,
                end_date=request.POST.get("end_date") or None,
            )
            
            # Log activity
            ActivityLog.objects.create(
                user=request.user,
                action="CREATE",
                content_type="Jingle",
                object_id=jingle.id,
                description=f"Uploaded jingle: {jingle.name} for {channel.name}"
            )
            
            messages.success(request, f"Jingle {jingle.name} uploaded successfully.")
            return redirect("channels:jingle_list", channel_id=channel.id)
            
        except Exception as e:
            messages.error(request, f"Error uploading jingle: {str(e)}")
    
    context = {
        "channel": channel,
        "jingle_types": Jingle.JINGLE_TYPES,
    }
    
    return render(request, "channels/jingle_upload.html", context)


@login_required
@require_http_methods(["POST"])
def channel_health_check(request, channel_id):
    """Perform health check on a channel."""
    channel = get_object_or_404(Channel, id=channel_id)
    
    try:
        # Here you would implement actual health check logic
        # For now, we"ll simulate it
        import requests
        import time
        
        start_time = time.time()
        
        if channel.stream_url:
            try:
                response = requests.head(channel.stream_url, timeout=10)
                is_online = response.status_code == 200
            except:
                is_online = False
        else:
            is_online = True  # Assume online if no URL to check
        
        response_time = int((time.time() - start_time) * 1000)  # ms
        
        channel.update_health_status(is_online)
        
        # Log activity
        ActivityLog.objects.create(
            user=request.user,
            action="HEALTH_CHECK",
            content_type="Channel",
            object_id=channel.id,
            description=f"Health check for {channel.name}: {'Online' if is_online else 'Offline'}",
            extra_info=f"Response time: {response_time} ms"
        )
        
        return JsonResponse({
            "success": True,
            "is_online": is_online,
            "response_time": response_time,
            "last_check": channel.last_health_check.isoformat() if channel.last_health_check else None
        })
        
    except Exception as e:
        return JsonResponse({
            "success": False,
            "error": str(e)
        })


@login_required
def channel_stats_api(request, channel_id):
    """API endpoint for channel statistics."""
    channel = get_object_or_404(Channel, id=channel_id)
    
    # Get date range
    days = int(request.GET.get("days", 7))
    end_date = timezone.now().date()
    start_date = end_date - timedelta(days=days)
    
    # Get program statistics
    programs = channel.programs.filter(
        start_time__date__gte=start_date,
        start_time__date__lte=end_date
    )
    
    # Daily program counts
    daily_stats = []
    current_date = start_date
    
    while current_date <= end_date:
        day_programs = programs.filter(start_time__date=current_date)
        
        daily_stats.append({
            "date": current_date.isoformat(),
            "program_count": day_programs.count(),
            "total_duration": sum(p.duration for p in day_programs),
        })
        
        current_date += timedelta(days=1)
    
    # Program type breakdown
    program_types = {}
    for program_type, label in EPGProgram.PROGRAM_TYPES:
        count = programs.filter(program_type=program_type).count()
        if count > 0:
            program_types[program_type] = {
                "label": label,
                "count": count
            }
    
    return JsonResponse({
        "daily_stats": daily_stats,
        "program_types": program_types,
        "total_programs": programs.count(),
        "total_jingles": channel.jingles.filter(is_active=True).count(),
        "is_online": channel.is_online,
        "last_health_check": channel.last_health_check.isoformat() if channel.last_health_check else None,
    })


# EPG Program Views
class EPGProgramListView(LoginRequiredMixin, ListView):
    """
    List all EPG programs
    """
    model = EPGProgram
    template_name = "channels/epg_list.html"
    context_object_name = "programs"
    paginate_by = 20
    
    def get_queryset(self):
        queryset = EPGProgram.objects.select_related("channel")
        
        # Filter by channel
        channel_id = self.request.GET.get("channel")
        if channel_id:
            queryset = queryset.filter(channel_id=channel_id)
        
        # Filter by date
        date = self.request.GET.get("date")
        if date:
            try:
                date_obj = datetime.strptime(date, "%Y-%m-%d").date()
                queryset = queryset.filter(start_time__date=date_obj)
            except ValueError:
                pass
        
        # Filter by program type
        program_type = self.request.GET.get("type")
        if program_type:
            queryset = queryset.filter(program_type=program_type)
        
        # Search
        search = self.request.GET.get("search")
        if search:
            queryset = queryset.filter(
                Q(title__icontains=search) |
                Q(description__icontains=search)
            )
        
        return queryset.order_by("-start_time")
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["channels"] = Channel.objects.filter(status="active").order_by("name")
        context["program_types"] = EPGProgram.PROGRAM_TYPE_CHOICES
        context["filters"] = {
            "channel": self.request.GET.get("channel", ""),
            "date": self.request.GET.get("date", ""),
            "type": self.request.GET.get("type", ""),
            "search": self.request.GET.get("search", ""),
        }
        return context


class EPGProgramDetailView(LoginRequiredMixin, DetailView):
    """
    EPG program detail view
    """
    model = EPGProgram
    template_name = "channels/epg_detail.html"
    context_object_name = "program"
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        program = self.get_object()
        
        # Get related programs (same channel, same day)
        related_programs = EPGProgram.objects.filter(
            channel=program.channel,
            start_time__date=program.start_time.date()
        ).exclude(id=program.id).order_by("start_time")[:5]
        
        context["related_programs"] = related_programs
        return context


class EPGProgramCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """
    Create new EPG program
    """
    model = EPGProgram
    fields = ["channel", "title", "description", "start_time", "end_time", 
              "program_type", "genre", "rating", "language", "is_live"]
    template_name = "channels/epg_form.html"
    permission_required = "channels.add_epgprogram"
    
    def get_success_url(self):
        return reverse("channels:epg_detail", kwargs={"pk": self.object.pk})
    
    def form_valid(self, form):
        # Log activity
        ActivityLog.objects.create(
            user=self.request.user,
            action="create",
            content_object=form.instance,
            description=f"Created EPG program: {form.instance.title}"
        )
        
        messages.success(self.request, "EPG program created successfully!")
        return super().form_valid(form)


class EPGProgramUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """
    Update existing EPG program
    """
    model = EPGProgram
    fields = ["channel", "title", "description", "start_time", "end_time", 
              "program_type", "genre", "rating", "language", "is_live"]
    template_name = "channels/epg_form.html"
    permission_required = "channels.change_epgprogram"
    
    def get_success_url(self):
        return reverse("channels:epg_detail", kwargs={"pk": self.object.pk})
    
    def form_valid(self, form):
        # Log activity
        ActivityLog.objects.create(
            user=self.request.user,
            action="update",
            content_object=form.instance,
            description=f"Updated EPG program: {form.instance.title}"
        )
        
        messages.success(self.request, "EPG program updated successfully!")
        return super().form_valid(form)


class EPGProgramDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """
    Delete EPG program
    """
    model = EPGProgram
    template_name = "channels/epg_confirm_delete.html"
    permission_required = "channels.delete_epgprogram"
    success_url = reverse_lazy("channels:epg_list")
    
    def delete(self, request, *args, **kwargs):
        program = self.get_object()
        
        # Log activity
        ActivityLog.objects.create(
            user=request.user,
            action="delete",
            content_object=program,
            description=f"Deleted EPG program: {program.title}"
        )
        
        messages.success(request, "EPG program deleted successfully!")
        return super().delete(request, *args, **kwargs)


# Jingle Views
class JingleListView(LoginRequiredMixin, ListView):
    """
    List all jingles
    """
    model = Jingle
    template_name = "channels/jingle_list.html"
    context_object_name = "jingles"
    paginate_by = 20
    
    def get_queryset(self):
        queryset = Jingle.objects.select_related("channel")
        
        # Filter by channel
        channel_id = self.request.GET.get("channel")
        if channel_id:
            queryset = queryset.filter(channel_id=channel_id)
        
        # Filter by type
        jingle_type = self.request.GET.get("type")
        if jingle_type:
            queryset = queryset.filter(jingle_type=jingle_type)
        
        # Filter by active status
        is_active = self.request.GET.get("active")
        if is_active:
            queryset = queryset.filter(is_active=is_active == "true")
        
        # Search
        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["channels"] = Channel.objects.filter(status="active").order_by("name")
        context["jingle_types"] = Jingle.JINGLE_TYPE_CHOICES
        context["filters"] = {
            "channel": self.request.GET.get("channel", ""),
            "type": self.request.GET.get("type", ""),
            "active": self.request.GET.get("active", ""),
            "search": self.request.GET.get("search", ""),
        }
        return context


class JingleDetailView(LoginRequiredMixin, DetailView):
    """
    Jingle detail view
    """
    model = Jingle
    template_name = "channels/jingle_detail.html"
    context_object_name = "jingle"
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        jingle = self.get_object()
        
        # Get related jingles (same channel, same type)
        related_jingles = Jingle.objects.filter(
            channel=jingle.channel,
            jingle_type=jingle.jingle_type
        ).exclude(id=jingle.id).order_by("-created_at")[:5]
        
        context["related_jingles"] = related_jingles
        return context


class JingleCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """
    Create new jingle
    """
    model = Jingle
    fields = ["channel", "name", "description", "jingle_type", "audio_file", 
              "duration", "is_active"]
    template_name = "channels/jingle_form.html"
    permission_required = "channels.add_jingle"
    
    def get_success_url(self):
        return reverse("channels:jingle_detail", kwargs={"pk": self.object.pk})
    
    def form_valid(self, form):
        # Log activity
        ActivityLog.objects.create(
            user=self.request.user,
            action="create",
            content_object=form.instance,
            description=f"Created jingle: {form.instance.name}"
        )
        
        messages.success(self.request, "Jingle created successfully!")
        return super().form_valid(form)


class JingleUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """
    Update existing jingle
    """
    model = Jingle
    fields = ["channel", "name", "description", "jingle_type", "audio_file", 
              "duration", "is_active"]
    template_name = "channels/jingle_form.html"
    permission_required = "channels.change_jingle"
    
    def get_success_url(self):
        return reverse("channels:jingle_detail", kwargs={"pk": self.object.pk})
    
    def form_valid(self, form):
        # Log activity
        ActivityLog.objects.create(
            user=self.request.user,
            action="update",
            content_object=form.instance,
            description=f"Updated jingle: {form.instance.name}"
        )
        
        messages.success(self.request, "Jingle updated successfully!")
        return super().form_valid(form)


class JingleDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """
    Delete jingle
    """
    model = Jingle
    template_name = "channels/jingle_confirm_delete.html"
    permission_required = "channels.delete_jingle"
    success_url = reverse_lazy("channels:jingle_list")
    
    def delete(self, request, *args, **kwargs):
        jingle = self.get_object()
        
        # Log activity
        ActivityLog.objects.create(
            user=request.user,
            action="delete",
            content_object=jingle,
            description=f"Deleted jingle: {jingle.name}"
        )
        
        messages.success(request, "Jingle deleted successfully!")
        return super().delete(request, *args, **kwargs)


# Channel Schedule Views
class ChannelScheduleListView(LoginRequiredMixin, ListView):
    """
    List all channel schedules
    """
    model = ChannelSchedule
    template_name = "channels/schedule_list.html"
    context_object_name = "schedules"
    paginate_by = 20
    
    def get_queryset(self):
        queryset = ChannelSchedule.objects.select_related("channel")
        
        # Filter by channel
        channel_id = self.request.GET.get("channel")
        if channel_id:
            queryset = queryset.filter(channel_id=channel_id)
        
        # Filter by date
        date = self.request.GET.get("date")
        if date:
            try:
                date_obj = datetime.strptime(date, "%Y-%m-%d").date()
                queryset = queryset.filter(schedule_date=date_obj)
            except ValueError:
                pass
        
        # Filter by active status
        is_active = self.request.GET.get("active")
        if is_active:
            queryset = queryset.filter(is_active=is_active == "true")
        
        # Search
        search = self.request.GET.get("search")
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) |
                Q(description__icontains=search)
            )
        
        return queryset.order_by("-schedule_date", "start_time")
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["channels"] = Channel.objects.filter(status="active").order_by("name")
        context["filters"] = {
            "channel": self.request.GET.get("channel", ""),
            "date": self.request.GET.get("date", ""),
            "active": self.request.GET.get("active", ""),
            "search": self.request.GET.get("search", ""),
        }
        return context


class ChannelScheduleDetailView(LoginRequiredMixin, DetailView):
    """
    Channel schedule detail view
    """
    model = ChannelSchedule
    template_name = "channels/schedule_detail.html"
    context_object_name = "schedule"
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        schedule = self.get_object()
        
        # Get related schedules (same channel, same date)
        related_schedules = ChannelSchedule.objects.filter(
            channel=schedule.channel,
            schedule_date=schedule.schedule_date
        ).exclude(id=schedule.id).order_by("start_time")[:5]
        
        context["related_schedules"] = related_schedules
        return context


class ChannelScheduleCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    """
    Create new channel schedule
    """
    model = ChannelSchedule
    fields = ["channel", "name", "description", "schedule_date", "start_time", 
              "end_time", "schedule_data", "is_active"]
    template_name = "channels/schedule_form.html"
    permission_required = "channels.add_channelschedule"
    
    def get_success_url(self):
        return reverse("channels:schedule_detail", kwargs={"pk": self.object.pk})
    
    def form_valid(self, form):
        # Log activity
        ActivityLog.objects.create(
            user=self.request.user,
            action="create",
            content_object=form.instance,
            description=f"Created channel schedule: {form.instance.name}"
        )
        
        messages.success(self.request, "Channel schedule created successfully!")
        return super().form_valid(form)


class ChannelScheduleUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    """
    Update existing channel schedule
    """
    model = ChannelSchedule
    fields = ["channel", "name", "description", "schedule_date", "start_time", 
              "end_time", "schedule_data", "is_active"]
    template_name = "channels/schedule_form.html"
    permission_required = "channels.change_channelschedule"
    
    def get_success_url(self):
        return reverse("channels:schedule_detail", kwargs={"pk": self.object.pk})
    
    def form_valid(self, form):
        # Log activity
        ActivityLog.objects.create(
            user=self.request.user,
            action="update",
            content_object=form.instance,
            description=f"Updated channel schedule: {form.instance.name}"
        )
        
        messages.success(self.request, "Channel schedule updated successfully!")
        return super().form_valid(form)


class ChannelScheduleDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    """
    Delete channel schedule
    """
    model = ChannelSchedule
    template_name = "channels/schedule_confirm_delete.html"
    permission_required = "channels.delete_channelschedule"
    success_url = reverse_lazy("channels:schedule_list")
    
    def delete(self, request, *args, **kwargs):
        schedule = self.get_object()
        
        # Log activity
        ActivityLog.objects.create(
            user=request.user,
            action="delete",
            content_object=schedule,
            description=f"Deleted channel schedule: {schedule.name}"
        )
        
        messages.success(request, "Channel schedule deleted successfully!")
        return super().delete(request, *args, **kwargs)


# AJAX Views
@login_required
def channel_search_ajax(request):
    """
    AJAX endpoint for channel search
    """
    query = request.GET.get("q", "")
    channels = Channel.objects.filter(
        Q(name__icontains=query) |
        Q(description__icontains=query)
    ).values("id", "name", "channel_number")[:10]
    
    return JsonResponse({
        "status": "success",
        "channels": list(channels)
    })


@login_required
def epg_search_ajax(request):
    """
    AJAX endpoint for EPG program search
    """
    query = request.GET.get("q", "")
    channel_id = request.GET.get("channel")
    
    programs = EPGProgram.objects.filter(
        Q(title__icontains=query) |
        Q(description__icontains=query)
    )
    
    if channel_id:
        programs = programs.filter(channel_id=channel_id)
    
    programs = programs.values(
        "id", "title", "start_time", "end_time", "program_type"
    )[:10]
    
    return JsonResponse({
        "status": "success",
        "programs": list(programs)
    })


@login_required
def channel_performance_ajax(request, channel_id):
    """
    AJAX endpoint for channel performance data
    """
    try:
        channel = Channel.objects.get(id=channel_id)
        
        # Get performance data for the last 30 days
        end_date = timezone.now().date()
        start_date = end_date - timedelta(days=30)
        
        # Daily program counts
        daily_programs = []
        current_date = start_date
        while current_date <= end_date:
            count = EPGProgram.objects.filter(
                channel=channel,
                start_time__date=current_date
            ).count()
            daily_programs.append({
                "date": current_date.strftime("%Y-%m-%d"),
                "count": count
            })
            current_date += timedelta(days=1)
        
        # Program type breakdown
        program_types = EPGProgram.objects.filter(
            channel=channel,
            start_time__gte=start_date
        ).values("program_type").annotate(
            count=Count("id")
        ).order_by("-count")
        
        # Jingle statistics
        jingle_stats = Jingle.objects.filter(
            channel=channel
        ).aggregate(
            total=Count("id"),
            active=Count("id", filter=Q(is_active=True))
        )
        
        return JsonResponse({
            "status": "success",
            "data": {
                "daily_programs": daily_programs,
                "program_types": list(program_types),
                "jingle_stats": jingle_stats,
                "is_online": channel.is_online,
            }
        })
        
    except Channel.DoesNotExist:
        return JsonResponse({
            "status": "error",
            "message": "Channel not found"
        }, status=404)
    except Exception as e:
        logger.error(f"Error getting channel performance: {str(e)}")
        return JsonResponse({
            "status": "error",
            "message": "Internal server error"
        }, status=500)

