/**
 * Healthcare Service API client — real backend only.
 * Base: NEXT_PUBLIC_HEALTHCARE_API_URL (default http://localhost:8010)
 * Always sends Authorization + X-Tenant-ID.
 */

import { getValidAccessToken, refreshSession } from "@/lib/auth";

const HEALTHCARE_BASE =
  typeof window !== "undefined"
    ? "/api/healthcare"
    : process.env.HEALTHCARE_SERVICE_URL ||
      process.env.NEXT_PUBLIC_HEALTHCARE_API_URL ||
      "http://localhost:8010";

export class HealthcareApiError extends Error {
  constructor(
    public status: number,
    public code: string,
    message: string
  ) {
    super(message);
    this.name = "HealthcareApiError";
  }
}

type RequestOptions = RequestInit & { tenantId: string; auth?: boolean; patientId?: string };

async function request<T>(path: string, options: RequestOptions): Promise<T> {
  const { tenantId, auth = true, patientId, headers: customHeaders, ...init } = options;
  const headers = new Headers(customHeaders);
  headers.set("Content-Type", "application/json");
  headers.set("X-Tenant-ID", tenantId);
  if (patientId) headers.set("X-Patient-ID", patientId);
  if (auth) {
    const token = await getValidAccessToken();
    if (token) headers.set("Authorization", `Bearer ${token}`);
  }

  const url = path.startsWith("http")
    ? path
    : `${HEALTHCARE_BASE.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;

  let res: Response;
  try {
    res = await fetch(url, { ...init, headers });
  } catch (err) {
    const detail = err instanceof Error ? err.message : "network_error";
    throw new Error(`اتصال به سرویس سلامت برقرار نشد (${url}) — ${detail}`);
  }

  if (res.status === 401 && auth) {
    const refreshed = await refreshSession({ force: true });
    if (refreshed) {
      headers.set("Authorization", `Bearer ${refreshed}`);
      res = await fetch(url, { ...init, headers });
    }
  }

  if (!res.ok) {
    const body = await res.json().catch(() => ({}));
    throw new HealthcareApiError(
      res.status,
      body?.error?.code || "unknown_error",
      body?.error?.message || res.statusText
    );
  }
  if (res.status === 204) return undefined as T;
  return res.json() as Promise<T>;
}

function qs(params?: Record<string, string | number | undefined | null>) {
  if (!params) return "";
  const sp = new URLSearchParams();
  Object.entries(params).forEach(([k, v]) => {
    if (v !== undefined && v !== null && v !== "") sp.set(k, String(v));
  });
  const s = sp.toString();
  return s ? `?${s}` : "";
}

export type LifecycleStatus = "draft" | "active" | "inactive" | "suspended" | "archived";
export type ProfileStatus = "pending" | "active" | "inactive" | "suspended" | "archived";
export type ProviderKind =
  | "communication"
  | "crm"
  | "loyalty"
  | "accounting"
  | "delivery"
  | "storage"
  | "ai"
  | "identity"
  | "custom";
export type ProviderStatus = "registered" | "active" | "inactive" | "failed" | "retired";

export type HealthResponse = {
  status: string;
  service: string;
  version: string;
};

export type CapabilitiesResponse = {
  service: string;
  version: string;
  phase: string;
  commercial_product: string;
  features: Record<string, boolean>;
  independence: {
    standalone: boolean;
    superapp: boolean;
    integrations: string[];
    integration_mode: string;
  };
};

export type MetricsResponse = {
  service: string;
  version: string;
  phase: string;
  metrics: Record<string, string | number>;
  note?: string;
};

export type Clinic = {
  id: string;
  tenant_id: string;
  code: string;
  name: string;
  description: string | null;
  status: LifecycleStatus;
  legal_name: string | null;
  timezone: string;
  language: string;
  currency_code: string;
  settings: Record<string, unknown> | null;
  version: number;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type Branch = {
  id: string;
  tenant_id: string;
  clinic_id: string;
  code: string;
  name: string;
  description: string | null;
  status: LifecycleStatus;
  address: Record<string, unknown> | null;
  timezone: string | null;
  working_hours: Record<string, unknown> | null;
  metadata_json: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type Department = {
  id: string;
  tenant_id: string;
  clinic_id: string;
  branch_id: string | null;
  code: string;
  name: string;
  description: string | null;
  status: LifecycleStatus;
  specialty: string | null;
  metadata_json: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type Doctor = {
  id: string;
  tenant_id: string;
  user_id: string;
  clinic_id: string | null;
  department_id: string | null;
  code: string;
  display_name: string;
  specialty: string | null;
  license_number: string | null;
  status: ProfileStatus;
  contact: Record<string, unknown> | null;
  metadata_json: Record<string, unknown> | null;
  version: number;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type Patient = {
  id: string;
  tenant_id: string;
  user_id: string;
  code: string;
  display_name: string;
  status: ProfileStatus;
  date_of_birth: string | null;
  gender: string | null;
  contact: Record<string, unknown> | null;
  emergency_contact: Record<string, unknown> | null;
  metadata_json: Record<string, unknown> | null;
  version: number;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type ExternalProvider = {
  id: string;
  tenant_id: string;
  clinic_id: string | null;
  code: string;
  name: string;
  provider_kind: ProviderKind;
  adapter_key: string;
  status: ProviderStatus;
  priority: number;
  credentials_ref: string | null;
  config: Record<string, unknown> | null;
  capabilities: Record<string, unknown> | null;
  version: number;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type HealthcareConfiguration = {
  id: string;
  tenant_id: string;
  clinic_id: string;
  branch_id: string | null;
  code: string;
  working_hours: Record<string, unknown> | null;
  clinical_policies: Record<string, unknown> | null;
  privacy_policies: Record<string, unknown> | null;
  custom_fields: Record<string, unknown> | null;
  timezone: string;
  language: string;
  currency_code: string;
  version: number;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type HealthcareSetting = {
  id: string;
  tenant_id: string;
  clinic_id: string | null;
  branch_id: string | null;
  key: string;
  value: Record<string, unknown> | null;
  description: string | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type HealthcareAuditLog = {
  id: string;
  tenant_id: string;
  entity_type: string;
  entity_id: string;
  action: string;
  actor_user_id: string | null;
  changes: Record<string, unknown> | null;
  message: string | null;
  created_at: string;
};

export type PermissionCatalog = {
  prefix: string;
  prefixes: string[];
  permissions: string[];
  count: number;
};

export type AppointmentListResponse = {
  items: Appointment[];
  total: number;
  page: number;
  page_size: number;
};

export type Appointment = {
  id: string;
  tenant_id: string;
  clinic_id: string;
  doctor_id: string;
  patient_id: string;
  department_id: string | null;
  appointment_type_id: string | null;
  code: string;
  status: string;
  scheduled_start: string;
  scheduled_end: string;
  notes: string | null;
  status_reason: string | null;
  version: number;
  created_at: string;
  updated_at: string;
};

export type Schedule = {
  id: string;
  clinic_id: string;
  doctor_id: string;
  code: string;
  name: string;
  day_of_week: string;
  start_time: string;
  end_time: string;
  slot_duration_minutes: number;
  is_active: boolean;
};

export type AvailabilityWindow = {
  id: string;
  clinic_id: string;
  doctor_id: string;
  code: string;
  starts_at: string;
  ends_at: string;
  is_bookable: boolean;
};

export type AppointmentType = {
  id: string;
  clinic_id: string;
  code: string;
  name: string;
  default_duration_minutes: number;
  status: string;
};

export type WaitingListEntry = {
  id: string;
  clinic_id: string;
  doctor_id: string | null;
  patient_id: string;
  code: string;
  preferred_date: string | null;
  priority: number;
};

export type DoctorDashboard = {
  doctor_id: string;
  queued_count: number;
  in_progress_count: number;
  completed_today_count: number;
  upcoming_appointments: Appointment[];
};

export type DoctorQueue = {
  doctor_id: string;
  items: VisitSession[];
};

export type VisitSession = {
  id: string;
  clinic_id: string;
  doctor_id: string;
  patient_id: string;
  appointment_id: string;
  code: string;
  status: string;
  queue_position: number;
  version: number;
  started_at: string | null;
  finished_at: string | null;
};

export type VisitNote = {
  id: string;
  visit_session_id: string;
  doctor_id: string;
  code: string;
  title: string;
  body: string | null;
  version: number;
};

export type ClinicService = {
  id: string;
  clinic_id: string;
  code: string;
  name: string;
  duration_minutes: number;
  status: string;
};

export type StaffAssignment = {
  id: string;
  clinic_id: string;
  doctor_id: string;
  code: string;
  role_code: string;
  is_primary: boolean;
};

export type ClinicPolicy = {
  id: string;
  clinic_id: string;
  code: string;
  name: string;
  kind: string;
  booking_lead_time_hours: number;
  cancellation_window_hours: number;
};

export type OperatingHoursPolicy = {
  id: string;
  clinic_id: string;
  code: string;
  name: string;
  timezone: string;
};

export type PatientPortalProfile = {
  id: string;
  patient_id: string;
  preferred_clinic_id: string | null;
  preferred_language: string;
  version: number;
};

export type PatientDocumentRef = {
  id: string;
  patient_id: string;
  code: string;
  title: string;
  storage_file_ref: string;
  document_type: string | null;
};

export type PatientNotificationPreference = {
  id: string;
  patient_id: string;
  channel: string;
  template_key: string;
  enabled: boolean;
};

export type MedicalRecord = {
  id: string;
  clinic_id: string;
  patient_id: string;
  code: string;
  version: number;
};

export type ClinicalLists = {
  conditions: ClinicalItem[];
  allergies: ClinicalItem[];
  medications: ClinicalItem[];
  immunizations: ClinicalItem[];
};

export type ClinicalItem = {
  id: string;
  code: string;
  display?: string;
  substance?: string;
  vaccine_code?: string;
};

export type Encounter = {
  id: string;
  medical_record_id: string;
  doctor_id: string;
  code: string;
  status: string;
  chief_complaint: string | null;
  clinical_summary: string | null;
  version: number;
};

export type Pharmacy = {
  id: string;
  code: string;
  name: string;
  status: string;
  version: number;
};

export type PrescriptionOrder = {
  id: string;
  pharmacy_id: string;
  patient_id: string;
  doctor_id: string;
  code: string;
  status: string;
  version: number;
};

export type DeliveryIntegration = {
  id: string;
  clinic_id: string | null;
  pharmacy_id: string | null;
  code: string;
  name: string;
  delivery_merchant_ref: string;
  status: string;
  version: number;
};

export type DeliveryJobIntent = {
  id: string;
  registration_id: string;
  prescription_order_id: string;
  code: string;
  delivery_job_ref: string | null;
  status: string;
  idempotency_key: string;
  version: number;
};

export const healthcareApi = {
  health: () =>
    fetch(`${HEALTHCARE_BASE}/health`).then((r) => r.json() as Promise<HealthResponse>),

  capabilities: () =>
    fetch(`${HEALTHCARE_BASE}/capabilities`).then((r) => r.json() as Promise<CapabilitiesResponse>),

  metrics: () =>
    fetch(`${HEALTHCARE_BASE}/metrics`).then((r) => r.json() as Promise<MetricsResponse>),

  clinics: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Clinic[]>(`/api/v1/clinics${qs({ page, page_size: pageSize })}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Clinic>(`/api/v1/clinics/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        code: string;
        name: string;
        description?: string;
        status?: LifecycleStatus;
        legal_name?: string;
        timezone?: string;
        language?: string;
        currency_code?: string;
      }
    ) =>
      request<Clinic>("/api/v1/clinics", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        name: string;
        description: string;
        status: LifecycleStatus;
        legal_name: string;
        timezone: string;
        language: string;
        currency_code: string;
        version: number;
      }>
    ) =>
      request<Clinic>(`/api/v1/clinics/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<Clinic>(`/api/v1/clinics/${id}/delete`, { tenantId, method: "POST" }),
  },

  branches: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Branch[]>(`/api/v1/branches${qs({ page, page_size: pageSize })}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Branch>(`/api/v1/branches/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        clinic_id: string;
        code: string;
        name: string;
        description?: string;
        status?: LifecycleStatus;
      }
    ) =>
      request<Branch>("/api/v1/branches", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        name: string;
        description: string;
        status: LifecycleStatus;
      }>
    ) =>
      request<Branch>(`/api/v1/branches/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<Branch>(`/api/v1/branches/${id}/delete`, { tenantId, method: "POST" }),
  },

  departments: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Department[]>(`/api/v1/departments${qs({ page, page_size: pageSize })}`, {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<Department>(`/api/v1/departments/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        clinic_id: string;
        branch_id?: string;
        code: string;
        name: string;
        description?: string;
        status?: LifecycleStatus;
        specialty?: string;
      }
    ) =>
      request<Department>("/api/v1/departments", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        branch_id: string | null;
        name: string;
        description: string;
        status: LifecycleStatus;
        specialty: string;
      }>
    ) =>
      request<Department>(`/api/v1/departments/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<Department>(`/api/v1/departments/${id}/delete`, { tenantId, method: "POST" }),
  },

  doctors: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Doctor[]>(`/api/v1/doctors${qs({ page, page_size: pageSize })}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Doctor>(`/api/v1/doctors/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        user_id: string;
        clinic_id?: string;
        department_id?: string;
        code: string;
        display_name: string;
        specialty?: string;
        license_number?: string;
        status?: ProfileStatus;
      }
    ) =>
      request<Doctor>("/api/v1/doctors", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        clinic_id: string | null;
        department_id: string | null;
        display_name: string;
        specialty: string;
        license_number: string;
        status: ProfileStatus;
        version: number;
      }>
    ) =>
      request<Doctor>(`/api/v1/doctors/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<Doctor>(`/api/v1/doctors/${id}/delete`, { tenantId, method: "POST" }),
  },

  patients: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Patient[]>(`/api/v1/patients${qs({ page, page_size: pageSize })}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Patient>(`/api/v1/patients/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        user_id: string;
        code: string;
        display_name: string;
        status?: ProfileStatus;
        date_of_birth?: string;
        gender?: string;
      }
    ) =>
      request<Patient>("/api/v1/patients", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        display_name: string;
        status: ProfileStatus;
        date_of_birth: string;
        gender: string;
        version: number;
      }>
    ) =>
      request<Patient>(`/api/v1/patients/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<Patient>(`/api/v1/patients/${id}/delete`, { tenantId, method: "POST" }),
  },

  externalProviders: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<ExternalProvider[]>(
        `/api/v1/external-providers${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    get: (tenantId: string, id: string) =>
      request<ExternalProvider>(`/api/v1/external-providers/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        clinic_id?: string;
        code: string;
        name: string;
        provider_kind?: ProviderKind;
        adapter_key: string;
        status?: ProviderStatus;
        priority?: number;
      }
    ) =>
      request<ExternalProvider>("/api/v1/external-providers", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        name: string;
        provider_kind: ProviderKind;
        adapter_key: string;
        status: ProviderStatus;
        priority: number;
        version: number;
      }>
    ) =>
      request<ExternalProvider>(`/api/v1/external-providers/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<ExternalProvider>(`/api/v1/external-providers/${id}/delete`, {
        tenantId,
        method: "POST",
      }),
  },

  configurations: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<HealthcareConfiguration[]>(
        `/api/v1/configurations${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    get: (tenantId: string, id: string) =>
      request<HealthcareConfiguration>(`/api/v1/configurations/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        clinic_id: string;
        branch_id?: string;
        code: string;
        timezone?: string;
        language?: string;
        currency_code?: string;
      }
    ) =>
      request<HealthcareConfiguration>("/api/v1/configurations", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        branch_id: string | null;
        timezone: string;
        language: string;
        currency_code: string;
        version: number;
      }>
    ) =>
      request<HealthcareConfiguration>(`/api/v1/configurations/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<HealthcareConfiguration>(`/api/v1/configurations/${id}/delete`, {
        tenantId,
        method: "POST",
      }),
  },

  settings: {
    list: (tenantId: string, page = 1, pageSize = 100) =>
      request<HealthcareSetting[]>(`/api/v1/settings${qs({ page, page_size: pageSize })}`, {
        tenantId,
      }),
    upsert: (
      tenantId: string,
      body: {
        clinic_id?: string;
        branch_id?: string;
        key: string;
        value?: Record<string, unknown>;
        description?: string;
      }
    ) =>
      request<HealthcareSetting>("/api/v1/settings", {
        tenantId,
        method: "PUT",
        body: JSON.stringify(body),
      }),
  },

  audit: {
    list: (tenantId: string, entityType: string, entityId: string, limit = 100) =>
      request<HealthcareAuditLog[]>(
        `/api/v1/audit${qs({ entity_type: entityType, entity_id: entityId, limit })}`,
        { tenantId }
      ),
  },

  permissions: {
    catalog: (tenantId: string) =>
      request<PermissionCatalog>("/api/v1/permissions/catalog", { tenantId }),
  },

  schedules: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Schedule[]>(`/api/v1/schedules${qs({ page, page_size: pageSize })}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Schedule>("/api/v1/schedules", { tenantId, method: "POST", body: JSON.stringify(body) }),
  },

  availabilityWindows: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<AvailabilityWindow[]>(
        `/api/v1/availability-windows${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<AvailabilityWindow>("/api/v1/availability-windows", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  appointmentTypes: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<AppointmentType[]>(
        `/api/v1/appointment-types${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<AppointmentType>("/api/v1/appointment-types", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  appointments: {
    list: (
      tenantId: string,
      params?: {
        page?: number;
        page_size?: number;
        status?: string;
        doctor_id?: string;
        clinic_id?: string;
        patient_id?: string;
      }
    ) =>
      request<AppointmentListResponse>(`/api/v1/appointments${qs(params)}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Appointment>(`/api/v1/appointments/${id}`, { tenantId }),
    book: (tenantId: string, body: Record<string, unknown>) =>
      request<Appointment>("/api/v1/appointments", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    confirm: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<Appointment>(`/api/v1/appointments/${id}/confirm`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    cancel: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<Appointment>(`/api/v1/appointments/${id}/cancel`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    reschedule: (
      tenantId: string,
      id: string,
      body: { scheduled_start: string; scheduled_end: string; version: number; reason?: string }
    ) =>
      request<Appointment>(`/api/v1/appointments/${id}/reschedule`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    noShow: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<Appointment>(`/api/v1/appointments/${id}/no-show`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  waitingList: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<WaitingListEntry[]>(`/api/v1/waiting-list${qs({ page, page_size: pageSize })}`, {
        tenantId,
      }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<WaitingListEntry>("/api/v1/waiting-list", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  doctorPanel: {
    dashboard: (tenantId: string, doctorId: string) =>
      request<DoctorDashboard>(`/api/v1/doctor-panel/dashboard${qs({ doctor_id: doctorId })}`, {
        tenantId,
      }),
    queue: (tenantId: string, doctorId: string) =>
      request<DoctorQueue>(`/api/v1/doctor-panel/queue${qs({ doctor_id: doctorId })}`, {
        tenantId,
      }),
  },

  visitSessions: {
    list: (
      tenantId: string,
      params?: { page?: number; page_size?: number; doctor_id?: string; clinic_id?: string; status?: string }
    ) =>
      request<VisitSession[]>(`/api/v1/visit-sessions${qs(params)}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<VisitSession>(`/api/v1/visit-sessions/${id}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<VisitSession>("/api/v1/visit-sessions", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    start: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<VisitSession>(`/api/v1/visit-sessions/${id}/start`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    finish: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<VisitSession>(`/api/v1/visit-sessions/${id}/finish`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    defer: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<VisitSession>(`/api/v1/visit-sessions/${id}/defer`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    callNext: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<VisitSession>(`/api/v1/visit-sessions/${id}/call-next`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  visitNotes: {
    list: (tenantId: string, visitSessionId: string) =>
      request<VisitNote[]>(
        `/api/v1/visit-notes${qs({ visit_session_id: visitSessionId })}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<VisitNote>("/api/v1/visit-notes", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{ title: string; body: string; version: number }>
    ) =>
      request<VisitNote>(`/api/v1/visit-notes/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
  },

  clinicServices: {
    list: (tenantId: string, clinicId?: string, page = 1, pageSize = 50) =>
      request<ClinicService[]>(
        `/api/v1/clinic-services${qs({ clinic_id: clinicId, page, page_size: pageSize })}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<ClinicService>("/api/v1/clinic-services", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  staffAssignments: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<StaffAssignment[]>(
        `/api/v1/staff-assignments${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<StaffAssignment>("/api/v1/staff-assignments", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  clinicPolicies: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<ClinicPolicy[]>(
        `/api/v1/clinic-policies${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<ClinicPolicy>("/api/v1/clinic-policies", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  operatingHoursPolicies: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<OperatingHoursPolicy[]>(
        `/api/v1/operating-hours-policies${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<OperatingHoursPolicy>("/api/v1/operating-hours-policies", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  patientPortal: {
    me: (tenantId: string, patientId: string) =>
      request<PatientPortalProfile>("/api/v1/patient-portal/me", { tenantId, patientId }),
    updateMe: (
      tenantId: string,
      patientId: string,
      body: Partial<{ preferred_language: string; version: number }>
    ) =>
      request<PatientPortalProfile>("/api/v1/patient-portal/me", {
        tenantId,
        patientId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    appointments: (tenantId: string, patientId: string) =>
      request<AppointmentListResponse>("/api/v1/patient-portal/appointments", {
        tenantId,
        patientId,
      }),
    bookAppointment: (tenantId: string, patientId: string, body: Record<string, unknown>) =>
      request<Appointment>("/api/v1/patient-portal/appointments", {
        tenantId,
        patientId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    cancelAppointment: (
      tenantId: string,
      patientId: string,
      appointmentId: string,
      body: { version: number; reason?: string }
    ) =>
      request<Appointment>(`/api/v1/patient-portal/appointments/${appointmentId}/cancel`, {
        tenantId,
        patientId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    documents: (tenantId: string, patientId: string) =>
      request<PatientDocumentRef[]>("/api/v1/patient-portal/documents", { tenantId, patientId }),
    createDocument: (tenantId: string, patientId: string, body: Record<string, unknown>) =>
      request<PatientDocumentRef>("/api/v1/patient-portal/documents", {
        tenantId,
        patientId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    notificationPreferences: (tenantId: string, patientId: string) =>
      request<PatientNotificationPreference[]>(
        "/api/v1/patient-portal/notification-preferences",
        { tenantId, patientId }
      ),
    upsertNotificationPreference: (
      tenantId: string,
      patientId: string,
      body: { channel: string; template_key: string; enabled?: boolean }
    ) =>
      request<PatientNotificationPreference>(
        "/api/v1/patient-portal/notification-preferences",
        { tenantId, patientId, method: "PUT", body: JSON.stringify(body) }
      ),
  },

  medicalRecords: {
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<MedicalRecord>("/api/v1/medical-records", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    get: (tenantId: string, id: string, reason?: string) =>
      request<MedicalRecord>(
        `/api/v1/medical-records/${id}${qs({ reason })}`,
        { tenantId }
      ),
    clinicalLists: (tenantId: string, recordId: string) =>
      request<ClinicalLists>(`/api/v1/medical-records/${recordId}/clinical-lists`, { tenantId }),
    addCondition: (tenantId: string, recordId: string, body: Record<string, unknown>) =>
      request<ClinicalItem>(`/api/v1/medical-records/${recordId}/conditions`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    addAllergy: (tenantId: string, recordId: string, body: Record<string, unknown>) =>
      request<ClinicalItem>(`/api/v1/medical-records/${recordId}/allergies`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    addMedication: (tenantId: string, recordId: string, body: Record<string, unknown>) =>
      request<ClinicalItem>(`/api/v1/medical-records/${recordId}/medications`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    addImmunization: (tenantId: string, recordId: string, body: Record<string, unknown>) =>
      request<ClinicalItem>(`/api/v1/medical-records/${recordId}/immunizations`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  encounters: {
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Encounter>("/api/v1/encounters", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{ chief_complaint: string; clinical_summary: string; version: number }>
    ) =>
      request<Encounter>(`/api/v1/encounters/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    finalize: (tenantId: string, id: string, body: { version: number; addendum?: string }) =>
      request<Encounter>(`/api/v1/encounters/${id}/finalize`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  pharmacies: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Pharmacy[]>(`/api/v1/pharmacies${qs({ page, page_size: pageSize })}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Pharmacy>("/api/v1/pharmacies", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  prescriptionOrders: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<PrescriptionOrder[]>(
        `/api/v1/prescription-orders${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    get: (tenantId: string, id: string) =>
      request<PrescriptionOrder>(`/api/v1/prescription-orders/${id}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<PrescriptionOrder>("/api/v1/prescription-orders", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    accept: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<PrescriptionOrder>(`/api/v1/prescription-orders/${id}/accept`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    prepare: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<PrescriptionOrder>(`/api/v1/prescription-orders/${id}/prepare`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    markReady: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<PrescriptionOrder>(`/api/v1/prescription-orders/${id}/mark-ready`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    completePickup: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<PrescriptionOrder>(`/api/v1/prescription-orders/${id}/complete-pickup`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    cancel: (tenantId: string, id: string, body: { version: number; reason?: string }) =>
      request<PrescriptionOrder>(`/api/v1/prescription-orders/${id}/cancel`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  deliveryIntegrations: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<DeliveryIntegration[]>(
        `/api/v1/delivery-integrations${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<DeliveryIntegration>("/api/v1/delivery-integrations", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  deliveryJobIntents: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<DeliveryJobIntent[]>(
        `/api/v1/delivery-job-intents${qs({ page, page_size: pageSize })}`,
        { tenantId }
      ),
    createForOrder: (
      tenantId: string,
      prescriptionOrderId: string,
      body: Record<string, unknown>
    ) =>
      request<DeliveryJobIntent>(
        `/api/v1/delivery-job-intents/prescription-orders/${prescriptionOrderId}`,
        { tenantId, method: "POST", body: JSON.stringify(body) }
      ),
  },
};
