"use client";
import { useCallback, useEffect, useState } from "react";

interface MetId {
  id: string;
}

/**
 * Generieke opslag-hook: toont IndexedDB-data onmiddellijk (snelle eerste
 * render), synchroniseert daarna met de /api/sync/*-route als die persistent
 * is (Supabase geconfigureerd), en pusht lokale items die nog niet op de
 * server staan (offline-sync). Zonder Supabase blijft alles gewoon lokaal.
 */
export function useGesynchroniseerdeOpslag<T extends MetId>(
  apiPad: string,
  lokaalLezen: () => Promise<T[]>,
  lokaalSchrijven: (item: T) => Promise<void>,
  lokaalVerwijderen: (id: string) => Promise<void>
) {
  const [items, setItems] = useState<T[]>([]);
  const [geladen, setGeladen] = useState(false);

  useEffect(() => {
    async function laad() {
      const lokaal = await lokaalLezen();
      if (lokaal.length > 0) setItems(lokaal);

      try {
        const res = await fetch(apiPad, { headers: { Accept: "application/json" }, cache: "no-store" });
        if (res.ok) {
          const json = (await res.json()) as { items?: T[]; persistent?: boolean };
          if (json.persistent && Array.isArray(json.items)) {
            for (const item of json.items) await lokaalSchrijven(item);

            const serverIds = new Set(json.items.map((i) => i.id));
            for (const item of lokaal) {
              if (!serverIds.has(item.id)) {
                fetch(apiPad, {
                  method: "POST",
                  headers: { "Content-Type": "application/json" },
                  body: JSON.stringify(item),
                }).catch(() => {});
              }
            }
            setItems(await lokaalLezen());
          }
        }
      } catch {
        // Geen netwerk of Supabase niet geconfigureerd: gebruik lokale data.
      }
      setGeladen(true);
    }
    laad();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const slaOp = useCallback(
    async (item: T) => {
      await lokaalSchrijven(item);
      setItems((prev) => {
        const bestaat = prev.some((i) => i.id === item.id);
        return bestaat ? prev.map((i) => (i.id === item.id ? item : i)) : [...prev, item];
      });
      fetch(apiPad, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(item),
      }).catch(() => {});
    },
    [apiPad, lokaalSchrijven]
  );

  const verwijder = useCallback(
    async (id: string) => {
      await lokaalVerwijderen(id);
      setItems((prev) => prev.filter((i) => i.id !== id));
      fetch(`${apiPad}?id=${encodeURIComponent(id)}`, { method: "DELETE" }).catch(() => {});
    },
    [apiPad, lokaalVerwijderen]
  );

  return { items, geladen, slaOp, verwijder, setItems };
}
