from django.db.models import Subquery, CharField, Q
from django.db.models.aggregates import Count

from apps.calls.models import Call
from apps.calls.constants import BotType, TRANSFER_STATUS, BookingIntent
from apps.calls.utils import get_date_range_from_request
from apps.calls.serializers import DateRangeSerializer
from apps.customers.repository import CustomerRepository


class BDCProgressService:

    @staticmethod
    def fetch_calls(request, company):

        if not company:
            return Call.objects.none()

        start_dt, end_dt = get_date_range_from_request(
            request,
            DateRangeSerializer
        )

        return (
            Call.objects
            .filter(
                company=company,
                transfer_number__isnull=False,
                bot_type=BotType.SERVICE_BOT.value,
                created_at__gte=start_dt,
                created_at__lte=end_dt,
            ).annotate(
                customer_name=Subquery(
                    CustomerRepository.get_name_subquery(),
                    output_field=CharField(),
                )
            )
        )

    @staticmethod
    def get_stats(queryset):
        stats = queryset.aggregate(
            total_calls=Count('id'),

            scheduled=Count(
                'id',
                filter=Q(booking_intent=BookingIntent.YES.value),
            ),
            not_scheduled=Count(
                'id',
                filter=~Q(booking_intent=BookingIntent.YES.value),
            ),

            received_calls=Count(
                'id',
                filter=Q(
                    transfer_status=TRANSFER_STATUS.SUCCESSFUL.value
                ),
            ),
            calls_missed=Count(
                'id',
                filter=Q(
                    transfer_status=TRANSFER_STATUS.FAILED.value
                ),
            ),
        )

        total = stats['total_calls'] or 0

        percentage = {
            'calls_missed': 0,
            'calls_received': 0,
            'scheduled': 0,
            'not_scheduled': 0,
        }

        if total:
            percentage['calls_missed'] = round(
                (stats['calls_missed'] / total) * 100, 2
            )
            percentage['calls_received'] = round(
                (stats['received_calls'] / total) * 100, 2
            )
            percentage['scheduled'] = round(
                (stats['scheduled'] / total) * 100, 2
            )
            percentage['not_scheduled'] = round(
                (stats['not_scheduled'] / total) * 100, 2
            )

        stats['percentage'] = percentage
        return stats
