/**
 * Beauty Business Service API client — real backend only.
 * Base: NEXT_PUBLIC_BEAUTY_BUSINESS_API_URL (default http://localhost:8011)
 * Always sends Authorization + X-Tenant-ID.
 */

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

const BEAUTY_BASE =
  typeof window !== "undefined"
    ? "/api/beauty-business"
    : process.env.BEAUTY_BUSINESS_SERVICE_URL ||
      process.env.NEXT_PUBLIC_BEAUTY_BUSINESS_API_URL ||
      "http://localhost:8011";

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

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

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

  const url = path.startsWith("http")
    ? path
    : `${BEAUTY_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 BeautyBusinessApiError(
      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 BusinessFormat = "salon" | "clinic" | "spa" | "barbershop" | "mixed";
export type ProviderKind =
  | "communication"
  | "crm"
  | "loyalty"
  | "accounting"
  | "delivery"
  | "storage"
  | "ai"
  | "identity"
  | "custom";
export type ProviderStatus = "registered" | "active" | "inactive" | "failed" | "retired";
export type BookingEngineStatus = "registered" | "active" | "inactive" | "failed" | "retired";
export type AppointmentStatus =
  | "requested"
  | "confirmed"
  | "checked_in"
  | "in_progress"
  | "completed"
  | "cancelled"
  | "no_show";
export type ServiceStatus = "draft" | "active" | "inactive" | "archived";
export type ResourceStatus = "available" | "occupied" | "maintenance" | "inactive";
export type StaffKind = "stylist" | "therapist" | "receptionist" | "manager" | "other";
export type DayOfWeek =
  | "monday"
  | "tuesday"
  | "wednesday"
  | "thursday"
  | "friday"
  | "saturday"
  | "sunday";
export type ScheduleExceptionKind = "closed" | "modified_hours" | "holiday";
export type IntegrationDispatchStatus = "pending" | "sent" | "failed" | "skipped";

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 Organization = {
  id: string;
  tenant_id: string;
  code: string;
  name: string;
  description: string | null;
  status: LifecycleStatus;
  business_format: BusinessFormat;
  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;
  organization_id: string;
  code: string;
  name: string;
  description: string | null;
  status: LifecycleStatus;
  business_format: BusinessFormat | null;
  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 ExternalProvider = {
  id: string;
  tenant_id: string;
  organization_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 BookingEngine = {
  id: string;
  tenant_id: string;
  organization_id: string | null;
  code: string;
  name: string;
  adapter_key: string;
  status: BookingEngineStatus;
  is_default: boolean;
  config: Record<string, unknown> | null;
  capabilities: Record<string, unknown> | null;
  version: number;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type Configuration = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string | null;
  code: string;
  working_hours: Record<string, unknown> | null;
  booking_policies: Record<string, unknown> | null;
  cancellation_policies: Record<string, unknown> | null;
  reminder_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 Setting = {
  id: string;
  tenant_id: string;
  organization_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 AuditLog = {
  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 StaffSchedule = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string;
  staff_ref: string;
  code: string;
  day_of_week: DayOfWeek;
  start_time: string;
  end_time: string;
  is_active: boolean;
  metadata_json: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type StaffAvailability = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string;
  staff_ref: string;
  code: string;
  starts_at: string;
  ends_at: string;
  is_bookable: boolean;
  metadata_json: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type ScheduleException = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string;
  staff_ref: string | null;
  code: string;
  kind: ScheduleExceptionKind;
  exception_date: string;
  start_time: string | null;
  end_time: string | null;
  reason: string | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type AppointmentType = {
  id: string;
  tenant_id: string;
  organization_id: string;
  code: string;
  name: string;
  description: string | null;
  default_duration_minutes: number;
  status: LifecycleStatus;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type Appointment = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string;
  appointment_type_id: string | null;
  code: string;
  customer_ref: string | null;
  staff_ref: string | null;
  room_ref: string | null;
  service_ref: string | null;
  status: AppointmentStatus;
  scheduled_start: string;
  scheduled_end: string;
  notes: string | null;
  status_reason: string | null;
  status_changed_at: string | null;
  metadata_json: Record<string, unknown> | null;
  version: number;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type AppointmentStatusHistory = {
  id: string;
  tenant_id: string;
  appointment_id: string;
  action: string;
  from_status: AppointmentStatus;
  to_status: AppointmentStatus;
  reason: string | null;
  actor_user_id: string | null;
  metadata_json: Record<string, unknown> | null;
  created_at: string;
};

export type WaitingListEntry = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string;
  code: string;
  customer_ref: string | null;
  service_ref: string | null;
  preferred_staff_ref: string | null;
  requested_date: string | null;
  notes: string | null;
  priority: number;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type TreatmentRoom = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string;
  code: string;
  name: string;
  description: string | null;
  status: ResourceStatus;
  capacity: number;
  metadata_json: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type Station = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string;
  room_id: string | null;
  code: string;
  name: string;
  status: ResourceStatus;
  metadata_json: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type BranchPolicy = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string;
  code: string;
  name: string;
  policy_type: string;
  rules: Record<string, unknown> | null;
  status: LifecycleStatus;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type ServiceCategory = {
  id: string;
  tenant_id: string;
  organization_id: string;
  code: string;
  name: string;
  description: string | null;
  status: LifecycleStatus;
  sort_order: number;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type BeautyService = {
  id: string;
  tenant_id: string;
  organization_id: string;
  category_id: string | null;
  code: string;
  name: string;
  description: string | null;
  status: ServiceStatus;
  base_duration_minutes: number;
  base_price: number | null;
  metadata_json: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type CustomerProfile = {
  id: string;
  tenant_id: string;
  organization_id: string;
  code: string;
  display_name: string;
  external_crm_contact_ref: string | null;
  external_user_ref: string | null;
  mobile: string | null;
  email: string | null;
  status: LifecycleStatus;
  metadata_json: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type PackageDefinition = {
  id: string;
  tenant_id: string;
  organization_id: string;
  code: string;
  name: string;
  description: string | null;
  total_sessions: number;
  price: number | null;
  valid_days: number | null;
  status: LifecycleStatus;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type MembershipPlan = {
  id: string;
  tenant_id: string;
  organization_id: string;
  code: string;
  name: string;
  description: string | null;
  billing_interval_days: number;
  price: number | null;
  benefits: Record<string, unknown> | null;
  status: LifecycleStatus;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type StaffProfile = {
  id: string;
  tenant_id: string;
  organization_id: string;
  branch_id: string | null;
  code: string;
  display_name: string;
  kind: StaffKind;
  external_user_ref: string | null;
  mobile: string | null;
  email: string | null;
  status: LifecycleStatus;
  hire_date: string | null;
  metadata_json: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type CommissionRule = {
  id: string;
  tenant_id: string;
  organization_id: string;
  code: string;
  name: string;
  rule_type: string;
  rate_percent: number | null;
  flat_amount: number | null;
  applies_to_service_id: string | null;
  status: LifecycleStatus;
  config: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type MarketingCampaign = {
  id: string;
  tenant_id: string;
  organization_id: string | null;
  branch_id: string | null;
  code: string;
  name: string;
  external_campaign_ref: string | null;
  channel: string | null;
  status: LifecycleStatus;
  config: Record<string, unknown> | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type LoyaltyIntegration = {
  id: string;
  tenant_id: string;
  organization_id: string | null;
  code: string;
  name: string;
  external_program_ref: string | null;
  earn_rules: Record<string, unknown> | null;
  status: LifecycleStatus;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type CommunicationIntegration = {
  id: string;
  tenant_id: string;
  organization_id: string | null;
  code: string;
  name: string;
  template_mappings: Record<string, unknown> | null;
  status: LifecycleStatus;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

export type IntegrationDispatch = {
  id: string;
  tenant_id: string;
  organization_id: string | null;
  integration_kind: string;
  config_id: string | null;
  event_type: string;
  payload_ref: string | null;
  status: IntegrationDispatchStatus;
  response_json: Record<string, unknown> | null;
  notes: string | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
};

type PaginatedList = { page?: number; pageSize?: number };

function listPath(base: string, { page = 1, pageSize = 50 }: PaginatedList = {}) {
  return `${base}${qs({ page, page_size: pageSize })}`;
}

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

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

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

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

  branches: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Branch[]>(listPath("/api/v1/branches", { page, pageSize }), { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Branch>(`/api/v1/branches/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_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" }),
  },

  externalProviders: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<ExternalProvider[]>(listPath("/api/v1/external-providers", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<ExternalProvider>(`/api/v1/external-providers/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_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",
      }),
  },

  bookingEngines: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<BookingEngine[]>(listPath("/api/v1/booking-engines", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<BookingEngine>(`/api/v1/booking-engines/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id?: string;
        code: string;
        name: string;
        adapter_key: string;
        status?: BookingEngineStatus;
        is_default?: boolean;
      }
    ) =>
      request<BookingEngine>("/api/v1/booking-engines", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        name: string;
        adapter_key: string;
        status: BookingEngineStatus;
        is_default: boolean;
        version: number;
      }>
    ) =>
      request<BookingEngine>(`/api/v1/booking-engines/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<BookingEngine>(`/api/v1/booking-engines/${id}/delete`, {
        tenantId,
        method: "POST",
      }),
  },

  configurations: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Configuration[]>(listPath("/api/v1/configurations", { page, pageSize }), { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Configuration>(`/api/v1/configurations/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id?: string;
        code: string;
        timezone?: string;
        language?: string;
        currency_code?: string;
      }
    ) =>
      request<Configuration>("/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<Configuration>(`/api/v1/configurations/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<Configuration>(`/api/v1/configurations/${id}/delete`, {
        tenantId,
        method: "POST",
      }),
  },

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

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

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

  staffSchedules: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<StaffSchedule[]>(listPath("/api/v1/staff-schedules", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<StaffSchedule>(`/api/v1/staff-schedules/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id: string;
        staff_ref: string;
        code: string;
        day_of_week: DayOfWeek;
        start_time: string;
        end_time: string;
        is_active?: boolean;
      }
    ) =>
      request<StaffSchedule>("/api/v1/staff-schedules", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  staffAvailabilities: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<StaffAvailability[]>(listPath("/api/v1/staff-availabilities", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<StaffAvailability>(`/api/v1/staff-availabilities/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id: string;
        staff_ref: string;
        code: string;
        starts_at: string;
        ends_at: string;
        is_bookable?: boolean;
      }
    ) =>
      request<StaffAvailability>("/api/v1/staff-availabilities", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  scheduleExceptions: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<ScheduleException[]>(listPath("/api/v1/schedule-exceptions", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<ScheduleException>(`/api/v1/schedule-exceptions/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id: string;
        staff_ref?: string;
        code: string;
        kind: ScheduleExceptionKind;
        exception_date: string;
        start_time?: string;
        end_time?: string;
        reason?: string;
      }
    ) =>
      request<ScheduleException>("/api/v1/schedule-exceptions", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  appointmentTypes: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<AppointmentType[]>(listPath("/api/v1/appointment-types", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<AppointmentType>(`/api/v1/appointment-types/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        code: string;
        name: string;
        description?: string;
        default_duration_minutes?: number;
        status?: LifecycleStatus;
      }
    ) =>
      request<AppointmentType>("/api/v1/appointment-types", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  appointments: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Appointment[]>(listPath("/api/v1/appointments", { page, pageSize }), { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Appointment>(`/api/v1/appointments/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id: string;
        code: string;
        scheduled_start: string;
        scheduled_end: string;
        appointment_type_id?: string;
        customer_ref?: string;
        staff_ref?: string;
        room_ref?: string;
        service_ref?: string;
        status?: AppointmentStatus;
        notes?: string;
      }
    ) =>
      request<Appointment>("/api/v1/appointments", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        staff_ref: string;
        room_ref: string;
        service_ref: string;
        scheduled_start: string;
        scheduled_end: string;
        notes: string;
        version: number;
      }>
    ) =>
      request<Appointment>(`/api/v1/appointments/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    confirm: (tenantId: string, id: string, body: { reason?: string; version: number }) =>
      request<Appointment>(`/api/v1/appointments/${id}/confirm`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    checkIn: (tenantId: string, id: string, body: { reason?: string; version: number }) =>
      request<Appointment>(`/api/v1/appointments/${id}/check-in`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    complete: (tenantId: string, id: string, body: { reason?: string; version: number }) =>
      request<Appointment>(`/api/v1/appointments/${id}/complete`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    cancel: (tenantId: string, id: string, body: { reason?: string; version: number }) =>
      request<Appointment>(`/api/v1/appointments/${id}/cancel`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    noShow: (tenantId: string, id: string, body: { reason?: string; version: number }) =>
      request<Appointment>(`/api/v1/appointments/${id}/no-show`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    history: (tenantId: string, id: string) =>
      request<AppointmentStatusHistory[]>(`/api/v1/appointments/${id}/history`, { tenantId }),
  },

  waitingList: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<WaitingListEntry[]>(listPath("/api/v1/waiting-list", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<WaitingListEntry>(`/api/v1/waiting-list/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id: string;
        code: string;
        customer_ref?: string;
        service_ref?: string;
        preferred_staff_ref?: string;
        requested_date?: string;
        notes?: string;
        priority?: number;
      }
    ) =>
      request<WaitingListEntry>("/api/v1/waiting-list", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  treatmentRooms: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<TreatmentRoom[]>(listPath("/api/v1/treatment-rooms", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<TreatmentRoom>(`/api/v1/treatment-rooms/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id: string;
        code: string;
        name: string;
        description?: string;
        status?: ResourceStatus;
        capacity?: number;
      }
    ) =>
      request<TreatmentRoom>("/api/v1/treatment-rooms", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  stations: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<Station[]>(listPath("/api/v1/stations", { page, pageSize }), { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Station>(`/api/v1/stations/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id: string;
        room_id?: string;
        code: string;
        name: string;
        status?: ResourceStatus;
      }
    ) =>
      request<Station>("/api/v1/stations", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  branchPolicies: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<BranchPolicy[]>(listPath("/api/v1/branch-policies", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<BranchPolicy>(`/api/v1/branch-policies/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id: string;
        code: string;
        name: string;
        policy_type: string;
        rules?: Record<string, unknown>;
        status?: LifecycleStatus;
      }
    ) =>
      request<BranchPolicy>("/api/v1/branch-policies", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  serviceCategories: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<ServiceCategory[]>(listPath("/api/v1/service-categories", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<ServiceCategory>(`/api/v1/service-categories/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        code: string;
        name: string;
        description?: string;
        status?: LifecycleStatus;
        sort_order?: number;
      }
    ) =>
      request<ServiceCategory>("/api/v1/service-categories", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  services: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<BeautyService[]>(listPath("/api/v1/services", { page, pageSize }), { tenantId }),
    get: (tenantId: string, id: string) =>
      request<BeautyService>(`/api/v1/services/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        category_id?: string;
        code: string;
        name: string;
        description?: string;
        status?: ServiceStatus;
        base_duration_minutes?: number;
        base_price?: number;
      }
    ) =>
      request<BeautyService>("/api/v1/services", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  customers: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<CustomerProfile[]>(listPath("/api/v1/customers", { page, pageSize }), { tenantId }),
    get: (tenantId: string, id: string) =>
      request<CustomerProfile>(`/api/v1/customers/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        code: string;
        display_name: string;
        mobile?: string;
        email?: string;
        status?: LifecycleStatus;
      }
    ) =>
      request<CustomerProfile>("/api/v1/customers", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  packageDefinitions: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<PackageDefinition[]>(listPath("/api/v1/package-definitions", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<PackageDefinition>(`/api/v1/package-definitions/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        code: string;
        name: string;
        description?: string;
        total_sessions?: number;
        price?: number;
        valid_days?: number;
        status?: LifecycleStatus;
      }
    ) =>
      request<PackageDefinition>("/api/v1/package-definitions", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  membershipPlans: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<MembershipPlan[]>(listPath("/api/v1/membership-plans", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<MembershipPlan>(`/api/v1/membership-plans/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        code: string;
        name: string;
        description?: string;
        billing_interval_days?: number;
        price?: number;
        status?: LifecycleStatus;
      }
    ) =>
      request<MembershipPlan>("/api/v1/membership-plans", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  staff: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<StaffProfile[]>(listPath("/api/v1/staff", { page, pageSize }), { tenantId }),
    get: (tenantId: string, id: string) =>
      request<StaffProfile>(`/api/v1/staff/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        branch_id?: string;
        code: string;
        display_name: string;
        kind?: StaffKind;
        mobile?: string;
        email?: string;
        status?: LifecycleStatus;
      }
    ) =>
      request<StaffProfile>("/api/v1/staff", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  commissionRules: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<CommissionRule[]>(listPath("/api/v1/commission-rules", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<CommissionRule>(`/api/v1/commission-rules/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id: string;
        code: string;
        name: string;
        rule_type: string;
        rate_percent?: number;
        flat_amount?: number;
        applies_to_service_id?: string;
        status?: LifecycleStatus;
      }
    ) =>
      request<CommissionRule>("/api/v1/commission-rules", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  marketingCampaigns: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<MarketingCampaign[]>(listPath("/api/v1/marketing-campaigns", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<MarketingCampaign>(`/api/v1/marketing-campaigns/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id?: string;
        branch_id?: string;
        code: string;
        name: string;
        external_campaign_ref?: string;
        channel?: string;
        status?: LifecycleStatus;
      }
    ) =>
      request<MarketingCampaign>("/api/v1/marketing-campaigns", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  loyaltyIntegrations: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<LoyaltyIntegration[]>(listPath("/api/v1/loyalty-integrations", { page, pageSize }), {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<LoyaltyIntegration>(`/api/v1/loyalty-integrations/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id?: string;
        code: string;
        name: string;
        external_program_ref?: string;
        status?: LifecycleStatus;
      }
    ) =>
      request<LoyaltyIntegration>("/api/v1/loyalty-integrations", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  communicationIntegrations: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<CommunicationIntegration[]>(
        listPath("/api/v1/communication-integrations", { page, pageSize }),
        { tenantId }
      ),
    get: (tenantId: string, id: string) =>
      request<CommunicationIntegration>(`/api/v1/communication-integrations/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id?: string;
        code: string;
        name: string;
        status?: LifecycleStatus;
      }
    ) =>
      request<CommunicationIntegration>("/api/v1/communication-integrations", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  integrationDispatches: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<IntegrationDispatch[]>(
        listPath("/api/v1/integration-dispatches", { page, pageSize }),
        { tenantId }
      ),
    get: (tenantId: string, id: string) =>
      request<IntegrationDispatch>(`/api/v1/integration-dispatches/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        organization_id?: string;
        integration_kind: string;
        config_id?: string;
        event_type: string;
        payload_ref?: string;
      }
    ) =>
      request<IntegrationDispatch>("/api/v1/integration-dispatches", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },
};
