## BookingAdmin Service (`Api/src/admin/booking/booking.admin.ts`)

This service is responsible for handling complex booking-related operations on the admin/backend side, intended primarily for use within Firebase Cloud Functions or other trusted server environments.

### Class: `BookingAdmin`

Manages booking availability calculations and the orchestration of appointment creation, including associated calendar events and documentation.

#### Constructor

```typescript
constructor(firestore?: admin.firestore.Firestore)
```

- **`firestore`**: An optional `admin.firestore.Firestore` instance. If not provided, it initializes a default Firestore instance.
- Initializes an instance of `DocumentManagerAdminService` for handling linked document operations.

---

#### Method: `getAvailableBookingSlots`

```typescript
async getAvailableBookingSlots(
  clinicId: string,
  practitionerId: string,
  procedureId: string,
  timeframe: { start: Date | admin.firestore.Timestamp; end: Date | admin.firestore.Timestamp; }
): Promise<{ availableSlots: { start: admin.firestore.Timestamp }[] }>
```

- Calculates and returns available booking time slots for a specified clinic, practitioner, and procedure within a given timeframe.
- **Steps Involved**:
  1.  Fetches data for the clinic, practitioner, and procedure.
  2.  Retrieves calendar events for both the clinic and the practitioner within the specified timeframe.
  3.  Converts admin Firestore Timestamps to a client-compatible format for the `BookingAvailabilityCalculator`.
  4.  Uses `BookingAvailabilityCalculator.calculateSlots()` to determine available slots based on working hours, existing events, and procedure duration.
  5.  Converts the resulting available slot timestamps back to admin Firestore Timestamps before returning.
- **Error Handling**: Throws an error if essential entities (clinic, practitioner, procedure) are not found or if any other issue occurs during the calculation.

---

#### Method: `orchestrateAppointmentCreation`

```typescript
async orchestrateAppointmentCreation(
  data: OrchestrateAppointmentCreationData, // { patientId, procedureId, appointmentStartTime, appointmentEndTime, patientNotes? }
  authenticatedUserId: string
): Promise<{
  success: boolean;
  appointmentId?: string;
  appointmentData?: Appointment;         // The created Appointment object
  practitionerCalendarEventId?: string; // ID of the practitioner's calendar event
  patientCalendarEventId?: string;      // ID of the patient's calendar event
  clinicCalendarEventId?: string;       // ID of the clinic's calendar event
  error?: string;
}>
```

- Orchestrates the comprehensive creation of a new appointment. This is a critical backend process that ensures data integrity and sets up all related entities atomically.
- **Input Data (`OrchestrateAppointmentCreationData`)**:
  - `patientId`: ID of the patient for whom the appointment is being booked.
  - `procedureId`: ID of the procedure.
  - `appointmentStartTime`: Firestore Timestamp for the start of the appointment.
  - `appointmentEndTime`: Firestore Timestamp for the end of the appointment.
  - `patientNotes` (optional): Any notes provided by the patient during booking.
- **`authenticatedUserId`**: The ID of the user making the request (typically the patient themselves, used for auditing and authorization checks).

- **Core Operations (performed within a single Firestore batch transaction)**:

  1.  **Input Validation**: Checks for required fields and valid timeframes.
  2.  **Data Fetching**: Retrieves all necessary documents:
      - `Procedure` (based on `data.procedureId`)
      - `Clinic` (based on `procedure.clinicBranchId`)
      - `Practitioner` (based on `procedure.practitionerId`)
      - `PatientProfile` and `PatientSensitiveInfo` (based on `data.patientId`)
      - `ClinicGroup` (based on `clinicData.clinicGroupId`)
  3.  **Information Aggregation**: Creates summarized info objects (`ClinicInfo`, `PractitionerProfileInfo`, `PatientProfileInfo`, `CalendarProcedureInfo`) from the fetched data.
  4.  **Status Determination**: Calculates the initial status for the appointment (`AppointmentStatus.CONFIRMED` or `PENDING`) and associated calendar events (`CalendarEventStatus.CONFIRMED` or `PENDING`) based on the `clinicGroupData.autoConfirmAppointments` setting.
  5.  **Calendar Event Creation**: For each of the practitioner, patient, and clinic:
      - Generates a unique ID for the calendar event.
      - Constructs the `CalendarEvent` data, including links to the appointment, relevant profiles, procedure details, event times, and status.
      - Adds a `set` operation to the Firestore batch for creating this calendar event in the respective entity's `calendar` subcollection (e.g., `practitioners/{id}/calendar/{eventId}`).
  6.  **Documentation Initialization (via `DocumentManagerAdminService`)**:
      - Calls `this.documentManagerAdmin.batchInitializeAppointmentForms()`.
      - This service method iterates through the `procedure.documentationTemplates`.
      - For each template, it creates a `FilledDocument` (in `DRAFT` or `PENDING` status) in the appropriate subcollection of the new appointment (`appointments/{newAppointmentId}/user-forms/{formId}` or `appointments/{newAppointmentId}/doctor-forms/{formId}`).
      - These creation operations are added to the _same Firestore batch_.
      - The method returns an object containing:
        - `initializedFormsInfo: LinkedFormInfo[]`: Detailed info for each initialized form.
        - `pendingUserFormsIds: string[]`: IDs of required user form templates.
        - `allLinkedTemplateIds: string[]`: IDs of all templates linked to the procedure.
  7.  **Appointment Object Construction**: Creates the main `Appointment` data object, populating all its fields, including:
      - `id`: The newly generated appointment ID.
      - `calendarEventId`: Linked to the `practitionerCalendarEventId`.
      - All aggregated info objects.
      - Timestamps (booking, confirmation, start, end), correctly using `FirebaseClientTimestamp` for client compatibility.
      - `pendingUserFormsIds` and `linkedFormIds`: Populated from the result of `batchInitializeAppointmentForms`.
      - `linkedForms`: Populated with the `initializedFormsInfo` array from `batchInitializeAppointmentForms`.
  8.  **Batch Commit**: Commits all the `set` operations (appointment, 3 calendar events, all filled documents) to Firestore. This ensures atomicity – either all documents are created, or none are.

- **Return Value**: On success, returns an object with `success: true`, the `appointmentId`, the full `appointmentData`, and the IDs of the three created calendar events. On failure, returns `success: false` and an error message.

---

### Helper Methods (Private)

- **`_generateCalendarProcedureInfo(procedure: Procedure): CalendarProcedureInfo`**
  - Creates a `CalendarProcedureInfo` object from a `Procedure` object, used when constructing `CalendarEvent` data.
- **`_generateProcedureSummaryInfo(procedure: Procedure, clinicData: Clinic, practitionerData: Practitioner): ProcedureSummaryInfo`**
  - Creates a `ProcedureSummaryInfo` object, used when constructing the `Appointment` data.
- **`_generateProcedureExtendedInfo(procedure: Procedure): ProcedureExtendedInfo`**
  - Creates a `ProcedureExtendedInfo` object, also used for the `Appointment` data.
- **`getPractitionerCalendarEvents(...)` / `getClinicCalendarEvents(...)`** (example, actual might vary if used by `getAvailableBookingSlots`)
  - Fetches calendar events for a specific entity within a time range.
- **Timestamp Conversion Utilities** (example, if present for `getAvailableBookingSlots`)
  - Handles conversions between admin and client Firestore Timestamp objects.

---

---

## Resource System Integration

### Resource Availability in `getAvailableBookingSlots`

When a procedure has `resourceRequirements`, the method performs additional steps:

1. **Resource Data Fetching**: For each resource requirement on the procedure:
   - Fetches the resource document and validates it is `active`
   - Fetches all active instances of the resource
   - For each instance, fetches calendar events within the timeframe (with 30-day lookback)
   - Converts admin timestamps to client-compatible format

2. **Builds `resourceCalendarEventsMap`**: A map keyed by `resourceId`, containing:
   ```typescript
   {
     resourceId: string;
     resourceName: string;
     quantity: number;
     instanceEvents: Record<string, ResourceCalendarEvent[]>; // keyed by instanceId
   }
   ```

3. **Passes to Calculator**: The map is included in the `BookingAvailabilityRequest` passed to `BookingAvailabilityCalculator.calculateSlots()`.

### Resource Allocation in `orchestrateAppointmentCreation`

After creating practitioner/patient/clinic calendar events, if the procedure has `resourceRequirements`:

1. For each requirement, iterates active instances sorted by index
2. For each instance, queries for overlapping events with active statuses (`PENDING`, `CONFIRMED`, `CHECKED_IN`, `IN_PROGRESS`)
3. Picks the **first free instance** (no overlapping active events)
4. Creates a `ResourceCalendarEvent` on the instance's calendar subcollection via the batch
5. Collects `ResourceBookingInfo` entries and adds them to the appointment document
6. If no free instance is found, returns `{ success: false, error: "Resource {name} not available..." }`

### BookingAvailabilityCalculator (`booking.calculator.ts`)

**Step 5 (new)**: After subtracting practitioner busy times:

- For each resource in `resourceCalendarEventsMap`:
  - Compute each instance's availability:
    - Subtract **blocking events** (any event with `eventType` BLOCKING/BREAK/FREE_DAY) regardless of status
    - Subtract **active booking events** (PENDING or CONFIRMED status) — events without `eventType` fall through to this check for backward compatibility
  - **Union** all instance availabilities (at least one must be free)
- **Intersect** all resource availabilities together
- Intersect with doctor availability → final availability

Key private methods:
- `applyResourceAvailability()`: Applies resource constraints to available intervals
- `computeResourceAvailability()`: Computes union of instance availabilities for a single resource
- `unionIntervals()`: Merges overlapping intervals from multiple instances

See [Resource System README](../../../../docs/RESOURCE_SYSTEM.md) for the full algorithm detail.

---

### Dependencies

- **`DocumentManagerAdminService`**: Used to handle the creation and management of `FilledDocument` instances associated with appointments.
- **`ResourceService`**: Used to fetch resources, instances, and calendar events for availability calculations and allocation.
- **Firebase Admin SDK**: For all Firestore interactions.
- **Various Type Definitions**: From `../../types/` for `Appointment`, `CalendarEvent`, `Procedure`, `Clinic`, `Practitioner`, `Patient`, `DocumentTemplate`, `LinkedFormInfo`, `Resource`, `ResourceInstance`, `ResourceCalendarEvent`, `ResourceBookingInfo`, etc.
- **`BookingAvailabilityCalculator`**: For calculating available booking slots (including resource constraints).
