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

/**
 * Customer addresses domain — a customer's saved, geocoded delivery addresses, customer-scoped
 * and tenancy-enforced server-side. Shapes mirror the b4 contract
 * (`dev/contracts/domains/geography-addresses.md` → `CustomerAddressDto`); the wire is camelCase.
 *
 * PII (`addressLine`/`postalCode`/`recipientName`/`recipientPhone`) is encrypted at rest and
 * **decrypted for the owner** on their own `list` — this screen only ever shows the owner their
 * own book, so the full `addressLine` is rendered (no masking is needed here).
 *
 * `provinceId` is **client-augmented**: the wire `CustomerAddressDto` carries `cityId` but not
 * its province (filed as REQ-009). We need the province to prefill the cascading dropdowns when
 * editing, so the mock persists it and the real client echoes the form's choice onto the
 * returned row (a genuinely refetched list from the server carries `null` until REQ-009 lands).
 */

/** Coordinates from the map-pin picker (also what the server's geocoder resolves to). */
export interface LatLng {
  latitude: number;
  longitude: number;
}

/** The b4 wire shape returned by every `customer_addresses/*` endpoint. */
export interface CustomerAddressDto {
  id: number;
  title: string;
  cityId: number;
  cityNameFa: string;
  cityNameEn: string;
  districtId: number | null;
  districtNameFa: string | null;
  districtNameEn: string | null;
  /** Decrypted for the owner; `null` only if never set. */
  addressLine: string | null;
  postalCode: string | null;
  /** `null` when the geocoder couldn't resolve the address ("no map pin"). */
  latitude: number | null;
  longitude: number | null;
  isPrimary: boolean;
  recipientName: string | null;
  recipientPhone: string | null;
}

/** App-level address = wire shape + the client-augmented `provinceId` (REQ-009). */
export interface CustomerAddress extends CustomerAddressDto {
  provinceId: number | null;
}

/**
 * Create/update input. `cityId` is required; `districtId` omitted/`null` = the whole city.
 * `latitude`/`longitude` are the picked pin (REQ-008 — the contract create body geocodes
 * server-side today; we send the pin so the coordinate is the user's, and echo it locally).
 * `provinceId` is client-augmented (REQ-009) — used to prefill the cascade on edit.
 */
export interface CreateAddressInput {
  title: string;
  provinceId: number;
  cityId: number;
  districtId?: number | null;
  addressLine: string;
  postalCode?: string | null;
  recipientName?: string | null;
  recipientPhone?: string | null;
  latitude?: number | null;
  longitude?: number | null;
  isPrimary?: boolean;
}

export type UpdateAddressInput = CreateAddressInput;

/** The domain's API seam — a mock and the real client both implement this interface. */
export interface AddressesApi {
  list(params?: PageParams): Promise<Paginated<CustomerAddress>>;
  create(input: CreateAddressInput): Promise<CustomerAddress>;
  update(id: number, input: UpdateAddressInput): Promise<CustomerAddress>;
  setPrimary(id: number): Promise<void>;
  remove(id: number): Promise<void>;
}
