from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status

from apps.calls.services import (
    get_company_users,
    aggregate_user_calls,
    format_best_worst,
    format_user_performance,
)
from rest_framework.exceptions import ValidationError


class UserPerformanceMixin:
    """
    Enterprise-grade user performance endpoints.
    """

    def _get_company_users_or_400(self, request):
        users = get_company_users(request.user)
        if users is None:
            raise ValidationError("No active company found")
        return users

    def _aggregate(self, request):
        calls_qs = self.filter_queryset(self.get_queryset())
        company_users = self._get_company_users_or_400(request)
        return aggregate_user_calls(
            calls_qs=calls_qs,
            company_users=company_users,
        )

    @action(detail=False, methods=["get"], url_path="user-performance")
    def user_performance(self, request):
        show_all = request.query_params.get('show_all', False)
        stats, users = self._aggregate(request)
        return Response(
            format_user_performance(
                stats,
                users,
                show_all=show_all,
            ),
            status=status.HTTP_200_OK,
        )

    @action(detail=False, methods=["get"], url_path="best-performing-users")
    def best_performing_users(self, request):
        show_all = request.query_params.get('show_all', False)
        stats, users = self._aggregate(request)
        return Response({"data": format_best_worst(
            stats,
            users,
            order_by="avg_attended_value",
            show_all=show_all,
        )}, status=status.HTTP_200_OK)

    @action(detail=False, methods=["get"], url_path="worst-performing-users")
    def worst_performing_users(self, request):
        show_all = request.query_params.get('show_all', False)
        stats, users = self._aggregate(request)
        return Response({"data": format_best_worst(
            stats,
            users,
            order_by="avg_missed_value",
            show_all=show_all,
        )}, status=status.HTTP_200_OK)
