import { useEffect, useRef } from 'react';
import { useGlobal } from 'hooks/useGlobal';

// ── "This screen has a better name for itself than its route does" ──
//
// A panel knows things the shell does not — which conversation is open, what it is called. The nav
// header is an ancestor of every screen, so nothing flows upward, and the title is wanted in two places
// at once (the header's centre, and the browser tab through `usePageTitleSync`). Hence a global, the
// same shape as `panel-fullscreen.ts`.
//
// It sits BELOW a typed tab name in `usePageTitle`'s precedence and above the route default:
// `label ?? override ?? titleForPath(pathname)`. Naming a window is a deliberate act meant to survive
// navigation — a chat title must not quietly take it back.
//
// In memory only. It is derived from data the panel already holds, so a remount republishes it, and a
// stale copy would be a header naming a conversation that is no longer open.
const PAGE_TITLE_OVERRIDE = 'PAGE_TITLE_OVERRIDE';

/**
 * What the screen wants the page called, and which thing it is naming.
 *
 * The `id` is not decoration. The shell has to tell two changes apart that look identical from the
 * outside — you opened a DIFFERENT conversation (new id, new title) versus you RENAMED the one you are
 * in (same id, new title) — because only the second should override a tab name you typed earlier. With
 * the title alone the shell would have to treat navigation as a rename and drop the tab name every time
 * you clicked a chat.
 */
export type PageTitleOverride = { id: string; title: string };

/** The override, or null. For the shell. */
export const usePageTitleOverride = () => useGlobal<PageTitleOverride | null>(PAGE_TITLE_OVERRIDE, null)[0];

/**
 * Name the page from inside a screen. Pass `null` when there is nothing to say.
 *
 * The cleanup is the load-bearing half: navigating away unmounts the publisher without anything setting
 * the title back, and a leftover value is a header still showing the last chat you had open.
 */
export function usePublishPageTitle(override: PageTitleOverride | null) {
  const [, setOverride] = useGlobal<PageTitleOverride | null>(PAGE_TITLE_OVERRIDE, null);

  // Through a ref: `useGlobal` rebuilds its setter every render, so as a dependency it would re-run the
  // effect — and therefore the cleanup's `null` — on every render of the publisher.
  const setOverrideRef = useRef(setOverride);
  setOverrideRef.current = setOverride;

  // Depend on the fields, not the object: callers build a fresh literal every render, so an object
  // dependency would re-run this — and its cleanup null — on every render of the publisher.
  const id = override?.id ?? null;
  const title = override?.title ?? null;
  useEffect(() => {
    setOverrideRef.current(id && title ? { id, title } : null);
    return () => setOverrideRef.current(null);
  }, [id, title]);
}
