/** Shared pending-resolve queue: Home banner / Log after-save / Entry detail. */

import { createContext } from "preact";
import { useCallback, useContext, useMemo, useState } from "preact/hooks";
import type { ComponentChildren } from "preact";
import { listPending, type Entry } from "../api";
import { ResolvePendingSheet } from "./ResolvePendingSheet";

type PendingApi = {
  openResolve: (entries?: Entry[]) => void;
  openResolveId: (id: string, fallback?: Entry) => void;
  refreshPendingSignal: number;
  bumpRefresh: () => void;
};

const PendingContext = createContext<PendingApi | null>(null);

export function usePendingResolve(): PendingApi {
  const ctx = useContext(PendingContext);
  if (!ctx) throw new Error("usePendingResolve requires PendingResolveProvider");
  return ctx;
}

export function PendingResolveProvider({ children }: { children: ComponentChildren }) {
  const [queue, setQueue] = useState<Entry[]>([]);
  const [open, setOpen] = useState(false);
  const [refreshPendingSignal, setRefresh] = useState(0);

  const bumpRefresh = useCallback(() => {
    setRefresh((n) => n + 1);
  }, []);

  const openResolve = useCallback(async (entries?: Entry[]) => {
    if (entries && entries.length) {
      setQueue(entries);
      setOpen(true);
      return;
    }
    try {
      const data = await listPending(50);
      if (!data.items.length) return;
      setQueue(data.items);
      setOpen(true);
    } catch {
      // leave closed
    }
  }, []);

  const openResolveId = useCallback(async (id: string, fallback?: Entry) => {
    if (fallback && fallback.id === id) {
      setQueue([fallback]);
      setOpen(true);
      return;
    }
    try {
      const data = await listPending(50);
      const hit = data.items.find((item) => item.id === id);
      const rest = data.items.filter((item) => item.id !== id);
      setQueue(hit ? [hit, ...rest] : fallback ? [fallback, ...rest] : rest);
      setOpen(true);
    } catch {
      if (fallback) {
        setQueue([fallback]);
        setOpen(true);
      }
    }
  }, []);

  const api = useMemo(
    () => ({ openResolve, openResolveId, refreshPendingSignal, bumpRefresh }),
    [openResolve, openResolveId, refreshPendingSignal, bumpRefresh],
  );

  return (
    <PendingContext.Provider value={api}>
      {children}
      <ResolvePendingSheet
        open={open}
        queue={queue}
        onClose={() => {
          setOpen(false);
          setQueue([]);
        }}
        onQueueChange={setQueue}
        onResolved={bumpRefresh}
      />
    </PendingContext.Provider>
  );
}
