/* eslint-disable */
// ============================================================
// APP ROOT
//   - Action-based routing (currentActionId)
//   - Loads ActionPayload via mockApi, dispatches by PartialView
//   - Admin "Edit configuration" pill on grids
//   - Persona switcher + devtools panel
// ============================================================

const { useState: useApp_S, useEffect: useApp_E, useMemo: useApp_M, useCallback: useApp_CB, useRef: useApp_R } = React;

// --------------------------------------------------------------
// Hook: load an ActionPayload for the current actionId
// --------------------------------------------------------------
const useActionPayload = (actionId, role) => {
  const [payload, setPayload] = useApp_S(null);
  const [loading, setLoading] = useApp_S(true);
  const [error, setError] = useApp_S(null);
  useApp_E(() => {
    if (!actionId) { setPayload(null); setLoading(false); return; }
    let cancelled = false;
    setLoading(true); setError(null);
    mockApi.getActionPayload(actionId).then((p) => {
      if (cancelled) return;
      // Apply per-role title override if present
      const override = ACTION_TITLE_OVERRIDES[role]?.[actionId];
      if (override) {
        if (override.ActionTitle) p.ActionTitle = override.ActionTitle;
        if (override.Subtitle && p.MergedParams) p.MergedParams = { ...p.MergedParams, Subtitle: override.Subtitle };
      }
      setPayload(p);
      setLoading(false);
    }).catch((e) => {
      if (cancelled) return;
      setError(e.message); setLoading(false);
    });
    return () => { cancelled = true; };
  }, [actionId, role]);
  return { payload, loading, error };
};

// --------------------------------------------------------------
// Page dispatcher — routes a payload to the right PartialView
// --------------------------------------------------------------
const PageDispatcher = ({ actionId, role, onToast, onOpenDetail, isEditing, draftMergedParams, setDraftMergedParams, rbac, setRbac, menus, setMenus, theme, setTheme }) => {
  const { payload, loading, error } = useActionPayload(actionId, role);

  if (loading) {
    return (
      <div className="space-y-3">
        <Skeleton className="h-7 w-64 mb-3" />
        <Skeleton className="h-4 w-96 mb-5" />
        <Skeleton className="h-80 w-full" />
      </div>
    );
  }
  if (error || !payload) {
    return <Empty icon="alert" title="Couldn't load action" subtitle={error || "Unknown error"} />;
  }

  const sub = payload.MergedParams?.Subtitle;
  const eyebrow = `actionId · ${payload.ActionId} · ${payload.PartialView}`;

  switch (payload.PartialView) {
    case "Dashboard":
      return (
        <div className="space-y-5">
          <PageHeader eyebrow={eyebrow} title={payload.ActionTitle || payload.ActionName} subtitle={sub} />
          <Dashboard actionPayload={payload} role={role} onToast={onToast} />
        </div>
      );

    case "Grid": {
      const mp = isEditing ? (draftMergedParams || payload.MergedParams) : payload.MergedParams;
      return (
        <div className="space-y-5">
          <PageHeader eyebrow={eyebrow} title={payload.ActionTitle || payload.ActionName} subtitle={sub} />
          {isEditing && (
            <div className="grid gap-4 xl:grid-cols-[460px_minmax(0,1fr)]">
              <div className="min-w-0">
                <div className="text-[10.5px] uppercase tracking-wider font-semibold mb-2 inline-flex items-center gap-1.5" style={{ color: "var(--primary)" }}>
                  <Icon name="sliders" size={11} /> Configuration · actionId {payload.ActionId}
                </div>
                <AdminEditor
                  action={{ ...payload, MergedParams: mp }}
                  onChange={(nextAction) => setDraftMergedParams(nextAction.MergedParams)}
                  onToast={onToast}
                  rbac={rbac} setRbac={setRbac}
                />
              </div>
              <div className="min-w-0">
                <div className="text-[10.5px] uppercase tracking-wider font-semibold mb-2 inline-flex items-center gap-1.5" style={{ color: "var(--primary)" }}>
                  <span className="bullet"></span> Live preview · what users will see
                </div>
                <Grid
                  actionPayload={payload}
                  mergedParamsOverride={mp}
                  role={role}
                  onToast={onToast}
                  onOpenDetail={onOpenDetail}
                />
              </div>
            </div>
          )}
          {!isEditing && (
            <Grid
              actionPayload={payload}
              role={role}
              onToast={onToast}
              onOpenDetail={onOpenDetail}
            />
          )}
        </div>
      );
    }

    case "RBACManager":
      return (
        <div className="space-y-5">
          <PageHeader eyebrow={eyebrow} title={payload.ActionTitle || "Settings"} subtitle="Configure who sees what — actions are the unit of RBAC; menus are role-shaped surfaces over them." />
          <RBACManagerPage onToast={onToast} rbac={rbac} setRbac={setRbac} menus={menus} setMenus={setMenus} theme={theme} setTheme={setTheme} />
        </div>
      );

    case "ActionLibrary":
      return (
        <div className="space-y-5">
          <PageHeader eyebrow={eyebrow} title="Action library" subtitle="Every clickable thing in this UI is an action. This is the source-of-truth for what exists, what each one does, and who can see it." />
          <ActionLibraryPage onToast={onToast} rbac={rbac} setRbac={setRbac} />
        </div>
      );

    default:
      return <Empty icon="alert" title={`Unknown PartialView "${payload.PartialView}"`} subtitle="No renderer registered for this action kind." />;
  }
};

// --------------------------------------------------------------
// Root App
// --------------------------------------------------------------
const App = () => {
  // ---- Role + persona ----
  const [role, setRole] = useApp_S("Admin");
  const persona = PERSONAS[role];

  // ---- Global state (mirrors mockApi.state but reactive) ----
  const [rbac, setRbac] = useApp_S(() => mockApi.state.getAllRbac());
  const [menus, setMenus] = useApp_S(() => structuredClone(DEFAULT_MENU));

  // ---- Theme ----
  const [theme, setTheme] = useApp_S(() => mockApi.state.getTheme());
  useApp_E(() => { applyTheme(theme); mockApi.state.setTheme(theme); }, [theme]);

  // ---- Current actionId ----
  const myMenu = menus[role] || [];
  const firstActionId = myMenu.find((it) => it.visible)?.actionId;
  const [currentActionId, setCurrentActionId] = useApp_S(firstActionId || null);

  // When role changes, if current action is not visible to new role, fall back to first visible
  useApp_E(() => {
    const visible = (menus[role] || []).filter((it) => it.visible);
    const has = visible.find((it) => it.actionId === currentActionId);
    if (!has) setCurrentActionId(visible[0]?.actionId || null);
  }, [role, menus]);

  // ---- Toast ----
  const [toasts, setToasts] = useApp_S([]);
  const toastId = useApp_R(0);
  const onToast = useApp_CB((t) => {
    const id = ++toastId.current;
    setToasts((arr) => [...arr, { id, ...t }]);
  }, []);
  const removeToast = (id) => setToasts((arr) => arr.filter((t) => t.id !== id));

  // ---- Detail drawer ----
  const [detail, setDetail] = useApp_S(null); // { detailActionId, row }
  const openDetail = (payload) => setDetail(payload);
  const closeDetail = () => setDetail(null);

  // ---- Admin edit mode ----
  const isAdmin = role === "Admin";
  const [isEditing, setIsEditing] = useApp_S(false);
  const [draft, setDraft] = useApp_S(null); // MergedParams draft
  // Reset edit mode when switching actions or roles
  useApp_E(() => { setIsEditing(false); setDraft(null); }, [currentActionId, role]);

  // Hint: is the current action editable inline (Grid only for now)?
  const [currentPayloadKind, setCurrentPayloadKind] = useApp_S(null);
  useApp_E(() => {
    if (!currentActionId) { setCurrentPayloadKind(null); return; }
    mockApi.getActionPayload(currentActionId).then((p) => setCurrentPayloadKind(p?.PartialView)).catch(() => {});
  }, [currentActionId]);
  const canEdit = isAdmin && currentPayloadKind === "Grid";

  const saveEdit = async () => {
    if (!draft || !currentActionId) return;
    await mockApi.putActionConfig(currentActionId, draft);
    setDraft(null);
    setIsEditing(false);
    onToast({ kind: "ok", text: `Saved config for action ${currentActionId}` });
  };

  // ---- UI chrome ----
  const [sidebarCollapsed, setSidebarCollapsed] = useApp_S(false);
  const [accountOpen, setAccountOpen] = useApp_S(false);
  const [devOpen, setDevOpen] = useApp_S(false);

  // ---- Active menu item (for topbar title) ----
  const activeMenuItem = (menus[role] || []).find((it) => it.actionId === currentActionId);

  // ---- Detail action payload (kept here so the drawer is decoupled from the grid) ----

  return (
    <div className="h-screen flex overflow-hidden" style={{ background: "var(--bg)" }}>
      <Sidebar
        menu={menus[role]}
        persona={persona}
        role={role}
        currentActionId={currentActionId}
        onNavigate={(id) => setCurrentActionId(id)}
        collapsed={sidebarCollapsed}
        setCollapsed={setSidebarCollapsed}
      />

      <div className="flex-1 flex flex-col min-w-0">
        <TopBar
          title={activeMenuItem?.label || "—"}
          subtitle={activeMenuItem?.section || ""}
          persona={persona}
          role={role}
          onMenuClick={() => setAccountOpen(true)}
          isAdmin={canEdit}
          isEditing={isEditing}
          onStartEdit={() => setIsEditing(true)}
          onStopEdit={() => { setIsEditing(false); setDraft(null); }}
          onSaveEdit={saveEdit}
          hasDraft={!!draft}
        />

        <main className="flex-1 overflow-y-auto scrollbar-thin">
          <div className="max-w-[1440px] mx-auto px-4 sm:px-6 py-6 pb-24">
            {currentActionId ? (
              <PageDispatcher
                actionId={currentActionId}
                role={role}
                onToast={onToast}
                onOpenDetail={openDetail}
                isEditing={isEditing}
                draftMergedParams={draft}
                setDraftMergedParams={setDraft}
                rbac={rbac}
                setRbac={setRbac}
                menus={menus}
                setMenus={setMenus}
                theme={theme}
                setTheme={setTheme}
              />
            ) : (
              <NotAllowedPage persona={persona} role={role} />
            )}
          </div>
        </main>
      </div>

      {/* Floating UI */}
      <PersonaSwitcher role={role} setRole={setRole} />
      <DevtoolsFab open={devOpen} setOpen={setDevOpen} />
      <Devtools open={devOpen} onClose={() => setDevOpen(false)} theme={theme} setTheme={setTheme} />

      {/* Detail drawer */}
      <DetailDrawer
        open={!!detail}
        detailActionId={detail?.detailActionId}
        row={detail?.row}
        role={role}
        onClose={closeDetail}
        onToast={onToast}
      />

      {/* Account modal */}
      <AccountModal open={accountOpen} onClose={() => setAccountOpen(false)} persona={persona} role={role} />

      {/* Toasts */}
      <ToastTray toasts={toasts} remove={removeToast} />
    </div>
  );
};

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
