import { jsx } from "react/jsx-runtime";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useInput } from "ink";
import { activityStore as defaultActivityStore } from "../state/activity-store-instance.js";
import { SettingsHome } from "../components/SettingsHome.js";
import { CategoryScreen } from "../components/CategoryScreen.js";
import { VerifyScreen } from "../components/VerifyScreen.js";
import { DoctorScreen } from "../components/DoctorScreen.js";
import { DashboardExport } from "../components/DashboardExport.js";
import { ImportScreen } from "../components/ImportScreen.js";
import { DashboardUninstall } from "../components/DashboardUninstall.js";
import { App, DEFAULT_ROUTES } from "../shell/App.js";
import { buildPaletteIndex } from "../shell/palette-index.js";
const ACTION_LABELS = ["Verify", "Doctor", "Export", "Import", "Uninstall"];
function computeSaveState(dirtyCount, isSaving, currentToast, hasUnresolvedError) {
  if (isSaving) return "saving";
  if (currentToast?.group === "save") return "saved-toast";
  if (hasUnresolvedError || currentToast?.severity === "err") return "error";
  if (dirtyCount > 0) return "dirty";
  return "idle-saved";
}
function saveStateToStatus(state) {
  if (state === "idle-saved" || state === "saved-toast") return "ok";
  if (state === "error") return "err";
  return "warn";
}
function saveStateLabel(state, dirtyCount, toastMessage, toastAction) {
  switch (state) {
    case "idle-saved":
      return "All changes saved \u2713";
    case "saving":
      return "Saving\u2026";
    case "saved-toast": {
      const base = toastMessage ?? "Saved";
      return toastAction ? `${base} \xB7 ${toastAction.label}` : base;
    }
    case "dirty":
      return `${dirtyCount} unsaved`;
    case "error":
      return "Save failed \u2014 check logs";
  }
}
function resolveInitialView(initialRoute) {
  if (!initialRoute || initialRoute === "home") return { kind: "home" };
  const r = DEFAULT_ROUTES.find((x) => x.id === initialRoute);
  if (!r) return { kind: "home" };
  return r.group === "settings" ? { kind: "category", id: r.id } : { kind: "action", id: r.id };
}
function computeActiveRoute(view) {
  if (view.kind === "home") return "browser";
  if (view.kind === "category") return view.id;
  return view.id;
}
function computeRouteId(view) {
  if (view.kind === "home") return "home";
  if (view.kind === "category") return `category:${view.id}`;
  return `action:${view.id}`;
}
function computePaneTitle(view, catalog) {
  if (view.kind === "home") return "Settings";
  if (view.kind === "category") {
    const cat = catalog.find((c) => c.id === view.id);
    return cat?.label ?? view.id;
  }
  const label = DEFAULT_ROUTES.find((r) => r.id === view.id)?.label;
  return label ?? view.id;
}
function computeDirtyByCategory(dirtyKeys) {
  const out = {};
  for (const key of dirtyKeys) {
    const seg = key.split(".")[0] ?? key;
    out[seg] = (out[seg] ?? 0) + 1;
  }
  return out;
}
function InkRoot(props) {
  const {
    store,
    catalog,
    onExit = () => {
    },
    version,
    productName,
    toastStore,
    activityStore: injectedActivityStore,
    initialRoute
  } = props;
  const liveActivityStore = injectedActivityStore ?? defaultActivityStore;
  const [view, setView] = useState(() => resolveInitialView(initialRoute));
  const [focusedPane, setFocusedPane] = useState("sidebar");
  const [inEditBuffer, setInEditBuffer] = useState(false);
  const [paletteOpen, setPaletteOpen] = useState(false);
  const [helpOpen, setHelpOpen] = useState(false);
  const [dirtyCount, setDirtyCount] = useState(() => store.dirtyKeys().length);
  useEffect(() => {
    const unsub = store.subscribe(() => setDirtyCount(store.dirtyKeys().length));
    return unsub;
  }, [store]);
  const [isSaving, setIsSaving] = useState(() => {
    const labels = liveActivityStore.labels();
    return labels.some((l) => l.startsWith("save:"));
  });
  useEffect(() => {
    const unsub = liveActivityStore.subscribe(() => {
      setIsSaving(liveActivityStore.labels().some((l) => l.startsWith("save:")));
    });
    return unsub;
  }, [liveActivityStore]);
  const [toast, setToast] = useState(
    () => toastStore?.current() ?? null
  );
  useEffect(() => {
    if (!toastStore) return;
    const unsub = toastStore.subscribe(() => setToast(toastStore.current()));
    return unsub;
  }, [toastStore]);
  const prevSaveToastRef = React.useRef(null);
  useEffect(() => {
    if (!toastStore) return;
    const unsub = toastStore.subscribe(() => {
      const t = toastStore.current();
      if (t?.group === "save" && !t.action) {
        const msg = t.message;
        if (msg !== prevSaveToastRef.current) {
          prevSaveToastRef.current = msg;
          toastStore.setCurrentAction({
            key: "\r",
            label: "\u23CE Apply & verify",
            handler: () => {
              setView({ kind: "action", id: "verify" });
              setFocusedPane("main");
            }
          });
        }
      }
      if (!t || t.group !== "save") {
        prevSaveToastRef.current = null;
      }
    });
    return unsub;
  }, [toastStore]);
  const [hasUnresolvedError, setHasUnresolvedError] = useState(false);
  useEffect(() => {
    if (!toastStore) return;
    const unsub = toastStore.subscribe(() => {
      const t = toastStore.current();
      if (t?.severity === "err" && t?.group === "save-error") {
        setHasUnresolvedError(true);
      } else if (t?.severity === "ok" && t?.group === "save") {
        setHasUnresolvedError(false);
      }
    });
    return unsub;
  }, [toastStore]);
  const saveState = computeSaveState(dirtyCount, isSaving, toast, hasUnresolvedError);
  const headerStatus = saveStateToStatus(saveState);
  const headerLabel = saveStateLabel(saveState, dirtyCount, toast?.message ?? null, toast?.action);
  const paletteEntries = useMemo(
    () => buildPaletteIndex({ catalog: [...catalog], actionLabels: ACTION_LABELS }),
    [catalog]
  );
  useInput((_input, key) => {
    if (paletteOpen || helpOpen) return;
    if (toast?.action && !inEditBuffer) {
      const action = toast.action;
      const matchesKey = action.key === "\r" ? key.return : _input === action.key;
      if (matchesKey) {
        action.handler();
        toastStore?.dismiss();
        return;
      }
    }
    if (key.ctrl && _input === "k") {
      setPaletteOpen(true);
      return;
    }
    if (_input === "?" && !inEditBuffer) {
      setHelpOpen(true);
      return;
    }
    if (key.tab) setFocusedPane((p) => p === "sidebar" ? "main" : "sidebar");
  });
  const handlePalettePick = useCallback((entry) => {
    setPaletteOpen(false);
    if (entry.kind === "category") {
      setView({ kind: "category", id: entry.id });
      setFocusedPane("main");
    } else if (entry.kind === "field" && entry.path) {
      setView({ kind: "category", id: entry.path, initialFocusKey: entry.id });
      setFocusedPane("main");
    } else if (entry.kind === "action") {
      setView({ kind: "action", id: entry.id });
      setFocusedPane("main");
    }
  }, []);
  const handlePaletteClose = useCallback(() => setPaletteOpen(false), []);
  const handleHelpClose = useCallback(() => setHelpOpen(false), []);
  const goHome = useCallback(() => {
    setView({ kind: "home" });
    setFocusedPane("sidebar");
  }, []);
  const onSelectCategory = useCallback((id) => {
    setView({ kind: "category", id });
    setFocusedPane("main");
  }, []);
  const onAction = useCallback((action) => {
    setView({ kind: "action", id: action });
    setFocusedPane("main");
  }, []);
  const handleSelectRoute = useCallback((id) => {
    const route = DEFAULT_ROUTES.find((r) => r.id === id);
    if (!route) return;
    if (route.group === "settings") {
      setView({ kind: "category", id });
    } else {
      setView({ kind: "action", id });
    }
    setFocusedPane("main");
  }, []);
  const activeRoute = computeActiveRoute(view);
  const routeId = computeRouteId(view);
  const paneTitle = computePaneTitle(view, catalog);
  const dirtyByCategory = computeDirtyByCategory(store.dirtyKeys());
  let currentScreen;
  if (view.kind === "category") {
    const category = catalog.find((c) => c.id === view.id);
    if (!category) {
      currentScreen = /* @__PURE__ */ jsx(
        SettingsHome,
        {
          store,
          catalog,
          onSelectCategory,
          onAction,
          onQuit: onExit,
          version,
          productName
        }
      );
    } else {
      currentScreen = /* @__PURE__ */ jsx(
        CategoryScreen,
        {
          category,
          store,
          onBack: goHome,
          onEditBufferChange: setInEditBuffer,
          initialFocusKey: view.initialFocusKey
        }
      );
    }
  } else if (view.kind === "action") {
    const actionId = view.id;
    switch (actionId) {
      case "verify":
        currentScreen = /* @__PURE__ */ jsx(VerifyScreen, { onBack: goHome });
        break;
      case "doctor":
        currentScreen = /* @__PURE__ */ jsx(DoctorScreen, { onBack: goHome });
        break;
      case "export":
        currentScreen = /* @__PURE__ */ jsx(DashboardExport, { onBack: goHome });
        break;
      case "import":
        currentScreen = /* @__PURE__ */ jsx(ImportScreen, { store, catalog, onBack: goHome });
        break;
      case "uninstall":
        currentScreen = /* @__PURE__ */ jsx(DashboardUninstall, { onBack: goHome });
        break;
      default: {
        const _exhaustive = actionId;
        throw new Error(`Unhandled action: ${String(_exhaustive)}`);
      }
    }
  } else {
    currentScreen = /* @__PURE__ */ jsx(
      SettingsHome,
      {
        store,
        catalog,
        onSelectCategory,
        onAction,
        onQuit: onExit,
        version,
        productName
      }
    );
  }
  return /* @__PURE__ */ jsx(
    App,
    {
      routes: DEFAULT_ROUTES,
      activeRoute,
      routeId,
      dirtyByCategory,
      status: headerStatus,
      pending: 0,
      toast,
      saveLabel: headerLabel,
      focusedPane,
      paneTitle,
      onSelectRoute: handleSelectRoute,
      paletteOpen,
      paletteEntries,
      onPalettePick: handlePalettePick,
      onPaletteClose: handlePaletteClose,
      helpOpen,
      onHelpClose: handleHelpClose,
      activityStore: liveActivityStore,
      children: currentScreen
    }
  );
}
export {
  InkRoot
};
//# sourceMappingURL=ink.js.map