import { useEffect } from 'react';

import { useClient } from 'hooks/useClient';
import { useDashboardState } from 'state/useDashboardState';

import { usePanelClose } from '../../components/Workspace';
import { randomId } from 'helpers/random-id';

const EMPTY_TERMINALS: Record<string, string> = {};

const newSessionId = (): string =>
  randomId() ?? Math.random().toString(36).slice(2) + Date.now().toString(36);

/**
 * The shell a terminal panel is attached to: minted on first mount, remembered until the panel is closed.
 *
 * The `panelId → sessionId` map deliberately outlives the component. It used to be dropped on unmount, so
 * any layout or route change minted a fresh uuid and abandoned the previous shell — alive, unreachable,
 * and never killed. Keeping it is what makes reopening a terminal re-attach to what you left running, and
 * what makes the sidecar's replay buffer worth having. It is persisted dashboard state, so it survives a
 * reload too.
 *
 * What was missing was the other end: a panel closed for good left its shell running with nothing pointing
 * at it, and the only way to find one was the running-shells list. `usePanelClose` fires on a real close
 * and on nothing else — not a drag, not a swap, not a mobile panel switch — so the shell can finally be
 * killed with it. If that request fails the shell is still in the running-shells list, which is where it
 * was before this hook existed; a lost shell is worse than a stale row, so the map entry goes either way.
 */
export function useTerminalSession(panelId: string, stateKey: string): string | undefined {
  const client = useClient();
  const { value: terminals, setValue: setTerminals } = useDashboardState<Record<string, string>>(
    stateKey,
    EMPTY_TERMINALS,
  );
  const sessionId = terminals[panelId];

  useEffect(() => {
    if (!sessionId) setTerminals((prev) => (prev[panelId] ? prev : { ...prev, [panelId]: newSessionId() }));
  }, [panelId, sessionId, setTerminals]);

  usePanelClose(panelId, () => {
    if (!sessionId) return;
    setTerminals((prev) => {
      const { [panelId]: _drop, ...rest } = prev;
      return rest;
    });
    client.delete(`/terminal/_officer/sessions/${sessionId}`).catch((err: unknown) => {
      console.error(`[terminal] could not kill ${sessionId} after its panel closed`, err);
    });
  });

  return sessionId;
}
