"""Receptions API resource."""

from __future__ import annotations

from typing import TYPE_CHECKING

from medelement_mis.models import (
    ColorCode,
    CreateReceptionRequest,
    CreateReceptionResponse,
    ReceptionDetail,
    RescheduleReceptionRequest,
    SearchReceptionPDRequest,
    SearchReceptionPDResponse,
    SearchReceptionRequest,
    SearchReceptionResponse,
)

if TYPE_CHECKING:
    from medelement_mis.client import MedelementClient


class ReceptionsAPI:
    """API resource for reception/appointment operations."""

    def __init__(self, client: MedelementClient) -> None:
        self._client = client

    def create(
        self,
        *,
        patient_code: int,
        specialist_code: int,
        company_cabinet_code: int,
        starttime: str,
        endtime: str,
        nomenclature_code: int | None = None,
        description: str | None = None,
        color_code: ColorCode | int | None = None,
    ) -> CreateReceptionResponse:
        """Create a new reception/appointment.

        POST /v1/doctor/reception

        Args:
            patient_code: Patient's profile code
            specialist_code: Specialist/doctor code
            company_cabinet_code: Cabinet code
            starttime: Start time in dd.mm.yyyy hh:mm format
            endtime: End time in dd.mm.yyyy hh:mm format
            nomenclature_code: Service/procedure code
            description: Appointment notes
            color_code: Color code for visual highlighting (0-9)

        Returns:
            CreateReceptionResponse with reception_code
        """
        request = CreateReceptionRequest(
            patient_code=patient_code,
            specialist_code=specialist_code,
            company_cabinet_code=company_cabinet_code,
            starttime=starttime,
            endtime=endtime,
            nomenclature_code=nomenclature_code,
            description=description,
            color_code=color_code,
        )

        response = self._client._request(
            "POST",
            "/v1/doctor/reception",
            json=request.model_dump(exclude_none=True),
        )
        self._client._raise_for_status(response)

        return CreateReceptionResponse.model_validate(response.json())

    def search(
        self,
        *,
        begin_datetime: str,
        end_datetime: str,
        patient_code: int | None = None,
        active: int | None = None,
        removed: int | None = None,
        paid: int | None = None,
        skip: int | None = None,
        only_ambulator: int | None = None,
    ) -> SearchReceptionResponse:
        """Search for receptions.

        POST /v2/doctor/reception/search

        Args:
            begin_datetime: Search start datetime
            end_datetime: Search end datetime
            patient_code: Filter by patient
            active: Filter by status (0=Closed, 1=Open)
            removed: Filter by removed status
            paid: Filter by paid status
            skip: Pagination offset
            only_ambulator: Only ambulatory visits

        Returns:
            SearchReceptionResponse with list of matching receptions
        """
        request = SearchReceptionRequest(
            begin_datetime=begin_datetime,
            end_datetime=end_datetime,
            patient_code=patient_code,
            active=active,
            removed=removed,
            paid=paid,
            skip=skip,
            only_ambulator=only_ambulator,
        )

        response = self._client._request(
            "POST",
            "/v2/doctor/reception/search",
            json=request.model_dump(exclude_none=True),
        )
        self._client._raise_for_status(response)

        return SearchReceptionResponse.model_validate(response.json())

    def search_pd(
        self,
        *,
        begin_datetime: str,
        end_datetime: str,
        patient_code: int | None = None,
        active: int | None = None,
        removed: int | None = None,
        paid: int | None = None,
        skip: int | None = None,
    ) -> SearchReceptionPDResponse:
        """Search for receptions with extended specialist details.

        POST /v3/doctor/reception/search_pd

        Args:
            begin_datetime: Search start datetime (dd.mm.yyyy)
            end_datetime: Search end datetime (dd.mm.yyyy)
            patient_code: Filter by patient
            active: Filter by status (0=Closed, 1=Open)
            removed: Filter by removed status
            paid: Filter by paid status
            skip: Pagination offset

        Returns:
            SearchReceptionPDResponse with extended reception details
        """
        request = SearchReceptionPDRequest(
            begin_datetime=begin_datetime,
            end_datetime=end_datetime,
            patient_code=patient_code,
            active=active,
            removed=removed,
            paid=paid,
            skip=skip,
        )

        response = self._client._request(
            "POST",
            "/v3/doctor/reception/search_pd",
            json=request.model_dump(exclude_none=True),
        )
        self._client._raise_for_status(response)

        return SearchReceptionPDResponse.model_validate(response.json())

    def remove(self, reception_code: int) -> None:
        """Delete a reception.

        POST /v2/doctor/reception/remove
        Only open, unpaid receptions can be deleted.

        Args:
            reception_code: Reception code to delete
        """
        response = self._client._request(
            "POST",
            "/v2/doctor/reception/remove",
            json={"reception_code": reception_code},
        )
        self._client._raise_for_status(response)

    def get(self, reception_code: int) -> ReceptionDetail:
        """Get reception details by code.

        GET /v1/doctor/reception/:reception_code

        Args:
            reception_code: Reception unique code

        Returns:
            ReceptionDetail with full reception information
        """
        response = self._client._request("GET", f"/v1/doctor/reception/{reception_code}")
        self._client._raise_for_status(response)

        return ReceptionDetail.model_validate(response.json())

    def reschedule(
        self,
        *,
        reception_code: int,
        doctor_code: int,
        start_time: str,
        end_time: str,
    ) -> None:
        """Reschedule a reception to a new time.

        POST /v2/doctor/reception/change_reception_date

        Args:
            reception_code: Reception code to reschedule
            doctor_code: Doctor code
            start_time: New start time in dd.mm.yyyy hh:mm format
            end_time: New end time in dd.mm.yyyy hh:mm format
        """
        request = RescheduleReceptionRequest(
            reception_code=reception_code,
            doctor_code=doctor_code,
            start_time=start_time,
            end_time=end_time,
        )

        response = self._client._request(
            "POST",
            "/v2/doctor/reception/change_reception_date",
            json=request.model_dump(exclude_none=True),
        )
        self._client._raise_for_status(response)
