import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { isAdminEmail } from "@/lib/admin";
import { refundRepo } from "@/server/repositories/refund.repo";
import { buildCsv, csvDateJakarta, csvResponse } from "@/lib/csv";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

const VALID_STATUS = new Set([
  "PENDING",
  "APPROVED",
  "REJECTED",
  "PROCESSING",
  "SUCCEEDED",
  "FAILED",
]);
const VALID_REASON = new Set([
  "USER_CANCELLATION",
  "ORGANIZER_CANCELLED",
  "TRIP_ISSUE",
  "ADMIN_ADJUSTMENT",
  "DISPUTE_RESOLVED",
]);

function parseDate(value: string | null): Date | undefined {
  if (!value) return undefined;
  const d = new Date(value);
  return Number.isNaN(d.getTime()) ? undefined : d;
}

export async function GET(req: NextRequest) {
  const session = await getServerSession(authOptions);
  if (!session?.user || !isAdminEmail(session.user.email)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const params = req.nextUrl.searchParams;
  const statusParam = params.get("status");
  const status =
    statusParam && VALID_STATUS.has(statusParam)
      ? (statusParam as
          | "PENDING"
          | "APPROVED"
          | "REJECTED"
          | "PROCESSING"
          | "SUCCEEDED"
          | "FAILED")
      : undefined;
  const reasonParam = params.get("reason");
  const reason =
    reasonParam && VALID_REASON.has(reasonParam)
      ? (reasonParam as
          | "USER_CANCELLATION"
          | "ORGANIZER_CANCELLED"
          | "TRIP_ISSUE"
          | "ADMIN_ADJUSTMENT"
          | "DISPUTE_RESOLVED")
      : undefined;

  const rows = await refundRepo.listByStatus(status, {
    dateFrom: parseDate(params.get("dateFrom")),
    dateTo: parseDate(params.get("dateTo")),
    reviewerEmail: params.get("reviewer") || undefined,
    reason,
  });

  const csv = buildCsv(
    [
      "Refund ID",
      "Status",
      "Reason",
      "Nominal (IDR)",
      "Dilaporkan oleh",
      "Catatan laporan",
      "Catatan admin",
      "Dibuat",
      "Reviewed at",
      "Succeeded at",
      "Failed at",
      "Reviewer email",
      "Booking ID",
      "Peserta nama",
      "Peserta email",
      "Trip ID",
      "Trip judul",
      "Trip tanggal",
    ],
    rows.map((r) => [
      r.id,
      r.status,
      r.reason,
      r.amount,
      r.reportedBy,
      r.reportNote,
      r.adminNote ?? "",
      csvDateJakarta(r.createdAt),
      csvDateJakarta(r.reviewedAt),
      csvDateJakarta(r.succeededAt),
      csvDateJakarta(r.failedAt),
      r.reviewedBy?.email ?? "",
      r.booking.id,
      r.booking.user.name,
      r.booking.user.email,
      r.booking.trip.id,
      r.booking.trip.title,
      csvDateJakarta(r.booking.trip.date),
    ])
  );

  const today = new Date().toISOString().slice(0, 10);
  return csvResponse(`refunds-${status ?? "all"}-${today}.csv`, csv);
}
