from django.utils import timezone
from datetime import timezone as dt_timezone
from django.db.models import Q
import django_filters
from django_filters import rest_framework as filters
from apps.calls.models import Call ,TonyCall
from rest_framework.filters import OrderingFilter



def to_utc(value):
    """
    Safely convert a datetime to timezone-aware UTC.
    """
    if value is None:
        return None

    if timezone.is_naive(value):
        # Make it aware in UTC
        return timezone.make_aware(value, dt_timezone.utc)

    # Convert any aware datetime to UTC
    return value.astimezone(dt_timezone.utc)

class CallFilter(filters.FilterSet):
    start_date = filters.DateTimeFilter(method='filter_start_date_with_timezone')
    end_date = filters.DateTimeFilter(method='filter_end_date_with_timezone')
    sentiment = filters.BaseInFilter(field_name='sentiment', lookup_expr='in')
    transfer_status = filters.BaseInFilter(field_name='transfer_status', lookup_expr='in')
    advisor_ids = filters.BaseInFilter(field_name='transfer_user', lookup_expr='in')
    call_id_search = filters.CharFilter(method='filter_call_id')
    company_ids = filters.BaseInFilter(field_name='company', lookup_expr='in')
    dealership_ids = filters.BaseInFilter(field_name='dealership', lookup_expr='in')

    def filter_start_date_with_timezone(self, queryset, name, value):
        if not value:
            return queryset
        return queryset.filter(created_at__gte=value)

    def filter_end_date_with_timezone(self, queryset, name, value):
        if not value:
            return queryset
        return queryset.filter(created_at__lte=value)

    def filter_call_id(self, queryset, name, value):
        value = value.strip()

        q = Q(call_id__icontains=value) | Q(twilio_call_sid__icontains=value)
        if value.isdigit():
            q = Q(id=int(value))

        return queryset.filter(q)

    class Meta:
        model = Call
        fields = [
            'start_date',
            'end_date',
            'sentiment',
            'advisor_ids',
            'transfer_status',
            'company_ids',
            'dealership_ids',
        ]

class DailyCallsFilter(CallFilter):
    class Meta(CallFilter.Meta):
        fields = ['start_date', 'end_date']

class BookingIntentFilter(CallFilter):
    booking_intent = filters.BaseInFilter(field_name='booking_intent', lookup_expr='in')
    class Meta(CallFilter.Meta):
        fields = ['booking_intent']



class TonyCallFilter(django_filters.FilterSet):
    start_date = django_filters.DateTimeFilter(field_name="call_date_time", lookup_expr="gte")
    end_date = django_filters.DateTimeFilter(field_name="call_date_time", lookup_expr="lte")

    intention = django_filters.CharFilter(field_name="intention", lookup_expr="icontains")
    status = django_filters.CharFilter(field_name="status", lookup_expr="iexact")
    called_number = django_filters.CharFilter(field_name="called_number", lookup_expr="icontains")
    called_to = django_filters.CharFilter(field_name="called_to", lookup_expr="icontains")
    company_id = django_filters.NumberFilter(field_name="company__id")
    call_id_search = django_filters.CharFilter(method='filter_call_id')

    def filter_call_id(self, queryset, name, value):
        value = value.strip()

        q = Q(call_id__icontains=value)
        if value.isdigit():
            q = Q(id=int(value))

        return queryset.filter(q)

    class Meta:
        model = TonyCall
        fields = []

class CallOrderingFilter(OrderingFilter):
    FIELD_MAP = {
        'caller_name': 'sort_name',
        '-caller_name': '-sort_name',
        'transfer_user__username' : 'sort_advisor_name',
        '-transfer_user__username' : '-sort_advisor_name',
    }

    def get_ordering(self, request, queryset, view):
        ordering = super().get_ordering(request, queryset, view)
        if not ordering:
            return ordering

        return [self.FIELD_MAP.get(field, field) for field in ordering]
