// Shared helpers for the v1 Finance API routes (server only).
import { NextResponse } from "next/server";
import { authenticateDeveloperRequest, type FinanceAccessRequirement } from "@/lib/developers/auth";
import { logApiError } from "@/lib/api/security";

export const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

export const TRANSACTION_COLUMNS =
  "id, type, title, description, category, amount_cents, currency, transaction_date, status, business, source, external_ref, created_at, updated_at";
export const RECURRING_COLUMNS =
  "id, type, title, category, amount_cents, currency, frequency, next_due_date, is_active, business, source, created_at, updated_at";

/** Finance routes: token needs the section right "finances" (read or write). Finance data always belongs
 *  to the token's creator (user_id) – also for team tokens. Returns the user id. */
export async function financeAuth(req: Request, need: FinanceAccessRequirement) {
  const auth = await authenticateDeveloperRequest(req, { write: need === "write", section: "finances" });
  return auth ? auth.workspaceUserId : null;
}

export function unauthorized() {
  return NextResponse.json(
    { error: "Unauthorized – token needs the 'Finances' right (Mindavio → Developers)" },
    { status: 401 }
  );
}

export function badRequest(error: string) {
  return NextResponse.json({ error }, { status: 400 });
}

export async function readJson(req: Request): Promise<unknown | undefined> {
  try {
    return await req.json();
  } catch {
    return undefined;
  }
}

export function serverError(context: string, error: unknown) {
  logApiError(context, error);
  return NextResponse.json({ error: "Finance request failed" }, { status: 500 });
}

/** Build "col = $n" list for a validated patch object (keys come from the validator, never from the client). */
export function setClause(patch: Record<string, unknown>, startIndex: number) {
  const keys = Object.keys(patch);
  return {
    text: keys.map((key, i) => `${key} = $${startIndex + i}`).join(", "),
    values: keys.map((key) => patch[key]),
  };
}
