// Fabriek voor REST-routes die een enkel jsonb-record per id synchroniseren
// met Supabase. Gebruikt door alles onder /api/sync/* om browserdata
// (dossiers, gebruikersmodellen, regelgeving-annotaties, ...) kantoorbreed
// beschikbaar te maken in plaats van vast te zitten in één browser.
//
// Vereiste tabel (SQL, eenmalig in de Supabase SQL Editor), per tabelnaam:
//
//   create table <tabel> (
//     id        text primary key,
//     data      jsonb not null,
//     aangepast timestamptz default now()
//   );

import { NextResponse } from "next/server";
import { maakServiceClient } from "@/lib/supabase/server";

interface MetId {
  id: string;
}

function heeftGeldigId(item: unknown): item is MetId {
  return (
    typeof item === "object" &&
    item !== null &&
    typeof (item as { id?: unknown }).id === "string" &&
    (item as { id: string }).id.length > 0
  );
}

export function maakJsonbSyncRoute<T extends MetId>(tabel: string) {
  async function GET() {
    const sb = maakServiceClient();
    if (!sb) return NextResponse.json({ items: [], persistent: false });

    const { data, error } = await sb.from(tabel).select("data").order("aangepast");
    if (error) return NextResponse.json({ fout: error.message }, { status: 500 });

    // Sla rijen over die niet langer een geldig {id} hebben (bv. door een
    // schemawijziging in het type T sinds de rij geschreven werd), in plaats
    // van de hele sync stil te laten breken op één corrupte rij.
    const items = (data ?? [])
      .map((r: { data: unknown }) => r.data as T)
      .filter(heeftGeldigId);
    return NextResponse.json({ items, persistent: true });
  }

  async function POST(request: Request) {
    const sb = maakServiceClient();
    if (!sb) return NextResponse.json({ genegeerd: true });

    let item: T;
    try {
      item = (await request.json()) as T;
    } catch {
      return NextResponse.json({ fout: "Ongeldige JSON." }, { status: 400 });
    }

    if (!heeftGeldigId(item)) {
      return NextResponse.json({ fout: "Item heeft geen geldig 'id'-veld." }, { status: 400 });
    }

    const { error } = await sb
      .from(tabel)
      .upsert({ id: item.id, data: item, aangepast: new Date().toISOString() });
    if (error) return NextResponse.json({ fout: error.message }, { status: 500 });

    return NextResponse.json({ opgeslagen: item.id });
  }

  async function DELETE(request: Request) {
    const sb = maakServiceClient();
    if (!sb) return NextResponse.json({ genegeerd: true });

    const id = new URL(request.url).searchParams.get("id");
    if (!id) return NextResponse.json({ fout: "'id' is verplicht." }, { status: 400 });

    const { error } = await sb.from(tabel).delete().eq("id", id);
    if (error) return NextResponse.json({ fout: error.message }, { status: 500 });

    return NextResponse.json({ verwijderd: id });
  }

  return { GET, POST, DELETE };
}
