from django.core.exceptions import ValidationError
from django.db.models.aggregates import Count
from rest_framework.permissions import IsAuthenticated
from rest_framework.filters import SearchFilter
from rest_framework.generics import ListAPIView
from django_filters.rest_framework import DjangoFilterBackend

from apps.companies.models import CallCatchPhrase
from apps.calls.repositories import CallsRepository
from apps.calls.pagination import CatchPhrasePagination
from apps.calls.serializers import CallPhraseReportSerializer
from apps.calls.filters import CatchPhraseReportFilter
import logging

logger = logging.getLogger(__name__)


class CatchPhraseReportAPIView(ListAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = CallPhraseReportSerializer
    filter_backends = [DjangoFilterBackend, SearchFilter]
    filterset_class = CatchPhraseReportFilter
    pagination_class = CatchPhrasePagination

    search_fields = [
        "caller_name",
        "from_number",
        "twilio_call_sid",
    ]

    def get_company_id(self):
        active_company_id = getattr(self.request.user, "active_company_id", None)
        if not active_company_id:
            raise ValidationError("User does not belong to an active company.")
        return active_company_id

    def get_queryset(self):
        """
        Calls that have at least one catchphrase detected.
        If no phrases exist yet → return empty queryset safely.
        """
        company_id = self.get_company_id()

        call_ids = (
            CallCatchPhrase.objects
            .filter(company_id=company_id)
            .values_list("call_id", flat=True)
            .distinct()
        )

        return CallsRepository.get_service_calls(
            company_id=company_id
        ).filter(id__in=call_ids)

    def list(self, request, *args, **kwargs):
        company_id = self.get_company_id()

        queryset = self.filter_queryset(self.get_queryset())

        call_ids = queryset.values_list("id", flat=True)

        graph_counts_qs = (
            CallCatchPhrase.objects
            .filter(
                company_id=company_id,
                call_id__in=call_ids
            )
            .values("phrase__id", "phrase__phrase")
            .annotate(count=Count("id"))
            .order_by("-count", "phrase__phrase")
        )

        graph_data = [
            {
                "phrase_id": row["phrase__id"],
                "phrase": row["phrase__phrase"],
                "count": row["count"],
            }
            for row in graph_counts_qs
        ]

        page = self.paginate_queryset(queryset)

        serializer = self.get_serializer(page, many=True)

        return self.get_paginated_response({
            "calls": serializer.data,
            "graph_data": graph_data
        })
