import type { PageParams, Paginated } from '@/lib/api/types';

/**
 * Nurse service-areas domain — the cities/districts a nurse will travel to, nurse-scoped and
 * tenancy-enforced server-side. Shapes mirror the b4 contract
 * (`dev/contracts/domains/geography-addresses.md` → `NurseServiceAreaDto`); the wire is camelCase.
 *
 * **`districtId = null` = the whole city** — a real coverage choice ("I cover the entire city"),
 * never missing data. Search (f6) treats a whole-city row as matching every district in that
 * city. `UNIQUE(nurseId, cityId, districtId)` is enforced server-side (a duplicate returns 409),
 * treating `null` district as a real value.
 */

/** The b4 wire shape returned by every `nurse_service_areas/*` endpoint. */
export interface NurseServiceArea {
  id: number;
  cityId: number;
  cityNameFa: string;
  cityNameEn: string;
  districtId: number | null;
  districtNameFa: string | null;
  districtNameEn: string | null;
  isWholeCity: boolean;
  isActive: boolean;
}

/** Add input — omit/`null` `districtId` for a whole-city area. */
export interface AddServiceAreaInput {
  cityId: number;
  districtId?: number | null;
}

/** The domain's API seam — a mock and the real client both implement this interface. */
export interface ServiceAreasApi {
  list(params?: PageParams): Promise<Paginated<NurseServiceArea>>;
  add(input: AddServiceAreaInput): Promise<NurseServiceArea>;
  remove(id: number): Promise<void>;
}

/**
 * The client-side duplicate guard (the fast path before firing the add): a `(cityId, districtId)`
 * pair is a duplicate if it already exists in the nurse's areas, **treating a `null` district as a
 * real value** (whole-city vs a specific district are distinct, but two whole-city rows collide).
 * The server's `UNIQUE` index + 409 is the source of truth; this just avoids a doomed round-trip.
 */
export function areaExists(
  areas: NurseServiceArea[],
  cityId: number,
  districtId: number | null,
): boolean {
  return areas.some((area) => area.cityId === cityId && (area.districtId ?? null) === (districtId ?? null));
}
