/**
 * Service-role fetch wrapper. Server-side only (uses `server-only`).
 *
 * Provides a single entry point for server actions that need full PostgREST
 * access (bypassing the anon key's RLS). Centralizes the URL + header pattern
 * so the 67 files that previously used `svcHeaders(POSTGREST_SERVICE_KEY)`
 * have one source of truth.
 *
 * `apikey` header alone is sufficient for PostgREST — it accepts it for both
 * anon and service-role access (no `Authorization: Bearer` needed). Safe for
 * Vercel Edge Runtime.
 *
 * Usage:
 *   import { svcFetch, svcHeaders } from "@/lib/svc-fetch";
 *   const res = await svcFetch("/rest/v1/brands?select=*");
 *   const data = await res.json();
 *
 * For RPC calls that need to bypass RLS, use `api.rpc` with the service key
 * passed via headers — see `svcRpc<T>(fn, args)` below.
 */

import "server-only";
import { PostgrestBuilder } from "@/lib/api";
import type { RowOf } from "@/lib/db-types";

const API_URL = (() => {
  const url = process.env.NEXT_PUBLIC_API_URL;
  if (!url) {
    throw new Error("Missing NEXT_PUBLIC_API_URL (server-side). Set it in .env.local.");
  }
  return url.replace(/\/$/, "");
})();

const SERVICE_KEY = (() => {
  const k = process.env.POSTGREST_SERVICE_KEY;
  if (!k) {
    throw new Error(
      "Missing POSTGREST_SERVICE_KEY. Set it in .env.local — it's the service-role key for the local PostgREST proxy.",
    );
  }
  return k;
})();

export function svcHeaders(): Record<string, string> {
  return { apikey: SERVICE_KEY, "Content-Type": "application/json" };
}

export async function svcFetch(path: string, init: RequestInit = {}): Promise<Response> {
  const url = path.startsWith("http") ? path : `${API_URL}${path.startsWith("/") ? "" : "/"}${path}`;
  const headers = { ...svcHeaders(), ...(init.headers as Record<string, string> | undefined) };
  return fetch(url, { ...init, headers });
}

export type SvcResult<T> = { data: T; error: null } | { data: null; error: { message: string } };

/** Service-role RPC call. Bypasses RLS, useful for admin server actions. */
export async function svcRpc<TReturns = unknown>(
  fn: string,
  args: Record<string, unknown> = {},
): Promise<SvcResult<TReturns>> {
  let res: Response;
  try {
    res = await svcFetch(`/rest/v1/rpc/${fn}`, {
      method: "POST",
      body: JSON.stringify(args),
    });
  } catch (e) {
    return { data: null, error: { message: (e as Error).message } };
  }
  if (!res.ok) {
    const text = await res.text().catch(() => "");
    return { data: null, error: { message: text || res.statusText } };
  }
  const data = (await res.json()) as TReturns;
  return { data, error: null };
}

/** Re-export the API URL for any code that still needs to build URLs by hand. */
export const SVC_API_URL = API_URL;

// ── Service-role PostgREST client ────────────────────────────────────────────
//
// Same builder shape as `api` (the anon-key client in `@/lib/api`) but uses
// the service-role key. Use this for server actions that need to bypass RLS
// (admin user management, writing to `admin_users`, etc.).
//
// Usage:
//   import { svcApi } from "@/lib/svc-fetch";
//   const { data, error } = await svcApi.from("admin_users").select("*");
//   const { data, error } = await svcApi.from("admin_users").insert({...}).select().single();

class SvcPostgrestBuilder<TRow, TResult = TRow[]> extends PostgrestBuilder<TRow, TResult> {
  constructor(table: string) {
    super(table);
    this.getHeaders = () => svcHeaders();
  }
}

export const svcApi = {
  from<TTable extends string>(table: TTable): SvcPostgrestBuilder<RowOf<TTable>> {
    return new SvcPostgrestBuilder<RowOf<TTable>>(table);
  },
  rpc: svcRpc,
};
