/**
 * `GET /groups` / `GET /customers` で使うクエリ処理（分類マスタ。指示書AK 段階1）。
 * 仕様の正は `d-watch-api.yaml` の /groups と /customers。
 *
 * `db.groups()` / `db.customers()` は全件を返すだけなので、絞り込みと並べ替えはここで組み立てる
 * （`lib/schedules/query.ts` と同じ分担。`lib/db/` はデータ取得だけを担う）。
 *
 * ★★ページングしない★★（指示書AK §4-1 #1）—
 *   セレクトリストの選択肢を返すエンドポイントなので、`page` / `per_page` を受け取らない。
 *   既定の `per_page=50` で切ると ★51件目以降の屋号がセレクトから黙って消える★。
 *   `meta` は返す（`CLAUDE.md` §9.3「一覧APIは必ず meta を返す」）。意味は
 *   `/reports/facility-performance` と同じ「page を持たない一覧」の書き方に合わせてある:
 *     `meta.total` = 絞り込み後の全件数 / `meta.page` = 常に 1 /
 *     `meta.per_page` = そのページに入っている件数（= `total`。1ページに全件返すため）
 *
 * ★純粋関数にすること★（`CLAUDE.md` §9.4）— DBアクセスやログ出力を混ぜない。
 */
import { parseMasterIdParam } from "@/lib/api/master-id";
import type { QueryParseResult } from "@/lib/api/query-result";
import type { Customer, Group, ListResponse } from "@/lib/types";

export interface CustomerQuery {
  /** ホールディングスで絞り込み。★`null` = 絞らない★ */
  groupId: number | null;
}

/**
 * `/customers` のクエリパラメータをパースする。
 *
 * ★検証は `parseMasterIdParam()` の1本に任せる★（`lib/api/master-id.ts`）—
 *   ★`Number.parseInt()` で書き直さないこと★（`1abc` が `1` として通る。D-123）。
 */
export function parseCustomerQuery(
  searchParams: URLSearchParams
): QueryParseResult<CustomerQuery> {
  const groupId = parseMasterIdParam(searchParams.get("group_id"), "group_id");
  if (!groupId.ok) return groupId;
  return { ok: true, query: { groupId: groupId.query } };
}

/**
 * ホールディングスで絞り込む。
 *
 * ★★`null`（未指定）と「該当0件」を取り違えないこと★★ —
 *   未指定のときだけ全件を返す。実在しない `group_id` を指定されたら ★空配列★ を返す
 *   （404 にしない。「該当なし」は正常な結果。指示書AK §9-3 の 6-9 と同じ考え方）。
 *
 * ★`group_id: null`（ホールディングスなし）の屋号だけを引く手段は用意しない★
 *   （指示書AK §4-1 #3）。0 を API に漏らさないため、
 *   「未設定を明示する値」をクエリパラメータに作らない。
 */
export function filterCustomersByGroup(
  items: Customer[],
  groupId: number | null
): Customer[] {
  if (groupId === null) return items;
  return items.filter((c) => c.group_id === groupId);
}

/**
 * id の昇順（`d-watch-api.yaml` に明記。D-052 / D-055 と同じく契約に書く）。
 *
 * ★名前順にしないこと★ — 日本語の並び順はDBの照合順序とJSの `localeCompare` で
 *   一致しないため、`USE_FIXTURES` の true/false で順序が変わりうる。
 *   セレクトリストの並びが環境で変わると「どちらが正しいか」を誰も決められない。
 */
export function sortGroups(items: Group[]): Group[] {
  return [...items].sort((a, b) => a.id - b.id);
}

/** `sortGroups()` と同じ規則（id 昇順） */
export function sortCustomers(items: Customer[]): Customer[] {
  return [...items].sort((a, b) => a.id - b.id);
}

/**
 * ページングしない一覧のレスポンスを組み立てる。
 *
 * ★`items` を切らない★ — セレクトリストは全件が要る（このファイル冒頭）。
 * ★`meta` は返す★ — `CLAUDE.md` §9.3。
 */
export function masterListResponse<T>(items: T[]): ListResponse<T> {
  return {
    items,
    meta: { total: items.length, page: 1, per_page: items.length },
  };
}
