/**
 * GET /reports/facility-performance/export — 施設別パフォーマンスの CSV エクスポート（D-163）
 *
 * /reports/facility-performance と同一のパラメータを受け付ける（★`limit` は無視して全件を出す★）。
 * UTF-8 BOM付き、ヘッダ行あり、★画面の言語によらず日本語★。
 * 仕様の正は `d-watch-api.yaml` の /reports/facility-performance/export。
 */
import { NextResponse } from "next/server";
import { MAX_CSV_ROWS } from "@/lib/config";
import { withRequestId } from "@/lib/logger";
import { logApiError } from "@/lib/logger/api";
// ★CSVの組み立ては lib/reports/facility-performance-csv.ts★ — App Router の route.ts は
//   HTTPメソッド以外の export を想定しておらず、ここに置くとテストから呼べない
//   （`app/api/clean-logs/export/route.ts` と同じ理由。D-125）
import {
  buildFacilityPerformanceCsv,
  facilityPerformanceCsvFilename,
} from "@/lib/reports/facility-performance-csv";
import { loadFacilityPerformance } from "@/lib/reports/facility-performance-load";
import { parseReportQuery } from "@/lib/reports/query";
import type { ApiError, FacilityPerformance } from "@/lib/types";

const ROUTE = "/api/reports/facility-performance/export";

export async function GET(request: Request) {
  return withRequestId(request, async () => {
    const { searchParams } = new URL(request.url);
    // ★検証は一覧と同じ★（period / year / month / week / group_id / customer_id が不正なら 422）。
    //   `limit` も読まれるが、不正値でも 422 にはならない（丸めるだけ）うえ、下で使わない。
    const parsed = parseReportQuery(searchParams);
    if (!parsed.ok) {
      return NextResponse.json(parsed.error, { status: parsed.status });
    }

    let items: FacilityPerformance[];
    try {
      // ★★一覧（`/reports/facility-performance`）と**同じ1本**を呼ぶ★★（D-163）—
      //   ★★片方だけ絞ると、画面の表と CSV の中身が食い違います★★。
      //   ★`limit` で切らない★ — 画面の「全施設表示」の200件上限に縛られず、絞り込み後の全施設を出す。
      items = await loadFacilityPerformance(parsed.query);
    } catch (e) {
      const body: ApiError = {
        error: { code: "internal_error", message: "データの取得に失敗しました", details: null },
      };
      logApiError({ route: ROUTE, method: "GET", body, status: 500, err: e });
      return NextResponse.json(body, { status: 500 });
    }

    // ★★行数の歯止め（清掃詳細ログの CSV と揃える。D-163）★★
    //
    // 施設数なので実際にはまず起きないが、★上限・形・境界は `/clean-logs/export` と同じ★にする
    // （`MAX_CSV_ROWS` を共有。★上限は「含む」＝ `>` であって `>=` ではない★）。
    // ★CSV を組み立てる**前**に数える★（組み立ててから長さで判断しない）。
    // ★500 ではなく 422★ — 利用者の指定が上限を超えているという話で、サーバの不具合ではない。
    if (items.length > MAX_CSV_ROWS) {
      const body: ApiError = {
        error: {
          code: "validation_failed",
          message:
            `CSVで出力できません。対象の施設が${items.length}件で、` +
            `上限の${MAX_CSV_ROWS}件を超えています。` +
            `分類・施設名・ステータスで絞り込んでください。`,
          // ★実数を入れる★ — 「あと何件減らせばよいか」が文言を読まずに分かる
          details: { total: items.length, max: MAX_CSV_ROWS },
        },
      };
      return NextResponse.json(body, { status: 422 });
    }

    const csv = buildFacilityPerformanceCsv(items, parsed.query.period);
    // ★ファイル名は parse 済みの数値から組み立てる★（生のクエリ文字列を入れない）ので、
    //   Content-Disposition に `"` や改行などの制御文字は入らない。
    const filename = facilityPerformanceCsvFilename(parsed.query);

    return new NextResponse(csv, {
      status: 200,
      headers: {
        "Content-Type": "text/csv; charset=utf-8",
        "Content-Disposition": `attachment; filename="${filename}"`,
      },
    });
  });
}
