"""Views for the channels app.

This module contains all view classes for managing channels, jingles, adbreaks,
and related functionality. All views inherit from Django's base View class
to provide maximum flexibility and control over request handling.

Author: Django Channels App
Version: 1.0.0
Date: 2024
"""

import json
import datetime 
from typing import Dict, Any, List, Union, Optional 


from django.contrib.auth import logout
from django.http import (
    HttpRequest, HttpResponse, JsonResponse, Http404,
    HttpResponseRedirect, HttpResponseBadRequest
)
from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse
from django.views import View
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib import messages
from django.db.models import Q, Count, Avg, Sum, Max, Min 
from django.utils import timezone
from django.core.exceptions import ValidationError
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import View
from django.shortcuts import render, get_object_or_404 
from django.http import HttpRequest, HttpResponse, JsonResponse, Http404 
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db.models import Q, Count
from django.utils import timezone
from django.utils.translation import gettext as _ 
 
from django.core.cache import cache 



from apps.common.utils import get_client_ip 

from apps.channels.models import (
    Channel, ChannelZone, ChannelCodec, Jingle, Adbreak,
    EPGProgram, ChannelSchedule, ChannelZoneRelation
)

from apps.activities.models import Activity




class ChannelListView(LoginRequiredMixin, View):
    """
        Channel List View

        This view is responsible for rendering the channels 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 channels list page template with advanced
        filtering, searching, pagination, and AJAX support.

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

        Template:
            - 'channels/channel/list.html': The HTML template used to render the channels list page.

        Features:
            - Advanced filtering by type, status, zone, and date ranges
            - Full-text search across channel name, display name, and description
            - Pagination with customizable items per page
            - AJAX support for dynamic updates
            - Statistics and analytics
            - Export functionality
            - Real-time updates
    """
    
    http_method_names = ["get"]
    template_name = "channels/channel/list.html"
    extra_context = {
        "title": "Channels - Adtlas",
        "author": "Adtlas Development Team", 
        "description": "Channels management for Adtlas TV advertising solutions. This page provides comprehensive channel management and insights.",
        "keywords": "Adtlas, channels, TV advertising solutions, channel management, broadcasting, data visualization",
        "active_menu": "channels",
    }

    def get_context_data(self, **kwargs):
        """
        Add channels page context data.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Updated context data
        """
        context = super().get_context_data(**kwargs)
        context.update({
            "title": _("Channels"),
        })
        return context
        
    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        """
            Handles the HTTP GET request and returns the rendered channels list page template.

            Args:
                request (HttpRequest): The HTTP request object.
                *args: Variable length argument list.
                **kwargs: Arbitrary keyword arguments.

            Returns:
                HttpResponse: The rendered channels list page template.

            Query Parameters:
                - search: Search term for channel name/display_name/description
                - type: Filter by channel type
                - status: Filter by channel status
                - zone: Filter by channel zone
                - date_from: Start date for filtering
                - date_to: End date for filtering
                - date_range: Predefined date range
                - sort_by: Sorting field and direction
                - page: Page number for pagination
                - per_page: Number of items per page (default: 20)
        """

        # 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)
        
        # 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 _get_filtered_queryset(self, request: HttpRequest):
        """
        Build filtered queryset based on request parameters.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered channel queryset
        """
        # Base queryset with optimizations
        queryset = Channel.objects.all().select_related().prefetch_related('zones')
        
        # Apply filters
        queryset = self._apply_search_filter(queryset, request)
        queryset = self._apply_type_filter(queryset, request)
        queryset = self._apply_status_filter(queryset, request)
        queryset = self._apply_zone_filter(queryset, request)
        queryset = self._apply_date_filters(queryset, request)
        
        # Apply sorting
        queryset = self._apply_sorting(queryset, request)
        
        return queryset

    def _apply_search_filter(self, queryset, request):
        """
        Apply search filter to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        """
        search_query = request.GET.get('search', '').strip()
        
        if search_query:
            queryset = queryset.filter(
                Q(name__icontains=search_query) |
                Q(display_name__icontains=search_query) |
                Q(description__icontains=search_query) |
                Q(channel_code__icontains=search_query)
            )
        
        return queryset

    def _apply_type_filter(self, queryset, request):
        """
        Apply channel type filter to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        """
        channel_type = request.GET.get('type', '').strip()
        
        if channel_type and channel_type != 'all':
            queryset = queryset.filter(channel_type=channel_type)
        
        return queryset

    def _apply_status_filter(self, queryset, request):
        """
        Apply status filter to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        """
        status_filter = request.GET.get('status', '').strip()
        
        if status_filter and status_filter != 'all':
            queryset = queryset.filter(status=status_filter)
        
        return queryset

    def _apply_zone_filter(self, queryset, request):
        """
        Apply zone filter to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        """
        zone_filter = request.GET.get('zone', '').strip()
        
        if zone_filter and zone_filter != 'all':
            queryset = queryset.filter(zones__id=zone_filter)
        
        return queryset

    def _apply_date_filters(self, queryset, request):
        """
        Apply date range filters to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        """
        date_from = request.GET.get('date_from')
        date_to = request.GET.get('date_to')
        date_range = request.GET.get('date_range')
        
        # Handle predefined date ranges
        if date_range:
            today = timezone.now().date()
            
            if date_range == 'today':
                queryset = queryset.filter(created_at__date=today)
            elif date_range == 'yesterday':
                yesterday = today - datetime.timedelta(days=1)
                queryset = queryset.filter(created_at__date=yesterday)
            elif date_range == 'this_week':
                week_start = today - datetime.timedelta(days=today.weekday())
                queryset = queryset.filter(created_at__date__gte=week_start)
            elif date_range == 'this_month':
                month_start = today.replace(day=1)
                queryset = queryset.filter(created_at__date__gte=month_start)
            elif date_range == 'last_30_days':
                last_30_days = today - datetime.timedelta(days=30)
                queryset = queryset.filter(created_at__date__gte=last_30_days)
        
        # Handle custom date range
        if date_from:
            try:
                from_date = datetime.datetime.strptime(date_from, '%Y-%m-%d').date()
                queryset = queryset.filter(created_at__date__gte=from_date)
            except ValueError:
                pass
        
        if date_to:
            try:
                to_date = datetime.datetime.strptime(date_to, '%Y-%m-%d').date()
                queryset = queryset.filter(created_at__date__lte=to_date)
            except ValueError:
                pass
        
        return queryset

    def _apply_sorting(self, queryset, request):
        """
        Apply sorting to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Sorted queryset
        """
        sort_by = request.GET.get('sort_by', 'name')
        
        valid_sort_fields = [
            'name', '-name',
            'display_name', '-display_name',
            'channel_type', '-channel_type',
            'status', '-status',
            'created_at', '-created_at',
            'updated_at', '-updated_at'
        ]
        
        if sort_by in valid_sort_fields:
            queryset = queryset.order_by(sort_by)
        else:
            queryset = queryset.order_by('name')
        
        return queryset

    def _build_context(self, request: HttpRequest, page_obj, paginator) -> Dict[str, Any]:
        """
        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
            'channels': page_obj.object_list,
            'page_obj': page_obj,
            'paginator': paginator,
            'is_paginated': paginator.num_pages > 1,
            
            # Filter data
            'channel_types': self._get_channel_types(),
            'status_choices': self._get_status_choices(),
            'zones': self._get_available_zones(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,
        }
        
        # Add extra context
        context.update(self.extra_context)
        
        return context

    def _get_channel_types(self):
        """
        Get available channel types.
        
        Returns:
            list: Channel type choices
        """
        # Assuming Channel model has CHANNEL_TYPES choices
        return getattr(Channel, 'CHANNEL_TYPES', [])

    def _get_status_choices(self):
        """
        Get available status choices.
        
        Returns:
            list: Status choices
        """
        # Assuming Channel model has STATUS_CHOICES
        return getattr(Channel, 'STATUS_CHOICES', [])

    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', 'created_at')

    def _get_current_filters(self, request: HttpRequest) -> Dict[str, str]:
        """
        Get current filter parameters for template.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            dict: Current filter values
        """
        return {
            'search': request.GET.get('search', ''),
            'type': request.GET.get('type', 'all'),
            'status': request.GET.get('status', 'all'),
            'zone': request.GET.get('zone', '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', 'name'),
            'per_page': request.GET.get('per_page', '20'),
        }

    def _get_sort_options(self) -> list:
        """
        Get available sorting options.
        
        Returns:
            list: Sort options for template
        """
        return [
            {'value': 'name', 'label': 'Name (A-Z)'},
            {'value': '-name', 'label': 'Name (Z-A)'},
            {'value': 'display_name', 'label': 'Display Name (A-Z)'},
            {'value': '-display_name', 'label': 'Display Name (Z-A)'},
            {'value': 'channel_type', 'label': 'Type (A-Z)'},
            {'value': '-channel_type', 'label': 'Type (Z-A)'},
            {'value': '-created_at', 'label': 'Newest First'},
            {'value': 'created_at', 'label': 'Oldest First'},
            {'value': '-updated_at', 'label': 'Recently Updated'},
        ]

    def _get_stats(self, user) -> Dict[str, int]:
        """
        Get channels statistics for dashboard.

        Args:
            user: Current user object

        Returns:
            dict: Channels statistics
        """
        base_queryset = Channel.objects.all()
        today = timezone.now().date()
        week_ago = today - datetime.timedelta(days=7)

        return {   
            'total_channels': base_queryset.count(),
            'active_channels': base_queryset.filter(status="active").count(),
            'online_channels': base_queryset.filter(is_online=True).count(),
            'pending_channels': base_queryset.filter(status="pending").count(),
            'inactive_channels': base_queryset.filter(status="inactive").count(),
            'offline_channels': base_queryset.filter(is_online=False).count(),
            'recent_channels': base_queryset.filter(
                created_at__date__gte=week_ago
            ).count(),
            'channels_by_type': base_queryset.values('channel_type').annotate(
                count=Count('id')
            ).order_by('-count'),
            'channels_with_zones': base_queryset.filter(zones__isnull=False).distinct().count(),
            'channels_without_zones': base_queryset.filter(zones__isnull=True).count(),
        }

    def _get_date_range(self) -> Dict[str, datetime.date]:
        """
        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: HttpRequest) -> JsonResponse:
        """
        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_ajax(request)
        elif action == 'get_channel_types':
            return self._get_channel_types_ajax(request)
        elif action == 'quick_stats':
            return self._get_quick_stats_ajax(request)
        elif action == 'export_data':
            return self._export_channels_data_ajax(request)
        elif action == 'load_more':
            return self._load_more_channels_ajax(request)
        
        # Default: return filtered channel data
        return self._get_filtered_channels_ajax(request)

    def _get_zones_ajax(self, request: HttpRequest) -> JsonResponse:
        """
        Get zones via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with zone data
        """
        user = request.user
        zones = self._get_available_zones(user)
        
        return JsonResponse({
            'success': True,
            'zones': list(zones.values('id', 'name', 'region', 'code'))
        })

    def _get_channel_types_ajax(self, request: HttpRequest) -> JsonResponse:
        """
        Get channel types via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with channel type data
        """
        channel_types = self._get_channel_types()
        
        return JsonResponse({
            'success': True,
            'channel_types': [{'value': ct[0], 'label': ct[1]} for ct in channel_types]
        })

    def _get_quick_stats_ajax(self, request: HttpRequest) -> JsonResponse:
        """
        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_channels_data_ajax(self, request: HttpRequest) -> JsonResponse:
        """
        Export channels 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()} channels',
            'download_url': '#',  # Replace with actual download URL
            'count': queryset.count()
        })

    def _load_more_channels_ajax(self, request: HttpRequest) -> JsonResponse:
        """
        Load more channels via AJAX for infinite scroll.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with additional channels
        """
        page = int(request.GET.get('page', 1))
        per_page = self._get_items_per_page(request)
        
        queryset = self._get_filtered_queryset(request)
        paginator = Paginator(queryset, per_page)
        
        try:
            page_obj = paginator.get_page(page)
        except (PageNotAnInteger, EmptyPage):
            return JsonResponse({'success': False, 'error': 'Invalid page'})
        
        # Convert channels to dict for JSON response
        channels_data = []
        for channel in page_obj.object_list:
            channels_data.append({
                'id': channel.id,
                'name': channel.name,
                'display_name': getattr(channel, 'display_name', ''),
                'channel_type': getattr(channel, 'channel_type', ''),
                'status': getattr(channel, 'status', ''),
                'created_at': channel.created_at.isoformat() if hasattr(channel, 'created_at') else '',
            })
        
        return JsonResponse({
            'success': True,
            'channels': channels_data,
            'has_next': page_obj.has_next(),
            'next_page': page_obj.next_page_number() if page_obj.has_next() else None,
            'current_page': page_obj.number,
            'total_pages': paginator.num_pages,
        })

    def _get_filtered_channels_ajax(self, request: HttpRequest) -> JsonResponse:
        """
        Get filtered channels via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with filtered channels
        """
        queryset = self._get_filtered_queryset(request)
        paginator = Paginator(queryset, self._get_items_per_page(request))
        page = request.GET.get('page', 1)
        
        try:
            page_obj = paginator.get_page(page)
        except (PageNotAnInteger, EmptyPage):
            return JsonResponse({'success': False, 'error': 'Invalid page'})
        
        # Convert to dict for JSON response
        channels_data = []
        for channel in page_obj.object_list:
            channels_data.append({
                'id': channel.id,
                'name': channel.name,
                'display_name': getattr(channel, 'display_name', ''),
                'channel_type': getattr(channel, 'channel_type', ''),
                'status': getattr(channel, 'status', ''),
                'zone_count': channel.zones.count() if hasattr(channel, 'zones') else 0,
            })
        
        return JsonResponse({
            'success': True,
            'channels': channels_data,
            'total_results': paginator.count,
            'current_page': page_obj.number,
            'total_pages': paginator.num_pages,
            'has_next': page_obj.has_next(),
            'has_previous': page_obj.has_previous(),
        })

    def _get_items_per_page(self, request: HttpRequest) -> int:
        """
        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_channels",
            description=f"User {user.email if user else 'System'} viewed channels list",
            request=request,
            ip_address=get_client_ip(request),
            user_agent=request.META.get("HTTP_USER_AGENT", ""),
            metadata={
                'filters_applied': self._get_current_filters(request),
                'results_count': self._get_filtered_queryset(request).count(),
            }
        )

    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)


class ChannelDetailView(LoginRequiredMixin, View):
    """
    Channel Detail View

    This view is responsible for rendering the channel detail page of the application.
    It extends the Django View class and provides comprehensive channel information
    including zones, codecs, recent adbreaks, jingles, health status, analytics,
    and real-time monitoring data.

    Methods:
        get(request, channel_id): Handles the HTTP GET request and returns the rendered
            channel detail page template with comprehensive data.

    Template:
        - 'channels/channel/detail.html': The HTML template used to render the channel detail page.

    Features:
        - Comprehensive channel information display
        - Real-time health status monitoring
        - Advanced analytics and statistics
        - Interactive charts and graphs
        - AJAX support for dynamic updates
        - Export functionality for reports
        - Historical data analysis
        - Performance metrics tracking
        - Zone and codec management
        - Adbreak and jingle analysis

    """
    
    http_method_names = ["get", "post"]
    template_name = "channels/channel/detail.html"
    extra_context = {
        "author": "Adtlas Development Team", 
        "description": "Detailed channel information and analytics for Adtlas TV advertising solutions.",
        "keywords": "Adtlas, channel details, TV advertising, channel analytics, broadcasting metrics",
        "active_menu": "channels",
    }

    def get_context_data(self, channel, **kwargs):
        """
        Add channel detail page context data.
        
        Args:
            channel: Channel object
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Updated context data
        """
        context = super().get_context_data(**kwargs) if hasattr(super(), 'get_context_data') else {}
        context.update({
            "title": f"{channel.name} - Channel Details - Adtlas",
            "page_title": _("Channel Details"),
            "channel_name": channel.name,
        })
        return context

    def get(self, request: HttpRequest, channel_id: int, *args, **kwargs) -> HttpResponse:
        """
        Handles the HTTP GET request and returns the rendered channel detail page template.

        Args:
            request (HttpRequest): The HTTP request object.
            channel_id (int): Primary key of the channel to display.
            *args: Variable length argument list.
            **kwargs: Arbitrary keyword arguments.

        Returns:
            HttpResponse: The rendered channel detail page template.

        Raises:
            Http404: If channel with given ID doesn't exist or user doesn't have permission.

        Query Parameters:
            - tab: Active tab to display (overview, analytics, zones, adbreaks, jingles, health)
            - date_from: Start date for analytics filtering
            - date_to: End date for analytics filtering
            - date_range: Predefined date range for analytics
            - export: Export format (json, csv, pdf)
        """

        # Check for AJAX requests
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return self._handle_ajax_request(request, channel_id)

        # Get channel object with permission check
        channel = self._get_channel_with_permissions(request, channel_id)
        
        # Get active tab
        active_tab = request.GET.get('tab', 'overview')
        
        # Log user activity for auditing
        self._log_user_activity(request, channel)
        
        # Build comprehensive context
        context = self._build_comprehensive_context(request, channel, active_tab)
        
        return render(request, self.template_name, context)

    def post(self, request: HttpRequest, channel_id: int, *args, **kwargs) -> Union[HttpResponse, JsonResponse]:
        """
        Handle POST requests for channel operations.
        
        Args:
            request: HTTP request object
            channel_id: Channel ID
            
        Returns:
            HttpResponse or JsonResponse based on request type
        """
        channel = self._get_channel_with_permissions(request, channel_id)
        
        action = request.POST.get('action')
        
        if action == 'update_status':
            return self._update_channel_status(request, channel)
        elif action == 'refresh_health':
            return self._refresh_health_status(request, channel)
        elif action == 'export_data':
            return self._export_channel_data(request, channel)
        
        messages.error(request, 'Invalid action requested.')
        return self.get(request, channel_id)

    def _get_channel_with_permissions(self, request: HttpRequest, channel_id: int):
        """
        Get channel object with permission checks.
        
        Args:
            request: HTTP request object
            channel_id: Channel ID
            
        Returns:
            Channel: Channel object
            
        Raises:
            Http404: If channel doesn't exist or user lacks permission
        """
        try:
            channel = get_object_or_404(Channel, pk=channel_id)
            
            # Add permission checks if needed
            # if not self._user_has_channel_access(request.user, channel):
            #     raise Http404("Channel not found or access denied")
            
            return channel
        except Channel.DoesNotExist:
            raise Http404("Channel not found")

    def _build_comprehensive_context(self, request: HttpRequest, channel, active_tab: str) -> Dict[str, Any]:
        """
        Build comprehensive template context with all necessary data.
        
        Args:
            request: Django HTTP request object
            channel: Channel object
            active_tab: Currently active tab
            
        Returns:
            dict: Template context
        """
        context = {
            # Basic channel info
            'channel': channel,
            'active_tab': active_tab,
            
            # Related data
            'zones': self._get_channel_zones(channel),
            'codecs': self._get_channel_codecs(channel),
            
            # Recent activity
            'recent_adbreaks': self._get_recent_adbreaks(channel),
            'recent_jingles': self._get_recent_jingles(channel),
            
            # Statistics and analytics
            'stats': self._get_channel_statistics(channel, request),
            'analytics': self._get_channel_analytics(channel, request),
            'performance_metrics': self._get_performance_metrics(channel, request),
            
            # Health and monitoring
            'health_status': self._get_health_status(channel),
            'monitoring_data': self._get_monitoring_data(channel),
            
            # Configuration data
            'date_range_options': self._get_date_range_options(),
            'export_options': self._get_export_options(),
            'chart_configs': self._get_chart_configurations(),
            
            # Navigation and UI
            'tab_configs': self._get_tab_configurations(),
            'breadcrumbs': self._get_breadcrumbs(channel),
        }
        
        # Add extra context
        context.update(self.extra_context)
        context.update(self.get_context_data(channel))
        
        return context

    def _get_channel_zones(self, channel):
        """
        Get zones associated with the channel.
        
        Args:
            channel: Channel object
            
        Returns:
            QuerySet: Channel zones with additional data
        """
        # return channel.zones.select_related().prefetch_related(
        #     'region'
        # ).annotate(
        #     adbreak_count=Count('adbreaks', distinct=True),
        #     last_activity=Max('adbreaks__start_time')
        # ).order_by('name')
        return channel.zones.select_related().prefetch_related(
            'region'
        ).order_by('name')

    def _get_channel_codecs(self, channel):
        """
        Get codecs associated with the channel.
        
        Args:
            channel: Channel object
            
        Returns:
            QuerySet: Channel codecs
        """
        # Assuming there's a relationship to codecs
        return getattr(channel, 'codecs', None) or []

    def _get_recent_adbreaks(self, channel, limit: int = 10):
        """
        Get recent adbreaks for the channel.
        
        Args:
            channel: Channel object
            limit: Number of adbreaks to return
            
        Returns:
            QuerySet: Recent adbreaks
        """
        week_ago = timezone.now().date() - datetime.timedelta(days=7)
        
        return Adbreak.objects.filter(
            channel=channel,
            date__gte=week_ago
        ).select_related(
            'campaign'
        ).prefetch_related(
            'advertisements'
        ).order_by('-date')[:limit]

    def _get_recent_jingles(self, channel, limit: int = 5):
        """
        Get recent jingles for the channel.
        
        Args:
            channel: Channel object
            limit: Number of jingles to return
            
        Returns:
            QuerySet: Recent jingles
        """
        return Jingle.objects.filter(
            channel=channel
        ).select_related(
            'category'
        ).order_by('-created_at')[:limit]

    def _get_channel_statistics(self, channel, request: HttpRequest) -> Dict[str, Any]:
        """
        Get comprehensive channel statistics.
        
        Args:
            channel: Channel object
            request: HTTP request object
            
        Returns:
            dict: Channel statistics
        """
        # Get date range for analysis
        date_from, date_to = self._get_analysis_date_range(request)
        today = timezone.now().date()
        
        # Base querysets
        adbreaks_qs = Adbreak.objects.filter(channel=channel)
        recent_adbreaks_qs = adbreaks_qs.filter(date__range=[date_from, date_to])
        
        return {
            # Basic counts
            'total_zones': channel.zones.count(),
            'total_adbreaks': adbreaks_qs.count(),
            'total_jingles': Jingle.objects.filter(channel=channel).count(),
            
            # Recent activity (based on selected date range)
            'recent_adbreaks': recent_adbreaks_qs.count(),
            'today_adbreaks': adbreaks_qs.filter(date=today).count(),
            
            # Duration statistics
            'avg_adbreak_duration': recent_adbreaks_qs.aggregate(
                avg=Avg('duration')
            )['avg'] or 0,
            'total_airtime': recent_adbreaks_qs.aggregate(
                total=Sum('duration')
            )['total'] or 0,
            'max_adbreak_duration': recent_adbreaks_qs.aggregate(
                max=Max('duration')
            )['max'] or 0,
            'min_adbreak_duration': recent_adbreaks_qs.aggregate(
                min=Min('duration')
            )['min'] or 0,
            
            # Performance metrics
            'adbreaks_per_day': self._calculate_adbreaks_per_day(channel, date_from, date_to),
            'peak_hours': self._get_peak_hours(channel, date_from, date_to),
            # 'zone_distribution': self._get_zone_distribution(channel),
            
            # Health metrics
            'uptime_percentage': self._calculate_uptime(channel),
            'error_rate': self._calculate_error_rate(channel),
            'last_activity': adbreaks_qs.aggregate(
                last=Max('start_at')
            )['last'],
        }

    def _get_channel_analytics(self, channel, request: HttpRequest) -> Dict[str, Any]:
        """
        Get detailed analytics data for charts and graphs.
        
        Args:
            channel: Channel object
            request: HTTP request object
            
        Returns:
            dict: Analytics data for visualization
        """
        date_from, date_to = self._get_analysis_date_range(request)
        
        return {
            'daily_adbreaks': self._get_daily_adbreaks_data(channel, date_from, date_to),
            'hourly_distribution': self._get_hourly_distribution(channel, date_from, date_to),
            'zone_performance': self._get_zone_performance_data(channel, date_from, date_to),
            'duration_trends': self._get_duration_trends(channel, date_from, date_to),
            'comparison_data': self._get_comparison_data(channel, date_from, date_to),
        }

    def _get_performance_metrics(self, channel, request: HttpRequest) -> Dict[str, Any]:
        """
        Get performance metrics for the channel.
        
        Args:
            channel: Channel object
            request: HTTP request object
            
        Returns:
            dict: Performance metrics
        """
        return {
            'signal_quality': self._get_signal_quality(channel),
            'transmission_stats': self._get_transmission_stats(channel),
            'error_logs': self._get_recent_errors(channel),
            'maintenance_schedule': self._get_maintenance_schedule(channel),
        }

    def _get_health_status(self, channel) -> Dict[str, Any]:
        """
        Get current health status of the channel.
        
        Args:
            channel: Channel object
            
        Returns:
            dict: Health status information
        """
        # Check cache first
        cache_key = f"channel_health_{channel.id}"
        cached_health = cache.get(cache_key)
        
        if cached_health:
            return cached_health
        
        health_data = {
            'status': self._determine_health_status(channel),
            'last_check': timezone.now(),
            'signal_strength': self._get_signal_strength(channel),
            'connectivity': self._check_connectivity(channel),
            'disk_usage': self._get_disk_usage(channel),
            'memory_usage': self._get_memory_usage(channel),
            'cpu_usage': self._get_cpu_usage(channel),
            'warnings': self._get_health_warnings(channel),
            'recommendations': self._get_health_recommendations(channel),
        }
        
        # Cache for 5 minutes
        cache.set(cache_key, health_data, 300)
        
        return health_data

    def _get_monitoring_data(self, channel) -> Dict[str, Any]:
        """
        Get real-time monitoring data.
        
        Args:
            channel: Channel object
            
        Returns:
            dict: Monitoring data
        """
        return {
            'live_status': self._get_live_status(channel),
            'current_broadcast': self._get_current_broadcast(channel),
            'upcoming_schedule': self._get_upcoming_schedule(channel),
            'alerts': self._get_active_alerts(channel),
            'system_metrics': self._get_system_metrics(channel),
        }

    def _get_analysis_date_range(self, request: HttpRequest) -> tuple:
        """
        Get date range for analysis from request parameters.
        
        Args:
            request: HTTP request object
            
        Returns:
            tuple: (date_from, date_to)
        """
        date_range = request.GET.get('date_range', 'last_7_days')
        date_from_str = request.GET.get('date_from')
        date_to_str = request.GET.get('date_to')
        
        today = timezone.now().date()
        
        # Handle custom date range
        if date_from_str and date_to_str:
            try:
                date_from = datetime.datetime.strptime(date_from_str, '%Y-%m-%d').date()
                date_to = datetime.datetime.strptime(date_to_str, '%Y-%m-%d').date()
                return (date_from, date_to)
            except ValueError:
                pass
        
        # Handle predefined ranges
        if date_range == 'today':
            return (today, today)
        elif date_range == 'yesterday':
            yesterday = today - datetime.timedelta(days=1)
            return (yesterday, yesterday)
        elif date_range == 'last_7_days':
            return (today - datetime.timedelta(days=7), today)
        elif date_range == 'last_30_days':
            return (today - datetime.timedelta(days=30), today)
        elif date_range == 'this_month':
            month_start = today.replace(day=1)
            return (month_start, today)
        elif date_range == 'last_month':
            last_month_end = today.replace(day=1) - datetime.timedelta(days=1)
            last_month_start = last_month_end.replace(day=1)
            return (last_month_start, last_month_end)
        
        # Default to last 7 days
        return (today - datetime.timedelta(days=7), today)

    def _handle_ajax_request(self, request: HttpRequest, channel_id: int) -> JsonResponse:
        """
        Handle AJAX requests for dynamic updates.
        
        Args:
            request: Django HTTP request object
            channel_id: Channel ID
            
        Returns:
            JsonResponse: JSON response with requested data
        """
        channel = self._get_channel_with_permissions(request, channel_id)
        action = request.GET.get('action')
        
        if action == 'get_health_status':
            return self._get_health_status_ajax(request, channel)
        elif action == 'get_analytics_data':
            return self._get_analytics_data_ajax(request, channel)
        elif action == 'get_live_stats':
            return self._get_live_stats_ajax(request, channel)
        elif action == 'get_recent_activity':
            return self._get_recent_activity_ajax(request, channel)
        elif action == 'refresh_monitoring':
            return self._refresh_monitoring_ajax(request, channel)
        
        return JsonResponse({'success': False, 'error': 'Invalid action'})

    def _get_health_status_ajax(self, request: HttpRequest, channel) -> JsonResponse:
        """
        Get health status via AJAX.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Health status data
        """
        health_data = self._get_health_status(channel)
        
        return JsonResponse({
            'success': True,
            'health_status': health_data
        })

    def _get_analytics_data_ajax(self, request: HttpRequest, channel) -> JsonResponse:
        """
        Get analytics data via AJAX for dynamic chart updates.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Analytics data
        """
        analytics_data = self._get_channel_analytics(channel, request)
        
        return JsonResponse({
            'success': True,
            'analytics': analytics_data
        })

    def _get_live_stats_ajax(self, request: HttpRequest, channel) -> JsonResponse:
        """
        Get live statistics via AJAX.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Live statistics
        """
        stats = self._get_channel_statistics(channel, request)
        monitoring = self._get_monitoring_data(channel)
        
        return JsonResponse({
            'success': True,
            'live_stats': {
                'current_viewers': monitoring.get('live_status', {}).get('viewers', 0),
                'adbreaks_today': stats.get('today_adbreaks', 0),
                'uptime_percentage': stats.get('uptime_percentage', 100),
                'signal_quality': monitoring.get('system_metrics', {}).get('signal_strength', 'Good'),
            }
        })

    def _get_recent_activity_ajax(self, request: HttpRequest, channel) -> JsonResponse:
        """
        Get recent activity via AJAX.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Recent activity data
        """
        recent_adbreaks = self._get_recent_adbreaks(channel, 5)
        recent_jingles = self._get_recent_jingles(channel, 3)
        
        # Convert to serializable format
        adbreaks_data = []
        for adbreak in recent_adbreaks:
            adbreaks_data.append({
                'id': adbreak.id,
                'start_time': adbreak.start_time.isoformat() if adbreak.start_time else None,
                'duration': float(adbreak.duration) if adbreak.duration else 0,
                'campaign_name': getattr(adbreak.campaign, 'name', '') if hasattr(adbreak, 'campaign') else '',
            })
        
        jingles_data = []
        for jingle in recent_jingles:
            jingles_data.append({
                'id': jingle.id,
                'name': getattr(jingle, 'name', ''),
                'duration': float(getattr(jingle, 'duration', 0)),
                'created_at': jingle.created_at.isoformat() if hasattr(jingle, 'created_at') else '',
            })
        
        return JsonResponse({
            'success': True,
            'recent_activity': {
                'adbreaks': adbreaks_data,
                'jingles': jingles_data,
            }
        })

    def _refresh_monitoring_ajax(self, request: HttpRequest, channel) -> JsonResponse:
        """
        Refresh monitoring data via AJAX.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Updated monitoring data
        """
        # Clear cache to force fresh data
        cache_key = f"channel_health_{channel.id}"
        cache.delete(cache_key)
        
        # Get fresh monitoring data
        health_status = self._get_health_status(channel)
        monitoring_data = self._get_monitoring_data(channel)
        
        return JsonResponse({
            'success': True,
            'health_status': health_status,
            'monitoring_data': monitoring_data,
            'last_updated': timezone.now().isoformat()
        })

    # Helper methods for calculations and data processing
    def _calculate_adbreaks_per_day(self, channel, date_from, date_to):
        """Calculate average adbreaks per day in the given period."""
        total_days = (date_to - date_from).days + 1
        total_adbreaks = Adbreak.objects.filter(
            channel=channel,
            date__range=[date_from, date_to]
        ).count()
        return round(total_adbreaks / total_days, 2) if total_days > 0 else 0

    def _get_peak_hours(self, channel, date_from, date_to):
        """Get peak hours for adbreaks."""
        # This would analyze adbreak start times to find peak hours
        # Placeholder implementation
        return ['18:00-19:00', '20:00-21:00', '21:00-22:00']

    def _get_zone_distribution(self, channel):
        """Get distribution of adbreaks across zones."""
        return channel.zones.annotate(
            adbreak_count=Count('adbreaks')
        ).values('name', 'adbreak_count')

    def _calculate_uptime(self, channel):
        """Calculate channel uptime percentage."""
        # Placeholder implementation - would calculate based on health checks
        return 99.5

    def _calculate_error_rate(self, channel):
        """Calculate error rate percentage."""
        # Placeholder implementation - would calculate based on error logs
        return 0.02

    def _determine_health_status(self, channel):
        """Determine overall health status of the channel."""
        # Placeholder implementation - would check various health indicators
        return 'healthy'  # healthy, warning, critical

    def _get_signal_strength(self, channel):
        """Get current signal strength."""
        # Placeholder implementation
        return 95  # Percentage

    def _check_connectivity(self, channel):
        """Check channel connectivity status."""
        # Placeholder implementation
        return True

    def _get_disk_usage(self, channel):
        """Get disk usage percentage."""
        # Placeholder implementation
        return 45

    def _get_memory_usage(self, channel):
        """Get memory usage percentage."""
        # Placeholder implementation
        return 72

    def _get_cpu_usage(self, channel):
        """Get CPU usage percentage."""
        # Placeholder implementation
        return 35

    def _get_health_warnings(self, channel):
        """Get current health warnings."""
        # Placeholder implementation
        return []

    def _get_health_recommendations(self, channel):
        """Get health recommendations."""
        # Placeholder implementation
        return []

    def _get_live_status(self, channel):
        """Get live broadcasting status."""
        # Placeholder implementation
        return {'is_live': True, 'viewers': 1250}

    def _get_current_broadcast(self, channel):
        """Get current broadcast information."""
        # Placeholder implementation
        return {'program': 'News Hour', 'started_at': timezone.now()}

    def _get_upcoming_schedule(self, channel):
        """Get upcoming broadcast schedule."""
        # Placeholder implementation
        return []

    def _get_active_alerts(self, channel):
        """Get active alerts for the channel."""
        # Placeholder implementation
        return []

    def _get_system_metrics(self, channel):
        """Get system metrics."""
        # Placeholder implementation
        return {'signal_strength': 'Good', 'temperature': 'Normal'}

    def _get_daily_adbreaks_data(self, channel, date_from, date_to):
        """Get daily adbreaks data for charts."""
        # This would return data for charts showing daily adbreak counts
        # Placeholder implementation
        return []

    def _get_hourly_distribution(self, channel, date_from, date_to):
        """Get hourly distribution data."""
        # Placeholder implementation
        return []

    def _get_zone_performance_data(self, channel, date_from, date_to):
        """Get zone performance data."""
        # Placeholder implementation
        return []

    def _get_duration_trends(self, channel, date_from, date_to):
        """Get duration trends data."""
        # Placeholder implementation
        return []

    def _get_comparison_data(self, channel, date_from, date_to):
        """Get comparison data with previous periods."""
        # Placeholder implementation
        return []

    def _get_signal_quality(self, channel):
        """Get signal quality metrics."""
        # Placeholder implementation
        return {'strength': 95, 'stability': 98, 'clarity': 97}

    def _get_transmission_stats(self, channel):
        """Get transmission statistics."""
        # Placeholder implementation
        return {'packets_sent': 1000000, 'packets_lost': 50, 'latency': 25}

    def _get_recent_errors(self, channel):
        """Get recent error logs."""
        # Placeholder implementation
        return []

    def _get_maintenance_schedule(self, channel):
        """Get maintenance schedule."""
        # Placeholder implementation
        return []

    def _get_date_range_options(self):
        """Get date range options for filtering."""
        return [
            {'value': 'today', 'label': 'Today'},
            {'value': 'yesterday', 'label': 'Yesterday'},
            {'value': 'last_7_days', 'label': 'Last 7 Days'},
            {'value': 'last_30_days', 'label': 'Last 30 Days'},
            {'value': 'this_month', 'label': 'This Month'},
            {'value': 'last_month', 'label': 'Last Month'},
            {'value': 'custom', 'label': 'Custom Range'},
        ]

    def _get_export_options(self):
        """Get export format options."""
        return [
            {'value': 'pdf', 'label': 'PDF Report'},
            {'value': 'csv', 'label': 'CSV Data'},
            {'value': 'json', 'label': 'JSON Data'},
            {'value': 'excel', 'label': 'Excel Spreadsheet'},
        ]

    def _get_chart_configurations(self):
        """Get chart configuration settings."""
        return {
            'colors': ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6'],
            'theme': 'light',
            'animation': True,
            'responsive': True,
        }

    def _get_tab_configurations(self):
        """Get tab configuration settings."""
        return [
            {'id': 'overview', 'label': 'Overview', 'icon': 'chart-bar'},
            {'id': 'analytics', 'label': 'Analytics', 'icon': 'trending-up'},
            {'id': 'zones', 'label': 'Zones', 'icon': 'map'},
            {'id': 'adbreaks', 'label': 'Adbreaks', 'icon': 'play'},
            {'id': 'jingles', 'label': 'Jingles', 'icon': 'music'},
            {'id': 'health', 'label': 'Health', 'icon': 'heart'},
        ]

    def _get_breadcrumbs(self, channel):
        """Get breadcrumb navigation."""
        return [
            {'label': 'Dashboard', 'url': '/dashboard/'},
            {'label': 'Channels', 'url': '/channels/'},
            {'label': channel.name, 'url': None, 'active': True},
        ]

    def _log_user_activity(self, request: HttpRequest, channel) -> None:
        """
        Log user activity for auditing purposes.
        
        Args:
            request (HttpRequest): The HTTP request object
            channel: Channel object
            
        Returns:
            None
        """
        user = request.user
        
        Activity.log_activity(
            user=user,
            action="view_channel_detail",
            description=f"User {user.email if user else 'System'} viewed channel {channel.name} details",
            request=request,
            ip_address=get_client_ip(request),
            user_agent=request.META.get("HTTP_USER_AGENT", ""),
            metadata={
                'channel_id': str(channel.id),
                'channel_name': channel.name,
                'active_tab': request.GET.get('tab', 'overview'),
                'date_range': request.GET.get('date_range', 'last_7_days'),
            }
        )


class ChannelCreateView(LoginRequiredMixin, View):
    """View for creating new channels.
    
    Handles both GET requests to display the creation form and POST requests
    to process form submission and create new channel instances.
    
    Methods:
        get: Display channel creation form
        post: Process form submission and create channel
        
    Template: channels/channel_form.html
    """
    
    def get(self, request: HttpRequest) -> HttpResponse:
        """Display channel creation form.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with empty form
        """
        context = {
            'channel_types': Channel.CHANNEL_TYPES,
            'status_choices': Channel.STATUS_CHOICES,
            'form_title': 'Create New Channel',
            'submit_text': 'Create Channel',
        }
        return render(request, 'channels/channel/form.html', context)
    
    def post(self, request: HttpRequest) -> HttpResponse:
        """Process channel creation form submission.
        
        Args:
            request: HTTP request object with form data
            
        Returns:
            HttpResponse: Redirect to channel detail on success, or form with errors
        """
        try:
            # Extract form data
            name = request.POST.get('name', '').strip()
            logo = request.FILES.get('logo')
            display_name = request.POST.get('display_name', '').strip()
            channel_number = request.POST.get('channel_number')
            channel_type = request.POST.get('channel_type')
            status = request.POST.get('status', 'inactive')
            description = request.POST.get('description', '').strip()
            website = request.POST.get('website', '').strip()
            language = request.POST.get('language', '').strip()
            category = request.POST.get('category', '').strip()
            target_audience = request.POST.get('target_audience', '').strip()
            supports_dai = request.POST.get('supports_dai') == 'on' 
            
            # Validate required fields
            if not name:
                messages.error(request, 'Channel name is required.')
                return self.get(request)
                
            if not display_name:
                display_name = name
                
            # Create channel
            channel = Channel.objects.create(
                name=name,
                logo=logo,
                display_name=display_name,
                channel_number=int(channel_number) if channel_number else None,
                channel_type=channel_type,
                status=status,
                description=description,
                website=website,
                language=language,
                category=category,
                target_audience=target_audience,
                supports_dai=supports_dai, 
            )
            
            messages.success(request, f'Channel "{channel.display_name}" created successfully.')
            return redirect('channels:channel_detail', channel_id=channel.pk)
            
        except ValidationError as e:
            messages.error(request, f'Validation error: {e}')
            return self.get(request)
        except Exception as e:
            messages.error(request, f'Error creating channel: {e}')
            return self.get(request)


class ChannelUpdateView(LoginRequiredMixin, View):
    """View for updating existing channels.
    
    Handles both GET requests to display the update form pre-filled with
    current channel data and POST requests to process updates.
    
    Methods:
        get: Display channel update form
        post: Process form submission and update channel
        
    Template: channels/channel_form.html
    """
    
    def get(self, request: HttpRequest, channel_id: int) -> HttpResponse:
        """Display channel update form.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of channel to update
            
        Returns:
            HttpResponse: Rendered template with pre-filled form
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        context = {
            'channel': channel,
            'channel_types': Channel.CHANNEL_TYPES,
            'status_choices': Channel.STATUS_CHOICES,
            'form_title': f'Update Channel: {channel.display_name}',
            'submit_text': 'Update Channel',
        }
        return render(request, 'channels/channel/form.html', context)
    
    def post(self, request: HttpRequest, channel_id: int) -> HttpResponse:
        """Process channel update form submission.
        
        Args:
            request: HTTP request object with form data
            channel_id: Primary key of channel to update
            
        Returns:
            HttpResponse: Redirect to channel detail on success, or form with errors
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        try:
            # Update channel fields
            channel.name = request.POST.get('name', '').strip() or channel.name
            channel.display_name = request.POST.get('display_name', '').strip() or channel.display_name
            
            channel_number = request.POST.get('channel_number')
            if channel_number:
                channel.channel_number = int(channel_number)
                
            channel.channel_type = request.POST.get('channel_type') or channel.channel_type
            channel.status = request.POST.get('status') or channel.status
            channel.description = request.POST.get('description', '').strip()
            channel.website = request.POST.get('website', '').strip()
            channel.language = request.POST.get('language', '').strip()
            channel.category = request.POST.get('category', '').strip()
            channel.target_audience = request.POST.get('target_audience', '').strip()
            channel.supports_dai = request.POST.get('supports_dai') == 'on'
            
            max_ad_duration = request.POST.get('max_ad_duration')
            if max_ad_duration:
                channel.max_ad_duration = int(max_ad_duration)
                
            min_ad_gap = request.POST.get('min_ad_gap')
            if min_ad_gap:
                channel.min_ad_gap = int(min_ad_gap)
            
            channel.save()
            
            messages.success(request, f'Channel "{channel.display_name}" updated successfully.')
            return redirect('channels:channel_detail', channel_id=channel.pk)
            
        except ValidationError as e:
            messages.error(request, f'Validation error: {e}')
            return self.get(request, channel_id)
        except Exception as e:
            messages.error(request, f'Error updating channel: {e}')
            return self.get(request, channel_id)


class ChannelDeleteView(View):
    """View for deleting channels.
    
    Handles both GET requests to display confirmation page and POST requests
    to perform the actual deletion.
    
    Methods:
        get: Display deletion confirmation
        post: Process deletion request
        
    Template: channels/channel_confirm_delete.html
    """
    
    def get(self, request: HttpRequest, channel_id: int) -> HttpResponse:
        """Display channel deletion confirmation.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of channel to delete
            
        Returns:
            HttpResponse: Rendered confirmation template
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        # Get related objects count for warning
        adbreaks_count = Adbreak.objects.filter(channel=channel).count()
        jingles_count = Jingle.objects.filter(channel=channel).count()
        
        context = {
            'channel': channel,
            'adbreaks_count': adbreaks_count,
            'jingles_count': jingles_count,
        }
        return render(request, 'channels/channel/confirm_delete.html', context)
    
    def post(self, request: HttpRequest, channel_id: int) -> HttpResponse:
        """Process channel deletion request.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of channel to delete
            
        Returns:
            HttpResponse: Redirect to channel list after deletion
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        channel_name = channel.display_name
        
        try:
            channel.delete()
            messages.success(request, f'Channel "{channel_name}" deleted successfully.')
        except Exception as e:
            messages.error(request, f'Error deleting channel: {e}')
            
        return redirect('channels:channel_list')


class JingleListView(View):
    """View for displaying a list of jingles for a specific channel.
    
    Shows paginated jingles with filtering options by type and placement.
    
    Methods:
        get: Handle GET requests to display jingle list
        
    Template: channels/jingle_list.html
    """
    
    def get(self, request: HttpRequest, channel_id: int) -> HttpResponse:
        """Handle GET request to display jingle list.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            HttpResponse: Rendered template with jingle list
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        # Get query parameters
        jingle_type = request.GET.get('type', '')
        placement = request.GET.get('placement', '')
        page = request.GET.get('page', 1)
        per_page = int(request.GET.get('per_page', 20))
        
        # Build queryset
        jingles = Jingle.objects.filter(channel=channel)
        
        if jingle_type:
            jingles = jingles.filter(type=jingle_type)
            
        if placement:
            jingles = jingles.filter(placement=placement)
            
        jingles = jingles.order_by('-created_at')
        
        # Pagination
        paginator = Paginator(jingles, per_page)
        try:
            jingles_page = paginator.page(page)
        except PageNotAnInteger:
            jingles_page = paginator.page(1)
        except EmptyPage:
            jingles_page = paginator.page(paginator.num_pages)
            
        context = {
            'channel': channel,
            'jingles': jingles_page,
            'jingle_types': Jingle.JINGLE_TYPES,
            'PLACEMENT_TYPES': Jingle.PLACEMENT_TYPES,
            'selected_type': jingle_type,
            'selected_placement': placement,
            'total_jingles': paginator.count,
        }
        
        return render(request, 'channels/jingle/list.html', context)


class AdbreakListView(View):
    """View for displaying adbreaks for a specific channel.
    
    Shows paginated adbreaks with filtering by date range, type, and category.
    
    Methods:
        get: Handle GET requests to display adbreak list
        
    Template: channels/adbreak_list.html
    """
    
    def get(self, request: HttpRequest, channel_id: int) -> HttpResponse:
        """Handle GET request to display adbreak list.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            HttpResponse: Rendered template with adbreak list
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        # Get query parameters
        start_date = request.GET.get('start_date')
        end_date = request.GET.get('end_date')
        adbreak_type = request.GET.get('type', '')
        category = request.GET.get('category', '')
        page = request.GET.get('page', 1)
        per_page = int(request.GET.get('per_page', 50))
        
        # Default date range (last 7 days)
        if not start_date:
            start_date = (timezone.now().date() - datetime.timedelta(days=7)).isoformat()
        if not end_date:
            end_date = timezone.now().date().isoformat()
            
        # Build queryset
        adbreaks = Adbreak.objects.filter(
            channel=channel,
            date__gte=start_date,
            date__lte=end_date
        )
        
        if adbreak_type:
            adbreaks = adbreaks.filter(type=adbreak_type)
            
        if category:
            adbreaks = adbreaks.filter(category=category)
            
        adbreaks = adbreaks.order_by('-date', '-start_time')
        
        # Pagination
        paginator = Paginator(adbreaks, per_page)
        try:
            adbreaks_page = paginator.page(page)
        except PageNotAnInteger:
            adbreaks_page = paginator.page(1)
        except EmptyPage:
            adbreaks_page = paginator.page(paginator.num_pages)
            
        context = {
            'channel': channel,
            'adbreaks': adbreaks_page,
            'adbreak_types': Adbreak.ADBREAK_TYPE_CHOICES,
            'category_choices': Adbreak.CATEGORY_CHOICES,
            'start_date': start_date,
            'end_date': end_date,
            'selected_type': adbreak_type,
            'selected_category': category,
            'total_adbreaks': paginator.count,
        }
        
        return render(request, 'channels/adbreak/list.html', context)


class ChannelHealthView(View):
    """View for monitoring channel health status.
    
    Displays real-time health information and recent health check history.
    
    Methods:
        get: Display channel health dashboard
        post: Trigger manual health check
        
    Template: channels/channel_health.html
    """
    
    def get(self, request: HttpRequest, channel_id: int) -> HttpResponse:
        """Display channel health dashboard.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            HttpResponse: Rendered template with health information
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        # Calculate health metrics
        now = timezone.now()
        last_24h = now - datetime.timedelta(hours=24)
        
        recent_adbreaks = Adbreak.objects.filter(
            channel=channel,
            date__gte=last_24h.date()
        ).count()
        
        # Health status based on last check time
        health_status = 'unknown'
        if channel.last_health_check:
            time_since_check = now - channel.last_health_check
            if time_since_check < datetime.timedelta(minutes=5):
                health_status = 'healthy' if channel.is_online else 'offline'
            elif time_since_check < datetime.timedelta(minutes=15):
                health_status = 'warning'
            else:
                health_status = 'critical'
                
        context = {
            'channel': channel,
            'health_status': health_status,
            'recent_adbreaks': recent_adbreaks,
            'last_check': channel.last_health_check,
            'is_online': channel.is_online,
        }
        
        return render(request, 'channels/channel/health.html', context)
    
    def post(self, request: HttpRequest, channel_id: int) -> JsonResponse:
        """Trigger manual health check for the channel.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: Health check results
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        try:
            # Perform health check (this would typically call external services)
            health_result = channel.check_health()
            
            return JsonResponse({
                'success': True,
                'status': 'healthy' if health_result else 'offline',
                'timestamp': timezone.now().isoformat(),
                'message': 'Health check completed successfully'
            })
            
        except Exception as e:
            return JsonResponse({
                'success': False,
                'error': str(e),
                'timestamp': timezone.now().isoformat()
            }, status=500)


# API Views for AJAX/JSON responses

@method_decorator(csrf_exempt, name='dispatch')
class ChannelAPIView(View):
    """RESTful API view for channel operations.
    
    Provides JSON API endpoints for channel CRUD operations.
    Supports GET (list/detail), POST (create), PUT (update), DELETE operations.
    
    Methods:
        get: Retrieve channel(s) as JSON
        post: Create new channel via JSON
        put: Update existing channel via JSON
        delete: Delete channel via JSON
    """
    
    def get(self, request: HttpRequest, channel_id: Optional[int] = None) -> JsonResponse:
        """Retrieve channel(s) as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Optional channel ID for single channel retrieval
            
        Returns:
            JsonResponse: Channel data or list of channels
        """
        try:
            if channel_id:
                # Single channel detail
                channel = get_object_or_404(Channel, pk=channel_id)
                data = {
                    'id': channel.id,
                    'name': channel.name,
                    'display_name': channel.display_name,
                    'channel_number': channel.channel_number,
                    'channel_type': channel.channel_type,
                    'status': channel.status,
                    'description': channel.description,
                    'website': channel.website,
                    'language': channel.language,
                    'category': channel.category,
                    'target_audience': channel.target_audience,
                    'supports_dai': channel.supports_dai,
                    'max_ad_duration': channel.max_ad_duration,
                    'min_ad_gap': channel.min_ad_gap,
                    'is_online': channel.is_online,
                    'last_health_check': channel.last_health_check.isoformat() if channel.last_health_check else None,
                    'created_at': channel.created_at.isoformat(),
                    'updated_at': channel.updated_at.isoformat(),
                }
                return JsonResponse(data)
            else:
                # Channel list
                channels = Channel.objects.all().order_by('name')
                
                # Apply filters
                search = request.GET.get('search')
                if search:
                    channels = channels.filter(
                        Q(name__icontains=search) |
                        Q(display_name__icontains=search)
                    )
                    
                channel_type = request.GET.get('type')
                if channel_type:
                    channels = channels.filter(channel_type=channel_type)
                    
                # Pagination
                page = int(request.GET.get('page', 1))
                per_page = int(request.GET.get('per_page', 20))
                
                paginator = Paginator(channels, per_page)
                channels_page = paginator.page(page)
                
                data = {
                    'channels': [
                        {
                            'id': channel.id,
                            'name': channel.name,
                            'display_name': channel.display_name,
                            'channel_number': channel.channel_number,
                            'channel_type': channel.channel_type,
                            'status': channel.status,
                            'is_online': channel.is_online,
                        }
                        for channel in channels_page
                    ],
                    'pagination': {
                        'page': page,
                        'per_page': per_page,
                        'total': paginator.count,
                        'pages': paginator.num_pages,
                        'has_next': channels_page.has_next(),
                        'has_previous': channels_page.has_previous(),
                    }
                }
                return JsonResponse(data)
                
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class JingleAPIListView(View):
    """API view for listing all jingles.
    
    Provides JSON endpoint for retrieving all jingles with optional filtering.
    
    Methods:
        get: Retrieve all jingles as JSON
    """
    
    def get(self, request: HttpRequest) -> JsonResponse:
        """Retrieve all jingles as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: List of all jingles
        """
        try:
            jingle_type = request.GET.get('type')
            placement = request.GET.get('placement')
            channel_id = request.GET.get('channel')
            
            jingles = Jingle.objects.all()
            
            if jingle_type:
                jingles = jingles.filter(type=jingle_type)
                
            if placement:
                jingles = jingles.filter(placement=placement)
                
            if channel_id:
                jingles = jingles.filter(channel_id=channel_id)
                
            jingles = jingles.order_by('-created_at')
            
            # Pagination
            page = int(request.GET.get('page', 1))
            per_page = int(request.GET.get('per_page', 20))
            
            paginator = Paginator(jingles, per_page)
            jingles_page = paginator.page(page)
            
            data = {
                'jingles': [
                    {
                        'id': str(jingle.id),
                        'name': jingle.name,
                        'type': jingle.type,
                        'placement': jingle.placement,
                        'duration': jingle.duration,
                        'channel': {
                            'id': str(jingle.channel.id),
                            'name': jingle.channel.name,
                            'display_name': jingle.channel.display_name,
                        },
                        'created_at': jingle.created_at.isoformat(),
                    }
                    for jingle in jingles_page
                ],
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total_pages': paginator.num_pages,
                    'total_count': paginator.count,
                    'has_next': jingles_page.has_next(),
                    'has_previous': jingles_page.has_previous(),
                }
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class ChannelJinglesAPIView(View):
    """API view for retrieving jingles for a specific channel.
    
    Provides JSON endpoint for getting all jingles associated with a channel.
    
    Methods:
        get: Retrieve jingles for a channel as JSON
    """
    
    def get(self, request: HttpRequest, channel_id: str) -> JsonResponse:
        """Retrieve jingles for a channel as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: List of jingles for the channel
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        try:
            channel = get_object_or_404(Channel, pk=channel_id)
            
            jingles = Jingle.objects.filter(channel=channel)
            
            # Apply filters
            jingle_type = request.GET.get('type')
            if jingle_type:
                jingles = jingles.filter(type=jingle_type)
                
            placement = request.GET.get('placement')
            if placement:
                jingles = jingles.filter(placement=placement)
                
            jingles = jingles.order_by('-created_at')
            
            data = {
                'channel': {
                    'id': str(channel.id),
                    'name': channel.name,
                    'display_name': channel.display_name,
                },
                'jingles': [
                    {
                        'id': str(jingle.id),
                        'name': jingle.name,
                        'type': jingle.type,
                        'placement': jingle.placement,
                        'duration': jingle.duration,
                        'file_path': jingle.file_path,
                        'created_at': jingle.created_at.isoformat(),
                    }
                    for jingle in jingles
                ],
                'total_jingles': jingles.count(),
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class AdbreakAPIListView(View):
    """API view for listing all adbreaks.
    
    Provides JSON endpoint for retrieving all adbreaks with optional filtering.
    
    Methods:
        get: Retrieve all adbreaks as JSON
    """
    
    def get(self, request: HttpRequest) -> JsonResponse:
        """Retrieve all adbreaks as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: List of all adbreaks
        """
        try:
            # Date range filtering
            start_date = request.GET.get('start_date')
            end_date = request.GET.get('end_date')
            channel_id = request.GET.get('channel')
            adbreak_type = request.GET.get('type')
            category = request.GET.get('category')
            
            if not start_date:
                start_date = (timezone.now().date() - datetime.timedelta(days=7)).isoformat()
            if not end_date:
                end_date = timezone.now().date().isoformat()
                
            adbreaks = Adbreak.objects.filter(
                date__gte=start_date,
                date__lte=end_date
            )
            
            if channel_id:
                adbreaks = adbreaks.filter(channel_id=channel_id)
                
            if adbreak_type:
                adbreaks = adbreaks.filter(type=adbreak_type)
                
            if category:
                adbreaks = adbreaks.filter(category=category)
                
            adbreaks = adbreaks.order_by('-date', '-start_time')
            
            # Pagination
            page = int(request.GET.get('page', 1))
            per_page = int(request.GET.get('per_page', 50))
            
            paginator = Paginator(adbreaks, per_page)
            adbreaks_page = paginator.page(page)
            
            data = {
                'adbreaks': [
                    {
                        'id': str(adbreak.id),
                        'date': adbreak.date.isoformat(),
                        'start_time': adbreak.start_time.isoformat(),
                        'end_time': adbreak.end_time.isoformat() if adbreak.end_time else None,
                        'duration': adbreak.duration,
                        'type': adbreak.type,
                        'category': adbreak.category,
                        'channel': {
                            'id': str(adbreak.channel.id),
                            'name': adbreak.channel.name,
                            'display_name': adbreak.channel.display_name,
                        },
                    }
                    for adbreak in adbreaks_page
                ],
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total_pages': paginator.num_pages,
                    'total_count': paginator.count,
                    'has_next': adbreaks_page.has_next(),
                    'has_previous': adbreaks_page.has_previous(),
                },
                'date_range': {
                    'start_date': start_date,
                    'end_date': end_date,
                }
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class ChannelAdbreaksAPIView(View):
    """API view for retrieving adbreaks for a specific channel.
    
    Provides JSON endpoint for getting all adbreaks associated with a channel.
    
    Methods:
        get: Retrieve adbreaks for a channel as JSON
    """
    
    def get(self, request: HttpRequest, channel_id: str) -> JsonResponse:
        """Retrieve adbreaks for a channel as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: List of adbreaks for the channel
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        try:
            channel = get_object_or_404(Channel, pk=channel_id)
            
            # Date range filtering
            start_date = request.GET.get('start_date')
            end_date = request.GET.get('end_date')
            
            if not start_date:
                start_date = (timezone.now().date() - timedelta(days=7)).isoformat()
            if not end_date:
                end_date = timezone.now().date().isoformat()
                
            adbreaks = Adbreak.objects.filter(
                channel=channel,
                date__gte=start_date,
                date__lte=end_date
            )
            
            # Apply additional filters
            adbreak_type = request.GET.get('type')
            if adbreak_type:
                adbreaks = adbreaks.filter(type=adbreak_type)
                
            category = request.GET.get('category')
            if category:
                adbreaks = adbreaks.filter(category=category)
                
            adbreaks = adbreaks.order_by('-date', '-start_time')
            
            # Calculate statistics
            total_duration = sum(ab.duration or 0 for ab in adbreaks)
            avg_duration = total_duration / len(adbreaks) if adbreaks else 0
            
            data = {
                'channel': {
                    'id': str(channel.id),
                    'name': channel.name,
                    'display_name': channel.display_name,
                },
                'adbreaks': [
                    {
                        'id': str(adbreak.id),
                        'date': adbreak.date.isoformat(),
                        'start_time': adbreak.start_time.isoformat(),
                        'end_time': adbreak.end_time.isoformat() if adbreak.end_time else None,
                        'duration': adbreak.duration,
                        'type': adbreak.type,
                        'category': adbreak.category,
                    }
                    for adbreak in adbreaks
                ],
                'statistics': {
                    'total_adbreaks': adbreaks.count(),
                    'total_duration': round(total_duration, 2),
                    'average_duration': round(avg_duration, 2),
                },
                'date_range': {
                    'start_date': start_date,
                    'end_date': end_date,
                }
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class ChannelHealthAPIView(View):
    """API view for channel health monitoring.
    
    Provides JSON endpoint for retrieving health status of all channels.
    
    Methods:
        get: Retrieve channel health data as JSON
    """
    
    def get(self, request: HttpRequest) -> JsonResponse:
        """Retrieve channel health data as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: Health status of all channels
        """
        try:
            channels = Channel.objects.all().order_by('name')
            
            # Filter by status if provided
            status_filter = request.GET.get('status')
            if status_filter:
                channels = channels.filter(status=status_filter)
                
            # Filter by online status
            online_filter = request.GET.get('online')
            if online_filter is not None:
                is_online = online_filter.lower() == 'true'
                channels = channels.filter(is_online=is_online)
                
            health_data = []
            for channel in channels:
                # Calculate health status
                last_check = channel.last_health_check
                if last_check:
                    time_since_check = timezone.now() - last_check
                    health_status = 'healthy' if time_since_check.total_seconds() < 300 else 'warning'
                    if time_since_check.total_seconds() > 600:
                        health_status = 'critical'
                else:
                    health_status = 'unknown'
                    
                health_data.append({
                    'id': str(channel.id),
                    'name': channel.name,
                    'display_name': channel.display_name,
                    'status': channel.status,
                    'is_online': channel.is_online,
                    'health_status': health_status,
                    'last_health_check': last_check.isoformat() if last_check else None,
                    'uptime_percentage': 95.5,  # This would be calculated from actual data
                })
                
            # Summary statistics
            total_channels = len(health_data)
            online_channels = sum(1 for ch in health_data if ch['is_online'])
            healthy_channels = sum(1 for ch in health_data if ch['health_status'] == 'healthy')
            
            data = {
                'channels': health_data,
                'summary': {
                    'total_channels': total_channels,
                    'online_channels': online_channels,
                    'offline_channels': total_channels - online_channels,
                    'healthy_channels': healthy_channels,
                    'unhealthy_channels': total_channels - healthy_channels,
                    'overall_health_percentage': round((healthy_channels / total_channels * 100) if total_channels > 0 else 0, 1),
                },
                'generated_at': timezone.now().isoformat(),
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class ChannelHealthDashboardView(View):
    """View for displaying channel health monitoring dashboard.
    
    Shows comprehensive health status and monitoring information for all channels.
    
    Methods:
        get: Display health dashboard
        
    Template: channels/health_dashboard.html
    """
    
    def get(self, request: HttpRequest) -> HttpResponse:
        """Handle GET request to display health dashboard.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with health dashboard
        """
        channels = Channel.objects.all().order_by('name')
        
        # Calculate health statistics
        total_channels = channels.count()
        online_channels = channels.filter(is_online=True).count()
        offline_channels = total_channels - online_channels
        
        # Health status calculation
        healthy_channels = 0
        warning_channels = 0
        critical_channels = 0
        unknown_channels = 0
        
        for channel in channels:
            last_check = channel.last_health_check
            if last_check:
                time_since_check = timezone.now() - last_check
                if time_since_check.total_seconds() < 300:
                    healthy_channels += 1
                elif time_since_check.total_seconds() < 600:
                    warning_channels += 1
                else:
                    critical_channels += 1
            else:
                unknown_channels += 1
                
        # Recent health events (this would come from a health log model)
        recent_events = [
            {
                'timestamp': timezone.now() - datetime.timedelta(minutes=5),
                'channel': 'Channel 1',
                'event': 'Health check passed',
                'status': 'success'
            },
            {
                'timestamp': timezone.now() - datetime.timedelta(minutes=15),
                'channel': 'Channel 2',
                'event': 'Connection timeout',
                'status': 'warning'
            },
        ]
        
        context = {
            'channels': channels,
            'total_channels': total_channels,
            'online_channels': online_channels,
            'offline_channels': offline_channels,
            'healthy_channels': healthy_channels,
            'warning_channels': warning_channels,
            'critical_channels': critical_channels,
            'unknown_channels': unknown_channels,
            'overall_health_percentage': round((healthy_channels / total_channels * 100) if total_channels > 0 else 0, 1),
            'recent_events': recent_events,
        }
        
        return render(request, 'channels/health_dashboard.html', context)


class ChannelAPIListView(View):
    """API view for listing all channels.
    
    Provides JSON endpoint for retrieving all channels with optional filtering.
    
    Methods:
        get: Retrieve all channels as JSON
    """
    
    def get(self, request: HttpRequest) -> JsonResponse:
        """Retrieve all channels as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: List of all channels
        """
        try:
            search_query = request.GET.get('search', '').strip()
            channel_type = request.GET.get('type')
            status = request.GET.get('status')
            
            channels = Channel.objects.all()
            
            if search_query:
                channels = channels.filter(
                    Q(name__icontains=search_query) |
                    Q(display_name__icontains=search_query)
                )
                
            if channel_type:
                channels = channels.filter(channel_type=channel_type)
                
            if status:
                channels = channels.filter(status=status)
                
            channels = channels.order_by('name')
            
            # Pagination
            page = int(request.GET.get('page', 1))
            per_page = int(request.GET.get('per_page', 20))
            
            paginator = Paginator(channels, per_page)
            channels_page = paginator.page(page)
            
            data = {
                'channels': [
                    {
                        'id': str(channel.id),
                        'name': channel.name,
                        'display_name': channel.display_name,
                        'channel_number': channel.channel_number,
                        'channel_type': channel.channel_type,
                        'status': channel.status,
                        'is_online': channel.is_online,
                        'language': channel.language,
                        'category': channel.category,
                        'last_health_check': channel.last_health_check.isoformat() if channel.last_health_check else None,
                    }
                    for channel in channels_page
                ],
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total_pages': paginator.num_pages,
                    'total_count': paginator.count,
                    'has_next': channels_page.has_next(),
                    'has_previous': channels_page.has_previous(),
                }
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class ChannelAPIDetailView(View):
    """API view for retrieving detailed channel information.
    
    Provides JSON endpoint for getting detailed information about a specific channel.
    
    Methods:
        get: Retrieve channel details as JSON
    """
    
    def get(self, request: HttpRequest, pk: str) -> JsonResponse:
        """Retrieve channel details as JSON.
        
        Args:
            request: HTTP request object
            pk: Primary key of the channel
            
        Returns:
            JsonResponse: Detailed channel information
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        try:
            channel = get_object_or_404(Channel, pk=pk)
            
            # Get related data
            zones = list(channel.zones.values('id', 'name', 'description'))
            recent_adbreaks = Adbreak.objects.filter(channel=channel).order_by('-date', '-start_time')[:5]
            jingles_count = Jingle.objects.filter(channel=channel).count()
            
            data = {
                'id': str(channel.id),
                'name': channel.name,
                'display_name': channel.display_name,
                'channel_number': channel.channel_number,
                'channel_type': channel.channel_type,
                'status': channel.status,
                'is_online': channel.is_online,
                'logo': channel.logo.url if channel.logo else None,
                'description': channel.description,
                'website': channel.website,
                'language': channel.language,
                'category': channel.category,
                'target_audience': channel.target_audience,
                'supports_dai': channel.supports_dai,
                'max_ad_duration': channel.max_ad_duration,
                'min_ad_gap': channel.min_ad_gap,
                'last_health_check': channel.last_health_check.isoformat() if channel.last_health_check else None,
                'created_at': channel.created_at.isoformat(),
                'updated_at': channel.updated_at.isoformat(),
                'zones': zones,
                'jingles_count': jingles_count,
                'recent_adbreaks': [
                    {
                        'id': str(adbreak.id),
                        'date': adbreak.date.isoformat(),
                        'start_time': adbreak.start_time.isoformat(),
                        'duration': adbreak.duration,
                        'type': adbreak.type,
                    }
                    for adbreak in recent_adbreaks
                ],
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class ChannelZoneAPIListView(View):
    """API view for listing all channel zones.
    
    Provides JSON endpoint for retrieving all zones with optional filtering.
    
    Methods:
        get: Retrieve all zones as JSON
    """
    
    def get(self, request: HttpRequest) -> JsonResponse:
        """Retrieve all zones as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: List of all zones
        """
        try:
            search_query = request.GET.get('search', '').strip()
            
            zones = ChannelZone.objects.all()
            
            if search_query:
                zones = zones.filter(
                    Q(name__icontains=search_query) |
                    Q(description__icontains=search_query)
                )
                
            zones = zones.order_by('name')
            
            # Pagination
            page = int(request.GET.get('page', 1))
            per_page = int(request.GET.get('per_page', 20))
            
            paginator = Paginator(zones, per_page)
            zones_page = paginator.page(page)
            
            data = {
                'zones': [
                    {
                        'id': str(zone.id),
                        'name': zone.name,
                        'description': zone.description,
                        'channels_count': zone.channels.count(),
                        'created_at': zone.created_at.isoformat(),
                    }
                    for zone in zones_page
                ],
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total_pages': paginator.num_pages,
                    'total_count': paginator.count,
                    'has_next': zones_page.has_next(),
                    'has_previous': zones_page.has_previous(),
                }
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class ZoneChannelsAPIView(View):
    """API view for retrieving channels in a specific zone.
    
    Provides JSON endpoint for getting all channels associated with a zone.
    
    Methods:
        get: Retrieve channels in a zone as JSON
    """
    
    def get(self, request: HttpRequest, zone_id: str) -> JsonResponse:
        """Retrieve channels in a zone as JSON.
        
        Args:
            request: HTTP request object
            zone_id: Primary key of the zone
            
        Returns:
            JsonResponse: List of channels in the zone
            
        Raises:
            Http404: If zone with given ID doesn't exist
        """
        try:
            zone = get_object_or_404(ChannelZone, pk=zone_id)
            
            channels = Channel.objects.filter(zones=zone).order_by('name')
            
            data = {
                'zone': {
                    'id': str(zone.id),
                    'name': zone.name,
                    'description': zone.description,
                },
                'channels': [
                    {
                        'id': str(channel.id),
                        'name': channel.name,
                        'display_name': channel.display_name,
                        'channel_number': channel.channel_number,
                        'channel_type': channel.channel_type,
                        'status': channel.status,
                        'is_online': channel.is_online,
                    }
                    for channel in channels
                ],
                'total_channels': channels.count(),
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


# ChannelZone Views

class ChannelZoneListView(LoginRequiredMixin, View):
    """Enhanced view for displaying a list of all channel zones.
    
    Features:
    - Advanced filtering by status, timezone, and activity
    - Enhanced search across multiple fields
    - Statistics and analytics
    - Bulk operations support
    - Export functionality
    - AJAX support for dynamic updates
    
    Methods:
        get: Handle GET requests to display zone list
        post: Handle bulk operations
        
    Template: channels/zone/list.html
    """
    
    def get(self, request: HttpRequest) -> HttpResponse:
        """Handle GET request to display enhanced zone list.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with zone list and statistics
        """
        # Get filter parameters
        search_query = request.GET.get('search', '').strip()
        status_filter = request.GET.get('status', '')
        timezone_filter = request.GET.get('timezone', '')
        sort_by = request.GET.get('sort', 'name')
        sort_order = request.GET.get('order', 'asc')
        page = request.GET.get('page', 1)
        per_page = int(request.GET.get('per_page', 20))
        
        # Base queryset with annotations
        zones = ChannelZone.objects.annotate(
            channels_count=Count('channels'),
            active_channels_count=Count('channels', filter=Q(channels__status='active')),
            relations_count=Count('channel_relations')
        )
        
        # Apply filters
        if search_query:
            zones = zones.filter(
                Q(name__icontains=search_query) |
                Q(code__icontains=search_query) |
                Q(description__icontains=search_query) |
                Q(timezone__icontains=search_query)
            )
            
        if status_filter:
            if status_filter == 'active':
                zones = zones.filter(is_active=True)
            elif status_filter == 'inactive':
                zones = zones.filter(is_active=False)
                
        if timezone_filter:
            zones = zones.filter(timezone__icontains=timezone_filter)
        
        # Apply sorting
        valid_sort_fields = ['name', 'code', 'timezone', 'channels_count', 'created_at']
        if sort_by in valid_sort_fields:
            if sort_order == 'desc':
                sort_by = f'-{sort_by}'
            zones = zones.order_by(sort_by)
        else:
            zones = zones.order_by('name')
        
        # Calculate statistics
        total_zones = zones.count()
        active_zones = zones.filter(is_active=True).count()
        inactive_zones = zones.filter(is_active=False).count()
        
        # Get unique timezones for filter dropdown
        available_timezones = ChannelZone.objects.values_list('timezone', flat=True).distinct().order_by('timezone')
        
        # Pagination
        paginator = Paginator(zones, per_page)
        try:
            zones_page = paginator.page(page)
        except PageNotAnInteger:
            zones_page = paginator.page(1)
        except EmptyPage:
            zones_page = paginator.page(paginator.num_pages)
            
        context = {
            'zones': zones_page,
            'search_query': search_query,
            'status_filter': status_filter,
            'timezone_filter': timezone_filter,
            'sort_by': sort_by.lstrip('-'),
            'sort_order': sort_order,
            'per_page': per_page,
            'total_zones': total_zones,
            'active_zones': active_zones,
            'inactive_zones': inactive_zones,
            'available_timezones': available_timezones,
        }
        
        # AJAX response for dynamic updates
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({
                'html': render(request, 'channels/zone/list_partial.html', context).content.decode(),
                'total_zones': total_zones,
                'active_zones': active_zones,
                'inactive_zones': inactive_zones,
            })
        
        return render(request, 'channels/zone/list.html', context)
    
    def post(self, request: HttpRequest) -> HttpResponse:
        """Handle bulk operations on zones.
        
        Args:
            request: HTTP request object with bulk operation data
            
        Returns:
            JsonResponse: Result of bulk operation
        """
        action = request.POST.get('action')
        zone_ids = request.POST.getlist('zone_ids')
        
        if not zone_ids:
            return JsonResponse({'success': False, 'message': 'No zones selected.'})
        
        try:
            zones = ChannelZone.objects.filter(id__in=zone_ids)
            
            if action == 'activate':
                updated = zones.update(is_active=True)
                messages.success(request, f'{updated} zones activated successfully.')
                
            elif action == 'deactivate':
                updated = zones.update(is_active=False)
                messages.success(request, f'{updated} zones deactivated successfully.')
                
            elif action == 'delete':
                # Check for dependencies
                zones_with_channels = zones.filter(channels__isnull=False).distinct()
                if zones_with_channels.exists():
                    return JsonResponse({
                        'success': False,
                        'message': 'Cannot delete zones that have associated channels.'
                    })
                
                deleted_count = zones.count()
                zones.delete()
                messages.success(request, f'{deleted_count} zones deleted successfully.')
                
            else:
                return JsonResponse({'success': False, 'message': 'Invalid action.'})
            
            return JsonResponse({'success': True, 'message': 'Operation completed successfully.'})
            
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'Error: {str(e)}'})


class ChannelZoneDetailView(LoginRequiredMixin, View):
    """Enhanced view for displaying detailed information about a specific channel zone.
    
    Features:
    - Comprehensive zone information and statistics
    - Associated channels with filtering and pagination
    - Zone-specific configurations and relationships
    - Health monitoring and status tracking
    - Export and reporting capabilities
    
    Methods:
        get: Handle GET requests to display zone details
        
    Template: channels/zone/detail.html
    """
    
    def get(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Handle GET request to display enhanced zone details.
        
        Args:
            request: HTTP request object
            pk: Primary key of the zone to display
            
        Returns:
            HttpResponse: Rendered template with comprehensive zone details
            
        Raises:
            Http404: If zone with given ID doesn't exist
        """
        zone = get_object_or_404(ChannelZone, pk=pk)
        
        # Get filter parameters for channels
        channel_search = request.GET.get('channel_search', '').strip()
        channel_status = request.GET.get('channel_status', '')
        channel_type = request.GET.get('channel_type', '')
        page = request.GET.get('page', 1)
        per_page = int(request.GET.get('per_page', 10))
        
        # Get associated channels with annotations
        channels = Channel.objects.filter(zones=zone).annotate(
            zone_relations_count=Count('zone_relations'),
            epg_programs_count=Count('epgprogram_set'),
            schedules_count=Count('channelschedule_set')
        ).select_related().prefetch_related('zone_relations', 'zones')
        
        # Apply channel filters
        if channel_search:
            channels = channels.filter(
                Q(name__icontains=channel_search) |
                Q(display_name__icontains=channel_search) |
                Q(channel_number__icontains=channel_search)
            )
            
        if channel_status:
            channels = channels.filter(status=channel_status)
            
        if channel_type:
            channels = channels.filter(channel_type=channel_type)
        
        channels = channels.order_by('channel_number', 'name')
        
        # Get zone-specific relationships
        zone_relations = ChannelZoneRelation.objects.filter(zone=zone).select_related(
            'channel', 'codec'
        ).order_by('-priority', 'channel__name')
        
        # Calculate comprehensive statistics
        total_channels = channels.count()
        active_channels = channels.filter(status='active').count()
        inactive_channels = channels.filter(status='inactive').count()
        maintenance_channels = channels.filter(status='maintenance').count()
        
        # Channel type distribution
        channel_types = channels.values('channel_type').annotate(
            count=Count('id')
        ).order_by('-count')
        
        # Zone relation statistics
        total_relations = zone_relations.count()
        active_relations = zone_relations.filter(is_active=True).count()
        vpn_relations = zone_relations.exclude(vpn_type='none').count()
        ftp_relations = zone_relations.exclude(ftp_host='').count()
        
        # Recent activity (last 30 days)
        thirty_days_ago = timezone.now() - datetime.timedelta(days=30)
        recent_channels = channels.filter(created_at__gte=thirty_days_ago).count()
        
        # Health status summary
        online_channels = channels.filter(is_online=True).count()
        offline_channels = channels.filter(is_online=False).count()
        
        # Pagination for channels
        paginator = Paginator(channels, per_page)
        try:
            channels_page = paginator.page(page)
        except PageNotAnInteger:
            channels_page = paginator.page(1)
        except EmptyPage:
            channels_page = paginator.page(paginator.num_pages)
        
        # Get available filter options
        available_statuses = Channel.STATUS_CHOICES
        available_types = Channel.CHANNEL_TYPES
        
        context = {
            'zone': zone,
            'channels': channels_page,
            'zone_relations': zone_relations,
            'channel_search': channel_search,
            'channel_status': channel_status,
            'channel_type': channel_type,
            'per_page': per_page,
            
            # Statistics
            'total_channels': total_channels,
            'active_channels': active_channels,
            'inactive_channels': inactive_channels,
            'maintenance_channels': maintenance_channels,
            'online_channels': online_channels,
            'offline_channels': offline_channels,
            'recent_channels': recent_channels,
            
            # Relations statistics
            'total_relations': total_relations,
            'active_relations': active_relations,
            'vpn_relations': vpn_relations,
            'ftp_relations': ftp_relations,
            
            # Distributions
            'channel_types': channel_types,
            
            # Filter options
            'available_statuses': available_statuses,
            'available_types': available_types,
        }
        
        # AJAX response for channel list updates
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({
                'html': render(request, 'channels/zone/channels_partial.html', context).content.decode(),
                'total_channels': total_channels,
                'active_channels': active_channels,
                'inactive_channels': inactive_channels,
            })
        
        return render(request, 'channels/zone/detail.html', context)


class ChannelZoneCreateView(LoginRequiredMixin, View):
    """Enhanced view for creating new channel zones.
    
    Features:
    - Comprehensive form validation
    - Support for all zone fields including timezone
    - Duplicate detection and prevention
    - AJAX form submission support
    - Activity logging
    
    Methods:
        get: Display zone creation form
        post: Process form submission and create zone
        
    Template: channels/zone/form.html
    """
    
    def get(self, request: HttpRequest) -> HttpResponse:
        """Display enhanced zone creation form.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with empty form and timezone options
        """
        # Get common timezone choices
        common_timezones = [
            'UTC',
            'America/New_York',
            'America/Chicago',
            'America/Denver',
            'America/Los_Angeles',
            'Europe/London',
            'Europe/Paris',
            'Europe/Berlin',
            'Europe/Madrid',
            'Europe/Rome',
            'Asia/Tokyo',
            'Asia/Shanghai',
            'Australia/Sydney',
        ]
        
        context = {
            'form_title': 'Create New Channel Zone',
            'submit_text': 'Create Zone',
            'common_timezones': common_timezones,
            'is_create': True,
        }
        return render(request, 'channels/zone/form.html', context)
    
    def post(self, request: HttpRequest) -> HttpResponse:
        """Process enhanced zone creation form submission.
        
        Args:
            request: HTTP request object with form data
            
        Returns:
            HttpResponse: Redirect to zone detail on success, or form with errors
        """
        try:
            # Extract and validate form data
            name = request.POST.get('name', '').strip()
            code = request.POST.get('code', '').strip().upper()
            description = request.POST.get('description', '').strip()
            timezone_val = request.POST.get('timezone', 'UTC').strip()
            is_active = request.POST.get('is_active') == 'on'
            
            # Validation
            errors = []
            
            if not name:
                errors.append('Zone name is required.')
            elif len(name) > 255:
                errors.append('Zone name must be 255 characters or less.')
                
            if not code:
                errors.append('Zone code is required.')
            elif len(code) > 10:
                errors.append('Zone code must be 10 characters or less.')
            elif ChannelZone.objects.filter(code=code).exists():
                errors.append(f'Zone code "{code}" already exists.')
                
            if ChannelZone.objects.filter(name=name).exists():
                errors.append(f'Zone name "{name}" already exists.')
            
            if errors:
                for error in errors:
                    messages.error(request, error)
                return self.get(request)
                
            # Create zone
            zone = ChannelZone.objects.create(
                name=name,
                code=code,
                description=description,
                timezone=timezone_val,
                is_active=is_active,
            )
            
            # Log activity
            Activity.objects.create(
                user=request.user,
                action='create',
                object_type='ChannelZone',
                object_id=zone.id,
                description=f'Created channel zone: {zone.name} ({zone.code})',
                ip_address=get_client_ip(request)
            )
            
            messages.success(request, f'Zone "{zone.name}" created successfully.')
            
            # AJAX response
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': f'Zone "{zone.name}" created successfully.',
                    'redirect_url': reverse('channels:zone_detail', kwargs={'pk': zone.pk})
                })
            
            return redirect('channels:zone_detail', pk=zone.pk)
            
        except ValidationError as e:
            error_msg = f'Validation error: {e}'
            messages.error(request, error_msg)
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({'success': False, 'message': error_msg})
            return self.get(request)
            
        except Exception as e:
            error_msg = f'Error creating zone: {e}'
            messages.error(request, error_msg)
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({'success': False, 'message': error_msg})
            return self.get(request)


class ChannelZoneUpdateView(LoginRequiredMixin, View):
    """Enhanced view for updating existing channel zones.
    
    Features:
    - Comprehensive form validation with change tracking
    - Support for all zone fields including timezone
    - Duplicate detection (excluding current zone)
    - AJAX form submission support
    - Activity logging with change details
    
    Methods:
        get: Display zone update form
        post: Process form submission and update zone
        
    Template: channels/zone/form.html
    """
    
    def get(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Display enhanced zone update form.
        
        Args:
            request: HTTP request object
            pk: Primary key of zone to update
            
        Returns:
            HttpResponse: Rendered template with pre-filled form and timezone options
            
        Raises:
            Http404: If zone with given ID doesn't exist
        """
        zone = get_object_or_404(ChannelZone, pk=pk)
        
        # Get common timezone choices
        common_timezones = [
            'UTC',
            'America/New_York',
            'America/Chicago',
            'America/Denver',
            'America/Los_Angeles',
            'Europe/London',
            'Europe/Paris',
            'Europe/Berlin',
            'Europe/Madrid',
            'Europe/Rome',
            'Asia/Tokyo',
            'Asia/Shanghai',
            'Australia/Sydney',
        ]
        
        # Add current timezone if not in common list
        if zone.timezone not in common_timezones:
            common_timezones.append(zone.timezone)
            common_timezones.sort()
        
        context = {
            'zone': zone,
            'form_title': f'Update Zone: {zone.name}',
            'submit_text': 'Update Zone',
            'common_timezones': common_timezones,
            'is_create': False,
        }
        return render(request, 'channels/zone/form.html', context)
    
    def post(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Process enhanced zone update form submission.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of zone to update
            
        Returns:
            HttpResponse: Redirect to zone detail on success, or form with errors
            
        Raises:
            Http404: If zone with given ID doesn't exist
        """
        zone = get_object_or_404(ChannelZone, pk=pk)
        
        try:
            # Store original values for change tracking
            original_values = {
                'name': zone.name,
                'code': zone.code,
                'description': zone.description,
                'timezone': zone.timezone,
                'is_active': zone.is_active,
            }
            
            # Extract and validate form data
            name = request.POST.get('name', '').strip()
            code = request.POST.get('code', '').strip().upper()
            description = request.POST.get('description', '').strip()
            timezone_val = request.POST.get('timezone', 'UTC').strip()
            is_active = request.POST.get('is_active') == 'on'
            
            # Validation
            errors = []
            
            if not name:
                errors.append('Zone name is required.')
            elif len(name) > 255:
                errors.append('Zone name must be 255 characters or less.')
                
            if not code:
                errors.append('Zone code is required.')
            elif len(code) > 10:
                errors.append('Zone code must be 10 characters or less.')
            elif ChannelZone.objects.filter(code=code).exclude(pk=zone.pk).exists():
                errors.append(f'Zone code "{code}" already exists.')
                
            if ChannelZone.objects.filter(name=name).exclude(pk=zone.pk).exists():
                errors.append(f'Zone name "{name}" already exists.')
            
            if errors:
                for error in errors:
                    messages.error(request, error)
                return self.get(request, pk)
            
            # Update zone
            zone.name = name
            zone.code = code
            zone.description = description
            zone.timezone = timezone_val
            zone.is_active = is_active
            zone.save()
            
            # Track changes for activity log
            changes = []
            for field, original_value in original_values.items():
                new_value = getattr(zone, field)
                if original_value != new_value:
                    changes.append(f'{field}: "{original_value}" → "{new_value}"')
            
            # Log activity
            if changes:
                Activity.objects.create(
                    user=request.user,
                    action='update',
                    object_type='ChannelZone',
                    object_id=zone.id,
                    description=f'Updated channel zone: {zone.name} ({zone.code}). Changes: {";".join(changes)}',
                    ip_address=get_client_ip(request)
                )
            
            messages.success(request, f'Zone "{zone.name}" updated successfully.')
            
            # AJAX response
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': f'Zone "{zone.name}" updated successfully.',
                    'redirect_url': reverse('channels:zone_detail', kwargs={'pk': zone.pk})
                })
            
            return redirect('channels:zone_detail', pk=zone.pk)
            
        except ValidationError as e:
            error_msg = f'Validation error: {e}'
            messages.error(request, error_msg)
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({'success': False, 'message': error_msg})
            return self.get(request, pk)
            
        except Exception as e:
            error_msg = f'Error updating zone: {e}'
            messages.error(request, error_msg)
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({'success': False, 'message': error_msg})
            return self.get(request, pk)


class ChannelZoneDeleteView(LoginRequiredMixin, View):
    """Enhanced view for deleting channel zones.
    
    Features:
    - Comprehensive dependency checking
    - Detailed impact analysis before deletion
    - Force deletion option for administrators
    - AJAX deletion support
    - Activity logging with dependency details
    
    Methods:
        get: Display deletion confirmation with impact analysis
        post: Process deletion request with safety checks
        
    Template: channels/zone/confirm_delete.html
    """
    
    def get(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Display enhanced zone deletion confirmation.
        
        Args:
            request: HTTP request object
            pk: Primary key of zone to delete
            
        Returns:
            HttpResponse: Rendered confirmation template with impact analysis
            
        Raises:
            Http404: If zone with given ID doesn't exist
        """
        zone = get_object_or_404(ChannelZone, pk=pk)
        
        # Comprehensive dependency analysis
        channels = Channel.objects.filter(zones=zone)
        channels_count = channels.count()
        active_channels_count = channels.filter(status='active').count()
        
        # Zone relations analysis
        zone_relations = ChannelZoneRelation.objects.filter(zone=zone)
        relations_count = zone_relations.count()
        active_relations_count = zone_relations.filter(is_active=True).count()
        vpn_relations_count = zone_relations.exclude(vpn_type='none').count()
        ftp_relations_count = zone_relations.exclude(ftp_host='').count()
        
        # EPG and Schedule analysis
        epg_programs_count = 0
        schedules_count = 0
        for channel in channels:
            epg_programs_count += channel.epgprogram_set.count()
            schedules_count += channel.channelschedule_set.count()
        
        # Determine if deletion is safe
        has_dependencies = (
            channels_count > 0 or 
            relations_count > 0 or 
            epg_programs_count > 0 or 
            schedules_count > 0
        )
        
        # Check if user can force delete (admin/superuser)
        can_force_delete = request.user.is_superuser or request.user.groups.filter(name='Administrators').exists()
        
        context = {
            'zone': zone,
            'channels_count': channels_count,
            'active_channels_count': active_channels_count,
            'relations_count': relations_count,
            'active_relations_count': active_relations_count,
            'vpn_relations_count': vpn_relations_count,
            'ftp_relations_count': ftp_relations_count,
            'epg_programs_count': epg_programs_count,
            'schedules_count': schedules_count,
            'has_dependencies': has_dependencies,
            'can_force_delete': can_force_delete,
            'channels': channels[:10],  # Show first 10 channels
        }
        return render(request, 'channels/zone/confirm_delete.html', context)
    
    def post(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Process enhanced zone deletion request.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of zone to delete
            
        Returns:
            HttpResponse: Redirect to zone list on success
            
        Raises:
            Http404: If zone with given ID doesn't exist
        """
        zone = get_object_or_404(ChannelZone, pk=pk)
        zone_name = zone.name
        zone_code = zone.code
        force_delete = request.POST.get('force_delete') == 'true'
        
        try:
            # Check dependencies
            channels = Channel.objects.filter(zones=zone)
            channels_count = channels.count()
            relations_count = ChannelZoneRelation.objects.filter(zone=zone).count()
            
            # Safety checks
            if channels_count > 0 and not force_delete:
                error_msg = f'Cannot delete zone "{zone_name}" because it has {channels_count} associated channels. Use force delete if you want to proceed.'
                messages.error(request, error_msg)
                
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({'success': False, 'message': error_msg})
                return self.get(request, pk)
            
            # Check permissions for force delete
            if force_delete and not (request.user.is_superuser or request.user.groups.filter(name='Administrators').exists()):
                error_msg = 'You do not have permission to force delete zones with dependencies.'
                messages.error(request, error_msg)
                
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({'success': False, 'message': error_msg})
                return self.get(request, pk)
            
            # Collect dependency info for logging
            dependency_info = []
            if channels_count > 0:
                dependency_info.append(f'{channels_count} channels')
            if relations_count > 0:
                dependency_info.append(f'{relations_count} zone relations')
            
            # Perform deletion
            zone.delete()
            
            # Log activity
            Activity.objects.create(
                user=request.user,
                action='delete',
                object_type='ChannelZone',
                object_id=pk,
                description=f'Deleted channel zone: {zone_name} ({zone_code}). Dependencies: {", ".join(dependency_info) if dependency_info else "None"}. Force delete: {force_delete}',
                ip_address=get_client_ip(request)
            )
            
            success_msg = f'Zone "{zone_name}" deleted successfully.'
            if force_delete and dependency_info:
                success_msg += f' Warning: This also removed {";".join(dependency_info)}.'
            
            messages.success(request, success_msg)
            
            # AJAX response
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': success_msg,
                    'redirect_url': reverse('channels:zone_list')
                })
            return redirect('channels:zone_list')
            
        except Exception as e:
            messages.error(request, f'Error deleting zone: {e}')
            return redirect('channels:zone_detail', pk=pk)


# Jingle CRUD Views

class JingleCreateView(View):
    """View for creating new jingles.
    
    Handles both GET requests to display the creation form and POST requests
    to process form submission and create new jingle instances.
    
    Methods:
        get: Display jingle creation form
        post: Process form submission and create jingle
        
    Template: channels/jingle_form.html
    """
    
    def get(self, request: HttpRequest) -> HttpResponse:
        """Display jingle creation form.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with empty form
        """
        channels = Channel.objects.filter(status='active').order_by('name')
        
        context = {
            'channels': channels,
            'jingle_types': Jingle.JINGLE_TYPES,
            'PLACEMENT_TYPES': Jingle.PLACEMENT_TYPES,
            'form_title': 'Create New Jingle',
            'submit_text': 'Create Jingle',
        }
        return render(request, 'channels/jingle/form.html', context)
    
    def post(self, request: HttpRequest) -> HttpResponse:
        """Process jingle creation form submission.
        
        Args:
            request: HTTP request object with form data
            
        Returns:
            HttpResponse: Redirect to jingle detail on success, or form with errors
        """
        try:
            channel_id = request.POST.get('channel')
            name = request.POST.get('name', '').strip()
            jingle_type = request.POST.get('type')
            placement = request.POST.get('placement')
            duration = request.POST.get('duration')
            file_upload = request.FILES.get('file')
            
            if not all([channel_id, name, jingle_type]):
                messages.error(request, 'Channel, name, and type are required.')
                return self.get(request)
                
            channel = get_object_or_404(Channel, pk=channel_id)
            
            jingle = Jingle.objects.create(
                channel=channel,
                name=name,
                type=jingle_type,
                placement=placement,
                duration=float(duration) if duration else None,
                file=file_upload,
            )
            
            messages.success(request, f'Jingle "{jingle.name}" created successfully.')
            return redirect('channels:jingle_detail', pk=jingle.pk)
            
        except ValidationError as e:
            messages.error(request, f'Validation error: {e}')
            return self.get(request)
        except Exception as e:
            messages.error(request, f'Error creating jingle: {e}')
            return self.get(request)


class JingleDetailView(View):
    """View for displaying detailed information about a specific jingle.
    
    Shows jingle details including metadata and playback information.
    
    Methods:
        get: Handle GET requests to display jingle details
        
    Template: channels/jingle_detail.html
    """
    
    def get(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Handle GET request to display jingle details.
        
        Args:
            request: HTTP request object
            pk: Primary key of the jingle to display
            
        Returns:
            HttpResponse: Rendered template with jingle details
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        """
        jingle = get_object_or_404(Jingle, pk=pk)
        
        context = {
            'jingle': jingle,
            'channel': jingle.channel,
        }
        
        return render(request, 'channels/jingle/detail.html', context)


class JingleUpdateView(View):
    """View for updating existing jingles.
    
    Handles both GET requests to display the update form and POST requests
    to process updates.
    
    Methods:
        get: Display jingle update form
        post: Process form submission and update jingle
        
    Template: channels/jingle_form.html
    """
    
    def get(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Display jingle update form.
        
        Args:
            request: HTTP request object
            pk: Primary key of jingle to update
            
        Returns:
            HttpResponse: Rendered template with pre-filled form
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        """
        jingle = get_object_or_404(Jingle, pk=pk)
        channels = Channel.objects.filter(status='active').order_by('name')
        
        context = {
            'jingle': jingle,
            'channels': channels,
            'jingle_types': Jingle.JINGLE_TYPES,
            'PLACEMENT_TYPES': Jingle.PLACEMENT_TYPES,
            'form_title': f'Update Jingle: {jingle.name}',
            'submit_text': 'Update Jingle',
        }
        return render(request, 'channels/jingle_form.html', context)
    
    def post(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Process jingle update form submission.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of jingle to update
            
        Returns:
            HttpResponse: Redirect to jingle detail on success, or form with errors
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        """
        jingle = get_object_or_404(Jingle, pk=pk)
        
        try:
            channel_id = request.POST.get('channel')
            if channel_id:
                jingle.channel = get_object_or_404(Channel, pk=channel_id)
                
            jingle.name = request.POST.get('name', '').strip() or jingle.name
            jingle.type = request.POST.get('type') or jingle.type
            jingle.placement = request.POST.get('placement') or jingle.placement
            
            duration = request.POST.get('duration')
            if duration:
                jingle.duration = float(duration)
                
            file_upload = request.FILES.get('file')
            if file_upload:
                jingle.file = file_upload
                
            jingle.save()
            
            messages.success(request, f'Jingle "{jingle.name}" updated successfully.')
            return redirect('channels:jingle_detail', pk=jingle.pk)
            
        except ValidationError as e:
            messages.error(request, f'Validation error: {e}')
            return self.get(request, pk)
        except Exception as e:
            messages.error(request, f'Error updating jingle: {e}')
            return self.get(request, pk)


class JingleDeleteView(View):
    """View for deleting jingles.
    
    Handles both GET requests to display confirmation page and POST requests
    to perform the actual deletion.
    
    Methods:
        get: Display deletion confirmation
        post: Process deletion request
        
    Template: channels/jingle_confirm_delete.html
    """
    
    def get(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Display jingle deletion confirmation.
        
        Args:
            request: HTTP request object
            pk: Primary key of jingle to delete
            
        Returns:
            HttpResponse: Rendered confirmation template
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        """
        jingle = get_object_or_404(Jingle, pk=pk)
        
        context = {
            'jingle': jingle,
            'channel': jingle.channel,
        }
        return render(request, 'channels/jingle/confirm_delete.html', context)
    
    def post(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Process jingle deletion request.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of jingle to delete
            
        Returns:
            HttpResponse: Redirect to jingle list on success
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        """
        jingle = get_object_or_404(Jingle, pk=pk)
        jingle_name = jingle.name
        channel = jingle.channel
        
        try:
            jingle.delete()
            messages.success(request, f'Jingle "{jingle_name}" deleted successfully.')
            return redirect('channels:jingle_list', channel_id=channel.pk)
            
        except Exception as e:
            messages.error(request, f'Error deleting jingle: {e}')
            return redirect('channels:jingle_detail', pk=pk)


# Adbreak CRUD Views

class AdbreakCreateView(View):
    """View for creating new adbreaks.
    
    Handles both GET requests to display the creation form and POST requests
    to process form submission and create new adbreak instances.
    
    Methods:
        get: Display adbreak creation form
        post: Process form submission and create adbreak
        
    Template: channels/adbreak_form.html
    """
    
    def get(self, request: HttpRequest) -> HttpResponse:
        """Display adbreak creation form.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with empty form
        """
        channels = Channel.objects.filter(status='active').order_by('name')
        
        context = {
            'channels': channels,
            'adbreak_types': Adbreak.ADBREAK_TYPE_CHOICES,
            'category_choices': Adbreak.CATEGORY_CHOICES,
            'form_title': 'Create New Adbreak',
            'submit_text': 'Create Adbreak',
        }
        return render(request, 'channels/adbreak/form.html', context)
    
    def post(self, request: HttpRequest) -> HttpResponse:
        """Process adbreak creation form submission.
        
        Args:
            request: HTTP request object with form data
            
        Returns:
            HttpResponse: Redirect to adbreak detail on success, or form with errors
        """
        try:
            channel_id = request.POST.get('channel')
            date = request.POST.get('date')
            start_time = request.POST.get('start_time')
            end_time = request.POST.get('end_time')
            duration = request.POST.get('duration')
            adbreak_type = request.POST.get('type')
            category = request.POST.get('category')
            
            if not all([channel_id, date, start_time, adbreak_type]):
                messages.error(request, 'Channel, date, start time, and type are required.')
                return self.get(request)
                
            channel = get_object_or_404(Channel, pk=channel_id)
            
            adbreak = Adbreak.objects.create(
                channel=channel,
                date=date,
                start_time=start_time,
                end_time=end_time,
                duration=float(duration) if duration else None,
                type=adbreak_type,
                category=category,
            )
            
            messages.success(request, f'Adbreak created successfully for {channel.name}.')
            return redirect('channels:adbreak_detail', pk=adbreak.pk)
            
        except ValidationError as e:
            messages.error(request, f'Validation error: {e}')
            return self.get(request)
        except Exception as e:
            messages.error(request, f'Error creating adbreak: {e}')
            return self.get(request)


class AdbreakDetailView(View):
    """View for displaying detailed information about a specific adbreak.
    
    Shows adbreak details including timing and metadata.
    
    Methods:
        get: Handle GET requests to display adbreak details
        
    Template: channels/adbreak_detail.html
    """
    
    def get(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Handle GET request to display adbreak details.
        
        Args:
            request: HTTP request object
            pk: Primary key of the adbreak to display
            
        Returns:
            HttpResponse: Rendered template with adbreak details
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        """
        adbreak = get_object_or_404(Adbreak, pk=pk)
        
        context = {
            'adbreak': adbreak,
            'channel': adbreak.channel,
        }
        
        return render(request, 'channels/adbreak/detail.html', context)


class AdbreakUpdateView(View):
    """View for updating existing adbreaks.
    
    Handles both GET requests to display the update form and POST requests
    to process updates.
    
    Methods:
        get: Display adbreak update form
        post: Process form submission and update adbreak
        
    Template: channels/adbreak_form.html
    """
    
    def get(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Display adbreak update form.
        
        Args:
            request: HTTP request object
            pk: Primary key of adbreak to update
            
        Returns:
            HttpResponse: Rendered template with pre-filled form
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        """
        adbreak = get_object_or_404(Adbreak, pk=pk)
        channels = Channel.objects.filter(status='active').order_by('name')
        
        context = {
            'adbreak': adbreak,
            'channels': channels,
            'adbreak_types': Adbreak.ADBREAK_TYPE_CHOICES,
            'category_choices': Adbreak.CATEGORY_CHOICES,
            'form_title': f'Update Adbreak: {adbreak.channel.name} - {adbreak.date}',
            'submit_text': 'Update Adbreak',
        }
        return render(request, 'channels/adbreak/form.html', context)
    
    def post(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Process adbreak update form submission.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of adbreak to update
            
        Returns:
            HttpResponse: Redirect to adbreak detail on success, or form with errors
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        """
        adbreak = get_object_or_404(Adbreak, pk=pk)
        
        try:
            channel_id = request.POST.get('channel')
            if channel_id:
                adbreak.channel = get_object_or_404(Channel, pk=channel_id)
                
            date = request.POST.get('date')
            if date:
                adbreak.date = date
                
            start_time = request.POST.get('start_time')
            if start_time:
                adbreak.start_time = start_time
                
            end_time = request.POST.get('end_time')
            if end_time:
                adbreak.end_time = end_time
                
            duration = request.POST.get('duration')
            if duration:
                adbreak.duration = float(duration)
                
            adbreak.type = request.POST.get('type') or adbreak.type
            adbreak.category = request.POST.get('category') or adbreak.category
            
            adbreak.save()
            
            messages.success(request, f'Adbreak updated successfully.')
            return redirect('channels:adbreak_detail', pk=adbreak.pk)
            
        except ValidationError as e:
            messages.error(request, f'Validation error: {e}')
            return self.get(request, pk)
        except Exception as e:
            messages.error(request, f'Error updating adbreak: {e}')
            return self.get(request, pk)


class AdbreakDeleteView(View):
    """View for deleting adbreaks.
    
    Handles both GET requests to display confirmation page and POST requests
    to perform the actual deletion.
    
    Methods:
        get: Display deletion confirmation
        post: Process deletion request
        
    Template: channels/adbreak_confirm_delete.html
    """
    
    def get(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Display adbreak deletion confirmation.
        
        Args:
            request: HTTP request object
            pk: Primary key of adbreak to delete
            
        Returns:
            HttpResponse: Rendered confirmation template
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        """
        adbreak = get_object_or_404(Adbreak, pk=pk)
        
        context = {
            'adbreak': adbreak,
            'channel': adbreak.channel,
        }
        return render(request, 'channels/adbreak/confirm_delete.html', context)
    
    def post(self, request: HttpRequest, pk: str) -> HttpResponse:
        """Process adbreak deletion request.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of adbreak to delete
            
        Returns:
            HttpResponse: Redirect to adbreak list on success
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        """
        adbreak = get_object_or_404(Adbreak, pk=pk)
        channel = adbreak.channel
        
        try:
            adbreak.delete()
            messages.success(request, f'Adbreak deleted successfully.')
            return redirect('channels:adbreak_list', channel_id=channel.pk)
            
        except Exception as e:
            messages.error(request, f'Error deleting adbreak: {e}')
            return redirect('channels:adbreak_detail', pk=pk)

 
# 


class JingleAPIView(View):
    """API view for jingle operations.
    
    Provides JSON endpoints for jingle management within channels.
    
    Methods:
        get: Retrieve jingles for a channel
    """
    
    def get(self, request: HttpRequest, channel_id: int) -> JsonResponse:
        """Retrieve jingles for a channel as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: List of jingles for the channel
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        try:
            jingles = Jingle.objects.filter(channel=channel).order_by('-created_at')
            
            # Apply filters
            jingle_type = request.GET.get('type')
            if jingle_type:
                jingles = jingles.filter(type=jingle_type)
                
            placement = request.GET.get('placement')
            if placement:
                jingles = jingles.filter(placement=placement)
                
            # Pagination
            page = int(request.GET.get('page', 1))
            per_page = int(request.GET.get('per_page', 20))
            
            paginator = Paginator(jingles, per_page)
            jingles_page = paginator.page(page)
            
            data = {
                'channel': {
                    'id': channel.id,
                    'name': channel.name,
                    'display_name': channel.display_name,
                },
                'jingles': [
                    {
                        'id': jingle.id,
                        'name': jingle.name,
                        'type': jingle.type,
                        'placement': jingle.placement,
                        'duration': jingle.duration,
                        'file_url': jingle.file.url if jingle.file else None,
                        'created_at': jingle.created_at.isoformat(),
                    }
                    for jingle in jingles_page
                ],
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': paginator.count,
                    'pages': paginator.num_pages,
                    'has_next': jingles_page.has_next(),
                    'has_previous': jingles_page.has_previous(),
                }
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class AdbreakAPIView(View):
    """API view for adbreak operations.
    
    Provides JSON endpoints for adbreak data retrieval and analysis.
    
    Methods:
        get: Retrieve adbreaks for a channel with filtering
    """
    
    def get(self, request: HttpRequest, channel_id: int) -> JsonResponse:
        """Retrieve adbreaks for a channel as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: List of adbreaks with statistics
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        try:
            # Date range filtering
            start_date = request.GET.get('start_date')
            end_date = request.GET.get('end_date')
            
            if not start_date:
                start_date = (timezone.now().date() - datetime.timedelta(days=7)).isoformat()
            if not end_date:
                end_date = timezone.now().date().isoformat()
                
            adbreaks = Adbreak.objects.filter(
                channel=channel,
                date__gte=start_date,
                date__lte=end_date
            )
            
            # Apply additional filters
            adbreak_type = request.GET.get('type')
            if adbreak_type:
                adbreaks = adbreaks.filter(type=adbreak_type)
                
            category = request.GET.get('category')
            if category:
                adbreaks = adbreaks.filter(category=category)
                
            adbreaks = adbreaks.order_by('-date', '-start_time')
            
            # Calculate statistics
            total_duration = sum(ab.duration or 0 for ab in adbreaks)
            avg_duration = total_duration / len(adbreaks) if adbreaks else 0
            
            # Pagination
            page = int(request.GET.get('page', 1))
            per_page = int(request.GET.get('per_page', 50))
            
            paginator = Paginator(adbreaks, per_page)
            adbreaks_page = paginator.page(page)
            
            data = {
                'channel': {
                    'id': channel.id,
                    'name': channel.name,
                    'display_name': channel.display_name,
                },
                'date_range': {
                    'start_date': start_date,
                    'end_date': end_date,
                },
                'statistics': {
                    'total_adbreaks': len(adbreaks),
                    'total_duration': round(total_duration, 2),
                    'average_duration': round(avg_duration, 2),
                },
                'adbreaks': [
                    {
                        'id': adbreak.id,
                        'date': adbreak.date.isoformat(),
                        'start_time': adbreak.start_time.isoformat() if adbreak.start_time else None,
                        'end_time': adbreak.end_time.isoformat() if adbreak.end_time else None,
                        'duration': adbreak.duration,
                        'type': adbreak.type,
                        'category': adbreak.category,
                    }
                    for adbreak in adbreaks_page
                ],
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': paginator.count,
                    'pages': paginator.num_pages,
                    'has_next': adbreaks_page.has_next(),
                    'has_previous': adbreaks_page.has_previous(),
                }
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class ChannelStatsAPIView(View):
    """API view for channel statistics and analytics.
    
    Provides aggregated statistics and metrics for channels.
    
    Methods:
        get: Retrieve channel statistics
    """
    
    def get(self, request: HttpRequest, channel_id: int) -> JsonResponse:
        """Retrieve channel statistics as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: Channel statistics and metrics
            
        Raises:
            Http404: If channel with given ID doesn't exist
        """
        channel = get_object_or_404(Channel, pk=channel_id)
        
        try:
            now = timezone.now()
            today = now.date()
            week_ago = today - datetime.timedelta(days=7)
            month_ago = today - datetime.timedelta(days=30)
            
            # Adbreak statistics
            today_adbreaks = Adbreak.objects.filter(channel=channel, date=today).count()
            week_adbreaks = Adbreak.objects.filter(
                channel=channel, date__gte=week_ago
            ).count()
            month_adbreaks = Adbreak.objects.filter(
                channel=channel, date__gte=month_ago
            ).count()
            
            # Duration statistics
            week_duration = Adbreak.objects.filter(
                channel=channel, date__gte=week_ago
            ).aggregate(total=Sum('duration'))['total'] or 0
            
            month_duration = Adbreak.objects.filter(
                channel=channel, date__gte=month_ago
            ).aggregate(total=Sum('duration'))['total'] or 0
            
            # Jingle statistics
            total_jingles = Jingle.objects.filter(channel=channel).count()
            
            # Health statistics
            uptime_percentage = 95.5  # This would be calculated from actual health checks
            
            data = {
                'channel': {
                    'id': channel.id,
                    'name': channel.name,
                    'display_name': channel.display_name,
                    'status': channel.status,
                    'is_online': channel.is_online,
                },
                'adbreak_stats': {
                    'today': today_adbreaks,
                    'this_week': week_adbreaks,
                    'this_month': month_adbreaks,
                    'week_duration': round(week_duration, 2),
                    'month_duration': round(month_duration, 2),
                },
                'content_stats': {
                    'total_jingles': total_jingles,
                },
                'health_stats': {
                    'uptime_percentage': uptime_percentage,
                    'last_health_check': channel.last_health_check.isoformat() if channel.last_health_check else None,
                },
                'generated_at': now.isoformat(),
            }
            
            return JsonResponse(data)
            
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


