/**
 * GET /customers — 屋号一覧（分類マスタ。指示書AK 段階1。読み取り専用）
 *
 * 形は `app/api/schedules/route.ts` と同じ。
 * 仕様の正は `d-watch-api.yaml` の /customers。
 *
 * ★GET だけ★（理由は `app/api/groups/route.ts` の冒頭）。
 * ★認証はここに書かない★ — `proxy.ts` が横断して判定する。
 *
 * ★`group_id` で絞れる★ — 画面（段階7）はホールディングスを選んだときに
 *   `GET /customers?group_id=X` を投げ、屋号の選択肢をその傘下だけに絞る。
 *   ★実在しない `group_id` でも 404 にしない★（空配列 + `meta.total = 0`）。
 *   「該当なし」は正常な結果で、404 は「エンドポイントが無い」と区別できなくなる。
 */
import { NextResponse } from "next/server";
import { db } from "@/lib/db";
import {
  filterCustomersByGroup,
  masterListResponse,
  parseCustomerQuery,
  sortCustomers,
} from "@/lib/masters/query";
import { withRequestId } from "@/lib/logger";
import { logApiError } from "@/lib/logger/api";
import type { ApiError, Customer, ListResponse } from "@/lib/types";

const ROUTE = "/api/customers";

function errorResponse(error: ApiError, status: number) {
  return NextResponse.json(error, { status });
}

export async function GET(request: Request) {
  return withRequestId(request, async () => {
    const { searchParams } = new URL(request.url);
    // ★`group_id=0` は 422★ — 0 は「ホールディングスなし」のセンチネルであって、
    //   有効なIDではない（D-011）。★`1abc` も 422★（D-123 で踏んだ罠）。
    const parsed = parseCustomerQuery(searchParams);
    if (!parsed.ok) {
      return errorResponse(parsed.error, parsed.status);
    }

    let rows: Customer[];
    try {
      rows = await db.customers();
    } catch (e) {
      const body: ApiError = {
        error: {
          code: "internal_error",
          message: "データの取得に失敗しました",
          details: null,
        },
      };
      logApiError({ route: ROUTE, method: "GET", body, status: 500, err: e });
      return errorResponse(body, 500);
    }

    // ここから下は純粋な絞り込み・並べ替え。すべて try の外
    // （`app/api/schedules/route.ts` と同じ方針）。
    const filtered = filterCustomersByGroup(rows, parsed.query.groupId);
    const body: ListResponse<Customer> = masterListResponse(
      sortCustomers(filtered)
    );
    return NextResponse.json(body);
  });
}
