from rest_framework import status
from rest_framework.exceptions import ValidationError

from api.models import EsInvigilatorRole, EsInvigilatorSetting, EsSessionInvigilator
from api.services.invigilator_assign import estimate_required_invigilators, summarize_assigned_invigilators
from api.services.invigilator_setting_v2 import load_invigilator_setting
from api.translation import __
from api.utils import get_exception_detail, log_critical_error
from api.views.admin.base import AdminApiBase


class InvigilatorSettingRulesV2(AdminApiBase):
    def post(self, request):
        try:
            self.api_log_skip_outgoing_data = True

            info = load_invigilator_setting()
            assigned_invigilators = [
                relation.invigilator
                for relation in (
                    EsSessionInvigilator.objects
                    .filter(invigilator_id__isnull=False)
                    .select_related("invigilator")
                    .prefetch_related("invigilator__role")
                )
            ]
            data = {
                "delete_confirmation_api": False,
                "allow_remove": [
                    "configuration",
                ],
                "role": [
                    {
                        "id": EsInvigilatorSetting.ANY_ROLE_ID,
                        "name": __("attr.invigilator_setting_any"),
                    },
                    *list(
                        EsInvigilatorRole.objects.filter(
                            status=EsInvigilatorRole.STATUS_TO_CODE["active"],
                        ).values("id", "name")
                    ),
                ],
                "is_floating": [
                    {
                        "id": val,
                        "name": __(f"attr.invigilator_setting_is_floating.{val}"),
                    }
                    for key, val in EsInvigilatorSetting.IS_FLOATING_TO_CODE.items()
                ],
                "is_inclusive": [
                    {
                        "id": val,
                        "name": __(f"attr.invigilator_setting_is_inclusive.{val}"),
                    }
                    for key, val in EsInvigilatorSetting.IS_INCLUSIVE_TO_CODE.items()
                ],
                "quantity_mode": [
                    {
                        "id": val,
                        "name": __(f"attr.invigilator_setting_quantity_mode.{val}"),
                    }
                    for key, val in EsInvigilatorSetting.QUANTITY_MODE_TO_CODE.items()
                ],
            }
            info["total_assigned_invigilators"] = summarize_assigned_invigilators(assigned_invigilators)
            info["total_estimated_invigilators"] = estimate_required_invigilators()

            return self.api_response(data={
                "info": info,
                "rules": data,
            })
        except ValidationError as e:
            first_message = e.detail["error"]
            errors = e.detail["errors"]
            return self.api_response(error=first_message, errors=errors, code=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            e_details = get_exception_detail(e)
            log_critical_error(user_id=None, descr=e_details["descr"], url=e_details["url"], trace=e_details["trace"])
            return self.api_response(error=__("message.internal_server_error"), code=status.HTTP_500_INTERNAL_SERVER_ERROR)
