/* eslint-disable */
// ============================================================
// SETTINGS & RBAC MANAGER  (PartialView: "RBACManager")
// ACTION LIBRARY            (PartialView: "ActionLibrary")
//
// Two admin-only pages that drive the entire framework configuration.
// ============================================================

const { useState: useNv_S, useMemo: useNv_M, useEffect: useNv_E } = React;

// ---- Curated icon set users pick from in the menu editor ----
const MENU_ICONS = [
  "layoutDashboard", "sparkles", "zap", "users", "building", "inbox",
  "bookOpen", "layers", "shield", "sliders", "database", "barChart",
  "diamond", "pulse", "calendar", "tag", "rocket", "globe",
];

const IconPicker = ({ value, onChange }) => {
  const [open, setOpen] = useNv_S(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onDown = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDown);
    return () => document.removeEventListener("mousedown", onDown);
  }, [open]);
  return (
    <div className="relative" ref={ref}>
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        className="h-8 w-8 inline-flex items-center justify-center rounded-md"
        style={{ background: "var(--surface)", color: "var(--ink-2)", border: "1px solid var(--border)" }}
        title="Choose icon"
      >
        <Icon name={value} size={15} />
      </button>
      {open && (
        <div className="absolute z-30 top-10 left-0 w-60 p-2 card backdrop-fade" style={{ boxShadow: "var(--shadow-md)" }}>
          <div className="text-[10.5px] uppercase tracking-wider font-semibold px-1 pb-1.5" style={{ color: "var(--muted)" }}>Icon</div>
          <div className="grid grid-cols-6 gap-1">
            {MENU_ICONS.map((n) => (
              <button
                key={n}
                onClick={() => { onChange(n); setOpen(false); }}
                className="h-9 inline-flex items-center justify-center rounded-md transition-colors"
                style={{
                  background: n === value ? "var(--primary-bg)" : "transparent",
                  color: n === value ? "var(--primary)" : "var(--muted)",
                  border: `1px solid ${n === value ? "var(--primary-ring)" : "transparent"}`,
                }}
                title={n}
              >
                <Icon name={n} size={14} />
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

// ============================================================
// MENU ITEM ROW
// ============================================================
const MenuItemRow = ({ item, action, idx, total, onChange, onMove, onRemove }) => {
  const set = (patch) => onChange({ ...item, ...patch });
  return (
    <div className="card-flat" style={{ opacity: item.visible ? 1 : 0.6 }}>
      <div className="flex items-center gap-2 px-3 py-2" style={{ background: "var(--surface-2)", borderBottom: "1px solid var(--border)" }}>
        <span style={{ color: "var(--subtle)" }}><Icon name="grip" size={14} /></span>
        <Toggle checked={!!item.visible} onChange={(v) => set({ visible: v })} />
        <div className="flex-1 min-w-0">
          <div className="text-[13px] font-medium truncate" style={{ color: "var(--ink)" }}>{item.label}</div>
          <div className="text-[10.5px] truncate font-mono" style={{ color: "var(--subtle)" }}>
            actionId {item.actionId} · {action?.PartialView || "?"}
          </div>
        </div>
        <div className="flex items-center gap-0.5">
          <button disabled={idx === 0} onClick={() => onMove(idx, -1)} className="h-7 w-7 inline-flex items-center justify-center rounded hover:bg-[var(--surface)] disabled:opacity-30" style={{ color: "var(--muted)" }}><Icon name="chevronUp" size={14} /></button>
          <button disabled={idx === total - 1} onClick={() => onMove(idx, 1)} className="h-7 w-7 inline-flex items-center justify-center rounded hover:bg-[var(--surface)] disabled:opacity-30" style={{ color: "var(--muted)" }}><Icon name="chevronDown" size={14} /></button>
          {!item.locked && (
            <button onClick={onRemove} className="h-7 w-7 inline-flex items-center justify-center rounded hover:bg-[var(--danger-bg)]" style={{ color: "var(--danger)" }} title="Remove from menu">
              <Icon name="trash" size={13} />
            </button>
          )}
        </div>
      </div>
      <div className="grid grid-cols-[auto_1fr_1fr] gap-3 p-3 items-end">
        <Field label="Icon"><IconPicker value={item.icon} onChange={(v) => set({ icon: v })} /></Field>
        <Field label="Sidebar label"><TextInput value={item.label} onChange={(v) => set({ label: v })} /></Field>
        <Field label="Section"><TextInput value={item.section || ""} onChange={(v) => set({ section: v })} placeholder="(none)" /></Field>
      </div>
    </div>
  );
};

// ============================================================
// RBAC MANAGER PAGE
// ============================================================
const RBACManagerPage = ({ onToast, rbac, setRbac, menus, setMenus, theme, setTheme }) => {
  const [selectedRole, setSelectedRole] = useNv_S("Admin");
  const allActions = useNv_M(() => mockApi.state.getAllActions(), []);
  const persona = PERSONAS[selectedRole];
  const items = menus[selectedRole] || [];

  // Persist on changes
  const setMenuItems = async (next) => {
    setMenus({ ...menus, [selectedRole]: next });
    await mockApi.putRoleMenu(selectedRole, next).catch(() => {});
  };
  const updateItem = (id, next) => setMenuItems(items.map((it) => (it.id === id ? next : it)));
  const moveItem = (idx, dir) => {
    const arr = [...items];
    const t = idx + dir;
    if (t < 0 || t >= arr.length) return;
    [arr[idx], arr[t]] = [arr[t], arr[idx]];
    setMenuItems(arr);
  };
  const removeItem = (id) => setMenuItems(items.filter((it) => it.id !== id));

  // Actions available to add (PartialView page-like, not already in menu)
  const pageActions = Object.values(allActions).filter((a) => ["Grid", "Dashboard", "RBACManager", "ActionLibrary"].includes(a.PartialView));
  const availableToAdd = pageActions.filter((a) => !items.find((it) => it.actionId === a.ActionId));

  const addAction = async (a) => {
    const next = [...items, {
      id: `m-${a.ActionId}`,
      actionId: a.ActionId,
      label: a.ActionTitle || a.ActionName,
      icon: a.PartialView === "Dashboard" ? "layoutDashboard" : a.PartialView === "Grid" ? "layers" : "sliders",
      section: a.PartialView === "RBACManager" || a.PartialView === "ActionLibrary" ? "Administration" : "Workspace",
      visible: true,
    }];
    setMenuItems(next);
    // Also grant RBAC if not yet
    if (!rbac[selectedRole]?.has(a.ActionId)) {
      const updated = { ...rbac, [selectedRole]: new Set(rbac[selectedRole] || []).add(a.ActionId) };
      setRbac(updated);
      await mockApi.putRoleAccess(selectedRole, a.ActionId, true);
    }
    onToast({ kind: "ok", text: `Added ${a.ActionName} to ${selectedRole}'s menu` });
  };

  return (
    <div className="space-y-5">
      {/* Role picker bar */}
      <div className="card p-2 flex flex-wrap items-center gap-2">
        <div className="px-2 text-[12px] inline-flex items-center gap-2" style={{ color: "var(--muted)" }}>
          <Icon name="users" size={14} style={{ color: "var(--subtle)" }} />
          Configure for role
        </div>
        <div className="inline-flex items-center p-0.5 rounded-md gap-0.5" style={{ background: "var(--surface-2)", border: "1px solid var(--border)" }}>
          {ROLES.map((r) => {
            const active = r.id === selectedRole;
            return (
              <button
                key={r.id}
                onClick={() => setSelectedRole(r.id)}
                className="inline-flex items-center gap-1.5 h-8 px-2.5 rounded text-[12.5px] font-medium transition-all"
                style={{
                  background: active ? "var(--surface)" : "transparent",
                  color: active ? "var(--ink)" : "var(--muted)",
                  boxShadow: active ? "var(--shadow-sm)" : "none",
                }}
              >
                <Icon name={r.icon} size={12} />{r.id}
              </button>
            );
          })}
        </div>
        <div className="flex-1" />
        <div className="text-[11px] px-2 inline-flex items-center gap-2" style={{ color: "var(--subtle)" }}>
          <span>{(rbac[selectedRole] || new Set()).size} actions allowed</span>
          <span style={{ color: "var(--faint)" }}>·</span>
          <span>{items.filter((i) => i.visible).length} in menu</span>
        </div>
      </div>

      <div className="grid gap-4 xl:grid-cols-[1fr_320px]">
        <div className="space-y-2">
          <div className="text-[10.5px] uppercase tracking-wider font-semibold inline-flex items-center gap-1.5" style={{ color: "var(--muted)" }}>
            <Icon name="layout" size={11} /> Menu order
          </div>
          {items.length === 0 ? (
            <div className="card p-10 text-center border-2 border-dashed" style={{ borderColor: "var(--border)" }}>
              <Icon name="layout" size={22} className="mx-auto mb-2" style={{ color: "var(--subtle)" }} />
              <div className="text-[13px] font-medium" style={{ color: "var(--ink-2)" }}>No menu items for this role</div>
              <div className="text-[12px] mt-1" style={{ color: "var(--muted)" }}>Add actions from the panel on the right.</div>
            </div>
          ) : items.map((it, idx) => (
            <MenuItemRow
              key={it.id}
              item={it}
              idx={idx}
              total={items.length}
              action={allActions[it.actionId]}
              onChange={(next) => updateItem(it.id, next)}
              onMove={moveItem}
              onRemove={() => removeItem(it.id)}
            />
          ))}

          {/* Add action */}
          {availableToAdd.length > 0 && (
            <div className="card p-3">
              <div className="text-[10.5px] uppercase tracking-wider font-semibold mb-2" style={{ color: "var(--muted)" }}>Add page to menu</div>
              <div className="flex flex-wrap gap-1.5">
                {availableToAdd.map((a) => (
                  <button
                    key={a.ActionId}
                    onClick={() => addAction(a)}
                    className="inline-flex items-center gap-1.5 h-7 px-2.5 rounded text-[12px] font-medium"
                    style={{ background: "var(--surface-2)", color: "var(--ink-2)", border: "1px solid var(--border)" }}
                  >
                    <Icon name="plus" size={11} style={{ color: "var(--primary)" }} />
                    <span>{a.ActionTitle || a.ActionName}</span>
                    <span className="text-[10px] font-mono" style={{ color: "var(--subtle)" }}>#{a.ActionId}</span>
                  </button>
                ))}
              </div>
            </div>
          )}
        </div>

        <div className="min-w-0">
          <div className="text-[10.5px] uppercase tracking-wider font-semibold inline-flex items-center gap-1.5 mb-2" style={{ color: "var(--muted)" }}>
            <span className="bullet"></span> Live sidebar preview · {persona.name}
          </div>
          <SidebarMiniPreview menu={items} persona={persona} />
          <div className="text-[11px] mt-3 leading-relaxed" style={{ color: "var(--muted)" }}>
            This is exactly what {persona.name} sees when signed in as <span className="font-medium" style={{ color: "var(--ink-2)" }}>{selectedRole}</span>.
            Switch the preview user (bottom-right) to feel it.
          </div>
        </div>
      </div>
    </div>
  );
};

// ---- Sidebar mini-preview ----
const SidebarMiniPreview = ({ menu, persona }) => {
  const sections = [];
  (menu || []).forEach((it) => {
    if (!it.visible) return;
    const key = it.section || "";
    let s = sections.find((x) => x.label === key);
    if (!s) { s = { label: key, items: [] }; sections.push(s); }
    s.items.push(it);
  });
  return (
    <div className="rounded-lg overflow-hidden" style={{ background: "var(--sidebar-bg, #0f1218)", color: "var(--sidebar-text, #d6d1c4)" }}>
      <div className="h-11 flex items-center gap-2 px-3" style={{ borderBottom: "1px solid var(--sidebar-border, rgba(255,255,255,0.05))" }}>
        <div className="h-7 w-7 inline-flex items-center justify-center rounded-md text-white" style={{ background: "var(--primary)" }}>
          <Icon name="diamond" size={12} />
        </div>
        <div className="leading-tight">
          <div className="text-[12px] font-semibold text-white wordmark">Green House</div>
          <div className="text-[9.5px]" style={{ color: "var(--sidebar-muted, #9095a3)" }}>workspace</div>
        </div>
      </div>
      <div className="py-2 min-h-[200px]">
        {sections.length === 0 && <div className="px-3 py-6 text-center text-[12px]" style={{ color: "#6b6e7a" }}>No visible items</div>}
        {sections.map((sec, i) => (
          <div key={i} className="mb-1">
            {sec.label && <div className="px-3 pt-2 pb-1 text-[9.5px] uppercase tracking-wider font-semibold" style={{ color: "#6b6e7a" }}>{sec.label}</div>}
            {sec.items.map((it, j) => (
              <div
                key={it.id}
                className={`mx-1.5 my-0.5 px-2.5 h-8 flex items-center gap-2 rounded-md text-[12px]`}
                style={{
                  background: j === 0 && i === 0 ? "var(--sidebar-active-bg, rgba(232,128,76,0.16))" : "transparent",
                  color: j === 0 && i === 0 ? "var(--sidebar-active-fg, #f49967)" : "var(--sidebar-text, #d6d1c4)",
                }}
              >
                <Icon name={it.icon} size={12} style={{ color: j === 0 && i === 0 ? "var(--sidebar-active-fg, #f49967)" : "var(--sidebar-muted, #9095a3)" }} />
                <span className="truncate">{it.label}</span>
              </div>
            ))}
          </div>
        ))}
      </div>
      <div className="border-t flex items-center gap-2 p-2.5" style={{ borderColor: "rgba(255,255,255,0.05)" }}>
        <Avatar persona={persona} size={28} />
        <div className="min-w-0">
          <div className="text-[12px] font-medium text-white truncate">{persona.name}</div>
          <div className="text-[10.5px] truncate" style={{ color: "var(--sidebar-muted, #9095a3)" }}>{persona.title}</div>
        </div>
      </div>
    </div>
  );
};

// ============================================================
// ACTION LIBRARY PAGE
// ============================================================
const ActionLibraryPage = ({ onToast, rbac, setRbac }) => {
  const [actions, setActions] = useNv_S(() => mockApi.state.getAllActions());
  const [filterKind, setFilterKind] = useNv_S("all");
  const [search, setSearch] = useNv_S("");
  const [selectedId, setSelectedId] = useNv_S(20); // default to Problems grid
  const selected = actions[selectedId];

  const kinds = useNv_M(() => {
    const m = { all: 0 };
    Object.values(actions).forEach((a) => { m[a.PartialView] = (m[a.PartialView] || 0) + 1; m.all++; });
    return m;
  }, [actions]);

  const filtered = useNv_M(() => {
    const q = search.toLowerCase();
    return Object.values(actions).filter((a) => {
      if (filterKind !== "all" && a.PartialView !== filterKind) return false;
      if (!q) return true;
      return [a.ActionName, a.ActionTitle, String(a.ActionId), a.PartialView].some((v) => String(v || "").toLowerCase().includes(q));
    }).sort((a, b) => a.ActionId - b.ActionId);
  }, [actions, filterKind, search]);

  return (
    <div className="grid gap-4 xl:grid-cols-[360px_1fr]">
      <div className="space-y-2 min-w-0">
        <div className="card p-2 space-y-2">
          <div className="relative">
            <Icon name="search" size={12} className="absolute left-2.5 top-1/2 -translate-y-1/2" style={{ color: "var(--subtle)" }} />
            <input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search actions…"
              className="w-full h-8 pl-8 pr-3 text-[13px] focus:outline-none focus:border-[var(--primary)]"
              style={{ background: "var(--surface-2)", color: "var(--ink)", border: "1px solid var(--border)", borderRadius: 7 }}
            />
          </div>
          <div className="flex flex-wrap gap-1">
            {[["all","All"],["Grid","Grids"],["Dashboard","Dashboards"],["KPICardWidget","KPIs"],["ToolbarButton","Toolbar"],["RowAction","Row"],["BulkAction","Bulk"],["Detail","Detail"],["DetailTab","Tabs"]].map(([k, label]) => {
              const active = filterKind === k;
              const n = kinds[k] || 0;
              if (n === 0 && k !== "all") return null;
              return (
                <button
                  key={k}
                  onClick={() => setFilterKind(k)}
                  className="inline-flex items-center gap-1 h-6 px-2 rounded text-[11px] font-medium"
                  style={{
                    background: active ? "var(--primary-bg)" : "var(--surface-2)",
                    color: active ? "var(--primary)" : "var(--muted)",
                    border: `1px solid ${active ? "var(--primary-ring)" : "var(--border)"}`,
                  }}
                >
                  {label} <span className="font-mono">{n}</span>
                </button>
              );
            })}
          </div>
        </div>

        <div className="card overflow-hidden">
          <div className="max-h-[520px] overflow-y-auto scrollbar-thin">
            {filtered.map((a) => (
              <button
                key={a.ActionId}
                onClick={() => setSelectedId(a.ActionId)}
                className="w-full flex items-center gap-2 px-3 py-2 text-left transition-colors"
                style={{
                  background: selectedId === a.ActionId ? "var(--primary-bg)" : "transparent",
                  borderBottom: "1px solid var(--border)",
                }}
                onMouseEnter={(e) => { if (selectedId !== a.ActionId) e.currentTarget.style.background = "var(--surface-2)"; }}
                onMouseLeave={(e) => { if (selectedId !== a.ActionId) e.currentTarget.style.background = "transparent"; }}
              >
                <span className="font-mono text-[10.5px] tabular-nums shrink-0 w-9" style={{ color: selectedId === a.ActionId ? "var(--primary)" : "var(--subtle)" }}>
                  #{a.ActionId}
                </span>
                <div className="flex-1 min-w-0">
                  <div className="text-[13px] font-medium truncate" style={{ color: "var(--ink)" }}>{a.ActionTitle || a.ActionName}</div>
                  <div className="text-[10.5px] font-mono truncate" style={{ color: "var(--subtle)" }}>{a.PartialView}</div>
                </div>
                <RbacDots actionId={a.ActionId} rbac={rbac} />
              </button>
            ))}
          </div>
        </div>
      </div>

      <div className="space-y-3 min-w-0">
        {!selected ? (
          <Empty icon="database" title="Select an action" subtitle="Pick an entry on the left to see its payload." />
        ) : (
          <>
            <div className="card p-4">
              <div className="flex items-start justify-between gap-3 mb-3">
                <div className="min-w-0">
                  <div className="text-[10.5px] uppercase tracking-wider font-semibold" style={{ color: "var(--primary)" }}>
                    actionId <span className="font-mono">{selected.ActionId}</span>
                  </div>
                  <div className="text-[19px] font-semibold mt-0.5" style={{ color: "var(--ink)", letterSpacing: "-0.01em" }}>{selected.ActionTitle || selected.ActionName}</div>
                  <div className="text-[12.5px] mt-0.5 font-mono" style={{ color: "var(--muted)" }}>PartialView: {selected.PartialView}</div>
                </div>
              </div>
              <RoleAccessPill actionId={selected.ActionId} rbac={rbac} setRbac={setRbac} onToast={onToast} />
            </div>

            <div style={{ height: 380 }}>
              <JsonPanel value={selected} onApply={async (next) => {
                if (next.MergedParams) {
                  await mockApi.putActionConfig(selected.ActionId, next.MergedParams);
                }
                setActions({ ...actions, [selected.ActionId]: next });
              }} onToast={onToast} />
            </div>
          </>
        )}
      </div>
    </div>
  );
};

// Small per-role visibility dots in the action library list
const RbacDots = ({ actionId, rbac }) => (
  <div className="flex items-center gap-0.5 shrink-0">
    {ROLES.map((r) => {
      const has = rbac[r.id]?.has(actionId);
      return (
        <span
          key={r.id}
          title={`${r.id}: ${has ? "can see" : "hidden"}`}
          className="w-1.5 h-1.5 rounded-full"
          style={{ background: has ? PERSONAS[r.id].accent : "var(--border-2)" }}
        />
      );
    })}
  </div>
);

Object.assign(window, { RBACManagerPage, ActionLibraryPage, SidebarMiniPreview });
