from rest_framework import status
from rest_framework.exceptions import ValidationError

from api.models import EsInvigilatorRole
from api.translation import __
from api.utils import log_critical_error, get_exception_detail
from api.views.admin.base import AdminApiBase

class InvigilatorRoleList(AdminApiBase):
    list_default_order_column = "id"
    def post(self, request):
        try:
            self.api_log_skip_outgoing_data=True
            data = self.get_data(request)
            return self.api_response(data=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)

    def get_data(self,request):
        roles = (
            EsInvigilatorRole.objects
            .all()
        )
        roles = self.invigilator_role_listing_filter(request, roles)
        pagination = self.invigilator_role_listing_pagination(request, roles)

        return_data=[]

        for val in pagination["paginated_data"]:
            data={}
            data["id"] = val.id
            data["code"] = val.code
            data["name"] = val.name
            data["desc"] = val.desc
            data["color"] = val.color
            data["status"] = val.status
            data["status_text"] = __("attr.invigilator_role_status." + str(val.status))

            for i in range(1,11):
                extra_data_field = f"extra_data_{i}"
                data[extra_data_field] = getattr(val,extra_data_field,None)

            return_data.append(data)

        return {
            "data": return_data,
            "total": pagination["total"],
            "page": pagination["page"],
            "per_page": pagination["per_page"],
        }

    def invigilator_role_listing_filter(self, request, model):
        filters = request.data.get("filter")
        if not isinstance(filters, dict) or not filters:
            return model

        for key, val in filters.items():
            if val in (None, "", [], {}):
                continue

            match key:
                case "code" | "name" | "desc" | "color":
                    model = model.filter(**{f"{key}__icontains": val})
                case "status":
                    if isinstance(val, (list, tuple, set)):
                        model = model.filter(status__in=list(val))
                    else:
                        model = model.filter(status=val)
                case _:
                    continue

        return model

    def invigilator_role_listing_pagination(self, request, model):
        page, per_page = self.parse_pagination(request)
        sort_by = request.data.get("sort_by")
        order_by = request.data.get("order_by")

        total = model.count()

        if sort_by:
            if str(order_by).lower() == "desc":
                ordering_string = f"-{sort_by}"
            else:
                ordering_string = sort_by
            model = model.order_by(ordering_string)
        else:
            model = model.order_by(self.list_default_order_column)

        if per_page != -1:
            start_index = (page - 1) * per_page
            end_index = start_index + per_page
            paginated_data = model[start_index:end_index]
        else:
            paginated_data = model

        return {
            "total": total,
            "paginated_data": paginated_data,
            "page": page,
            "per_page": per_page,
        }