import json
import uuid
from types import SimpleNamespace

from rest_framework import status
from rest_framework.exceptions import ValidationError

from api.translation import __
from api.utils import get_exception_detail, log_critical_error
from api.validator import BaseValidator
from api.views.admin.base import AdminApiBase


class SimulateScheduleResponse(AdminApiBase):
    """Test-only adapter that exercises the production atomic engine apply path."""

    def post(self, request):
        try:
            rules = {
                "activity_id": "required|exists:api.TtActivity,id",
                "staff_ids": "nullable|array|exists:api.TtStaff,id",
                "location_ids": "nullable|array|exists:api.TtLocation,id",
                "start_slot": "required|integer",
                "socket_id": "nullable",
            }
            error = BaseValidator(request.data, rules, {}).validate()
            if error:
                raise ValidationError(error)
            from kafka_consumer.tt_response import schedule

            response_data = {
                "session_id": request.user.name,
                "request_id": f"simulate:{uuid.uuid4()}",
                "status": "success",
                "schedule": json.dumps(
                    [
                        {
                            "activity": str(request.data["activity_id"]),
                            "teaching_staff": json.dumps(request.data.get("staff_ids") or []),
                            "location": json.dumps(request.data.get("location_ids") or []),
                            "start_slot": str(request.data["start_slot"]),
                        }
                    ]
                ),
            }
            result = schedule(
                response_data,
                SimpleNamespace(socket_id=request.data.get("socket_id")),
            )
            return self.api_response(data=result)
        except ValidationError as error:
            return self.api_response(
                error=error.detail["error"],
                errors=error.detail["errors"],
                code=status.HTTP_400_BAD_REQUEST,
            )
        except Exception as error:
            details = get_exception_detail(error)
            log_critical_error(
                user_id=getattr(request.user, "id", None),
                descr=details["descr"],
                url=details["url"],
                trace=details["trace"],
            )
            return self.api_response(error=__("message.internal_server_error"), code=500)
