from rest_framework import status
from rest_framework.exceptions import ValidationError

from api.models.audit_trail import AuditTrail
from api.models.audit_trail_details import AuditTrailDetails
from api.translation import __
from api.utils import get_exception_detail, get_ip, log_critical_error
from api.validator import BaseValidator
from api.views.admin.base import AdminApiBase
from api.services.exam_scheduler import schedule_exam_requirements


class ExamActivitySchedule(AdminApiBase):
	def validate_request(self, request):
		rules = {
			"id": "required|array|exists:api.EsExamActivity,id",
		}
		attribute = {
			"id": "Activity ID",
		}

		validator = BaseValidator(request.data, rules, attribute)
		error = validator.validate()
		if error:
			raise ValidationError(error)

	def post(self, request):
		try:
			self.validate_request(request)
			self.api_log_skip_outgoing_data = True

			result = schedule_exam_requirements(request.data.get("id") or [], request.user.id)
			if result["old_data"] or result["new_data"]:
				audit_trail = AuditTrail.objects.create(
					user_id=request.user.id,
					type=self.audit_type,
					ip_address=get_ip(request),
				)
				AuditTrailDetails.custom_insert(
					audit_trail=audit_trail,
					action="exam_activity_schedule",
					remark_param={"code": ",".join(result["remark_codes"])},
					new_data=result["new_data"],
					old_data=result["old_data"],
				)

			return self.api_response(data=result["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)