from typing import Any, Dict, List, Optional, Union

from fastapi.responses import JSONResponse
from pydantic import BaseModel


class GenericResponse(BaseModel):
    data: Any
    error: Any


class DoctorRequest(BaseModel):
    id: str
    vendor_id: str


class AssignDoctorRequest(BaseModel):
    prescription_id: str
    vendor_id: str


class ReleaseDoctorRequest(BaseModel):
    doctor_id: str
    prescription_id: str
    vendor_id: str


class BlockDoctorRequest(BaseModel):
    block_doctor_id: str
    vendor_id: str
    prescription_id: str


class GenericJSONResponse(JSONResponse):
    def __init__(
        self, data: Any = None, error: Any = None, status_code: int = 200, **kwargs
    ):
        # Wrap the data and error inside the content dictionary
        content = GenericResponse(data=data, error=error).model_dump()
        super().__init__(content=content, status_code=status_code, **kwargs)


class AssignDoctorResponseData(BaseModel):
    prescription_id: str
    doctor_ids: List[str]


class APIResponseError(BaseModel):
    message: str = None
    code: int = None
    status: str = None


class AssignDoctorResponse(BaseModel):
    data: AssignDoctorResponseData = None
    error: APIResponseError = None


class BlockDoctorResponseData(BaseModel):
    message: str


class BlockDoctorResponse(BaseModel):
    data: BlockDoctorResponseData = None
    error: APIResponseError = None


class ReassignDoctorResponseData(BaseModel):
    prescription_id: str
    doctor_ids: List[str]


class ReassignDoctorResponse(BaseModel):
    data: ReassignDoctorResponseData = None
    error: APIResponseError = None


class ReleaseDoctorResponseData(BaseModel):
    message: str


class ReleaseDoctorResponse(BaseModel):
    data: ReleaseDoctorResponseData = None
    error: APIResponseError = None


class DeleteDoctorResponseData(BaseModel):
    message: str


class DeleteDoctorResponse(BaseModel):
    data: DeleteDoctorResponseData = None
    error: APIResponseError = None


class CachedDoctorsResponseData(BaseModel):
    doctor_ids: List[str]


class CachedDoctorsResponse(BaseModel):
    data: CachedDoctorsResponseData = None
    error: APIResponseError = None


class PrescriptionsInQueueResponseData(BaseModel):
    prescription_ids: List[str]


class PrescriptionsInQueueResponse(BaseModel):
    data: PrescriptionsInQueueResponseData = None
    error: APIResponseError = None


class AssignedDoctorPrescriptionResponseData(BaseModel):
    prescription_doctor: Dict[str, List[str]]


class AssignedDoctorPrescriptionResponse(BaseModel):
    data: AssignedDoctorPrescriptionResponseData = None
    error: APIResponseError = None


class AddDoctorResponseData(BaseModel):
    message: str


class AddDoctorResponse(BaseModel):
    data: AddDoctorResponseData = None
    error: APIResponseError = None


class AddVendorResponseData(BaseModel):
    message: str


class AddVendorResponse(BaseModel):
    data: AddVendorResponseData = None
    error: APIResponseError = None


class HoldPrescriptionRequest(BaseModel):
    prescription_id: str
    vendor_id: str


class HoldPrescriptionResponseData(BaseModel):
    message: str


class HoldPrescriptionResponse(BaseModel):
    data: HoldPrescriptionResponseData = None
    error: APIResponseError = None


class DoctorResponseData(BaseModel):
    vendor: str
    doctors: List[str]
    
    concurrent_doctors: Union[int, None] = None
    immediate_unblock: bool
    rx_max_hold_time: int
    rx_max_block_time: int
    rx_notification_interval: int
    delay_after_hold: int


class AllAvailableDoctorsResponse(BaseModel):
    data: List[DoctorResponseData]
    error: Optional[str] = None


class UpdateVendorRequest(BaseModel):
    vendor_id: str
    concurrent_doctors: Optional[Union[int, None]] = None
    immediate_unblock: Optional[bool] = None
    rx_max_hold_time: Optional[int] = None
    rx_max_block_time: Optional[int] = None
    rx_notification_interval: Optional[int] = None
    delay_after_hold: Optional[int] = None


class UpdateVendorResponseData(BaseModel):
    message: str


class UpdateVendorResponse(BaseModel):
    data: UpdateVendorResponseData = None
    error: APIResponseError = None
