/**
 * GET /facilities — 施設ロボットマスタ（F-08。読み取り専用）
 *
 * 形は `app/api/ds-devices/route.ts` と同じ。
 * 仕様の正は `d-watch-api.yaml` の /facilities。
 *
 * ★登録・更新は D-Security 側の画面で行うため、D-Watch は GET のみ★（YAMLの description）。
 * ★summary は無い（items と meta だけ）★ — この画面は台帳の閲覧で、
 *   /ds-devices のような「異常◯件」のサマリーカードを持たない。
 */
import { NextResponse } from "next/server";
import { db } from "@/lib/db";
import { filterFacilitiesByIds } from "@/lib/facilities/filter-by-ids";
import { resolveFacilityIdsByMasters } from "@/lib/facilities/resolve-by-master";
import {
  filterFacilitiesByFields,
  filterFacilitiesByQ,
  paginateFacilities,
  parseFacilityQuery,
  sortFacilities,
} from "@/lib/facilities/query";
import { withRequestId } from "@/lib/logger";
import { logApiError } from "@/lib/logger/api";
import type { ApiError, Facility, ListResponse } from "@/lib/types";

const ROUTE = "/api/facilities";

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);
    // ★422 分岐が付いた（指示書AK 段階2）★ — `group_id` / `customer_id` が
    //   このエンドポイント初の「不正値がありうるパラメータ」になった
    //   （理由は `parseFacilityQuery` の JSDoc。YAML の /facilities にも 422 を追記済み）。
    const parsed = parseFacilityQuery(searchParams);
    if (!parsed.ok) return errorResponse(parsed.error, parsed.status);
    const query = parsed.query;

    let rows: Facility[];
    // ★分類（`group_id` / `customer_id`）→ 施設IDの配列★（指示書AK 段階4）。
    //   ★`null` = 絞らない / `[]` = 0件★（★罠1★。`?.length` で分岐しないこと）。
    let facilityIds: number[] | null;
    try {
      // ★解決（施設マスタの読み取り）も同じ try に入れる★ — 失敗したら 500。
      //   ★黙って絞らずに返さないこと★（他社の施設が混ざったまま台帳に出る）。
      facilityIds = await resolveFacilityIdsByMasters(parsed.query);
      rows = await db.facilities();
    } 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/ds-devices/route.ts` と同じ方針）。
    // q と個別パラメータは AND なので、順に通すだけでよい（OR は q の内部だけ）。
    // ★★分類は `Facility.id` で突き合わせる★★（指示書AK 段階4）—
    //   ★このAPIが返すのは「施設の行そのもの」★なので、
    //   `DsDevice` / `Schedule` のような `facility_id` 列を持たない。
    //   ★`Facility` は段階5 で `customer_id` / `group_id` を持ったが、
    //   解決の入口は `resolveFacilityIdsByMasters()` のままにしてある★ —
    //   施設名の解決と同じ「施設IDの配列」で積集合を取れる形を崩さないため（§2-2）。
    const filtered = filterFacilitiesByFields(
      filterFacilitiesByQ(filterFacilitiesByIds(rows, facilityIds), query.q),
      query
    );
    const sorted = sortFacilities(filtered);

    const body: ListResponse<Facility> = paginateFacilities(
      sorted,
      query.page,
      query.perPage
    );
    return NextResponse.json(body);
  });
}
