// T2 Falcon Admin — Hierarchy page

const { useState: useStateH, useRef: useRefH, useEffect: useEffectH, useMemo: useMemoH } = React;

// ===== Clients Tree Panel =====

const NodeRow = ({ node, depth, ancestorsHasNext, isLastChild, parentPath, expanded, onToggle, selected, onSelect, onCtxMenu, ctxOpen, hoveredPath, setHoveredPath, children, t, hideMenus = false, hideChevrons = false }) => {
  const hasChildren = (node.children || []).length > 0;
  const isSelected = selected === node.id;
  const isOnHoverPath = hoveredPath && hoveredPath.has(node.id);
  const ownPath = useMemoH(() => [...parentPath, node.id], [parentPath, node.id]);
  const rowRef = useRefH(null);
  const menuBtnRef = useRefH(null);
  const justClickedRef = useRefH(false);

  // Auto-scroll into view when this row becomes selected programmatically
  // (e.g. via chart-view click, search jump, deep-link). Skipped when the user
  // clicked this row directly — they already see it. block:'nearest' means
  // we only scroll if the row is actually offscreen.
  useEffectH(() => {
    if (!isSelected) return;
    if (justClickedRef.current) {
      justClickedRef.current = false;
      return;
    }
    const el = rowRef.current;
    if (!el) return;
    // Defer to next frame so any pending layout/expand animations settle first
    const raf = requestAnimationFrame(() => {
      el.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' });
    });
    return () => cancelAnimationFrame(raf);
  }, [isSelected]);

  const handleClick = () => {
    justClickedRef.current = true;
    onSelect(node.id);
  };

  const getLogo = () => {
    if (node.type === 'client') return <BrandLogo brand={node.brand} size={26} />;
    const name = (node.name || '').trim();
    const initials = (name.split(/\s+/).map((w) => w[0]).slice(0, 2).join('') || name.slice(0, 2)).toUpperCase();
    return (
      <div
        className="client-logo node-mini"
        style={{ width: 22, height: 22, fontSize: 9, fontWeight: 700 }}>
        {initials}
      </div>);
  };

  const handleMouseEnter = () => {
    setHoveredPath(new Set(ownPath));
  };
  const handleMouseLeave = () => {
    setHoveredPath(null);
  };

  // Build the rail/connector zone
  const rails = [];
  for (let i = 0; i < depth; i++) {
    const isElbowCol = i === depth - 1;
    const continuesDown = ancestorsHasNext[i]; // does ancestor at depth i still have siblings below?
    rails.push(
      <span
        key={i}
        className={`tree-rail ${isElbowCol ? 'elbow' : ''} ${!continuesDown && !isElbowCol ? 'rail-empty' : ''} ${isElbowCol && isLastChild ? 'rail-last' : ''}`}
        aria-hidden="true" />

    );
  }

  return (
    <div className="client-node" data-depth={depth} data-node-id={node.id}>
      <div
        ref={rowRef}
        className={`client-row ${isSelected ? 'selected' : ''} ${isOnHoverPath ? 'on-path' : ''} ${depth > 0 ? 'child-node-row' : ''}`}
        onClick={handleClick}
        onMouseEnter={handleMouseEnter}
        onMouseLeave={handleMouseLeave} style={{ justifyContent: "flex-start" }}>

        <div className="tree-rails" aria-hidden="true">{rails}</div>

        {!hideChevrons && (
        <span
          className={`client-chev ${hasChildren ? expanded ? 'open' : 'collapsed-has-kids' : 'invisible'}`}
          onClick={(e) => {e.stopPropagation();if (hasChildren) onToggle(node.id);}}
          role={hasChildren ? "button" : undefined}
          aria-label={hasChildren ? expanded ? "Collapse" : "Expand" : undefined}>
          <IcChevronRight size={12} stroke={2.4} className="flip-rtl" />
        </span>
        )}
        {getLogo()}
        <span className="client-name" title={node.name}>{node.name}</span>
        {!hideMenus && (
        <button
          ref={menuBtnRef}
          className={`client-menu-btn ${ctxOpen ? 'open' : ''}`}
          onClick={(e) => {e.stopPropagation();onCtxMenu(node.id, menuBtnRef.current);}}
          aria-label="Menu">
          <IcMore size={14} />
        </button>
        )}
      </div>
      {children}
    </div>);
};

const ClientsTree = ({ tree, expanded, toggleExpand, selected, selectNode, ctxOpenFor, setCtxOpenFor, onCtxAction, t, hideRoot = false, hideSectionLabel = false, hideMenus = false, hideChevrons = false, rootClickable = true }) => {
  const [hoveredPath, setHoveredPath] = useStateH(null);
  const [menuAnchor, setMenuAnchor] = useStateH(null); // DOM element of currently-open menu button
  const rootMenuBtnRef = useRefH(null);

  // Reposition the floating menu against its anchor (handles scroll/resize while open)
  const [menuPos, setMenuPos] = useStateH(null);
  useEffectH(() => {
    if (!menuAnchor || !ctxOpenFor) {
      setMenuPos(null);
      return;
    }
    const update = () => {
      const r = menuAnchor.getBoundingClientRect();
      const isRTL = document.body.getAttribute('dir') === 'rtl';
      const top = r.bottom + 6;
      // Anchor menu directly UNDER the button.
      // LTR: pin menu's right edge to button's right edge (use viewport-right offset).
      // RTL: pin menu's left edge to button's left edge.
      if (isRTL) {
        setMenuPos({ top, left: r.left, right: 'auto' });
      } else {
        setMenuPos({ top, left: 'auto', right: window.innerWidth - r.right });
      }
    };
    update();
    window.addEventListener('scroll', update, true);
    window.addEventListener('resize', update);
    return () => {
      window.removeEventListener('scroll', update, true);
      window.removeEventListener('resize', update);
    };
  }, [menuAnchor, ctxOpenFor]);

  // Close on outside click / Esc
  useEffectH(() => {
    if (!ctxOpenFor) return;
    const onDocClick = (e) => {
      if (e.target.closest('.ctx-menu') || e.target.closest('.client-menu-btn')) return;
      setCtxOpenFor(null);
      setMenuAnchor(null);
    };
    const onKey = (e) => {if (e.key === 'Escape') {setCtxOpenFor(null);setMenuAnchor(null);}};
    document.addEventListener('mousedown', onDocClick);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mousedown', onDocClick);
      document.removeEventListener('keydown', onKey);
    };
  }, [ctxOpenFor]);

  const handleCtxMenu = (id, anchorEl) => {
    if (ctxOpenFor === id) {
      setCtxOpenFor(null);
      setMenuAnchor(null);
    } else {
      setCtxOpenFor(id);
      setMenuAnchor(anchorEl);
    }
  };

  // Find the currently-open node to derive its menu items
  const openNode = useMemoH(() => {
    if (!ctxOpenFor) return null;
    const find = (n) => {
      if (n.id === ctxOpenFor) return n;
      for (const c of n.children || []) {const r = find(c);if (r) return r;}
      return null;
    };
    return find(tree);
  }, [ctxOpenFor, tree]);

  const menuItemsFor = (node) => {
    if (!node) return [];
    if (node.type === 'root') return [
    { id: 'addClient', icon: IcBuilding, label: t.addClient },
    { id: 'addUser', icon: IcUserPlus, label: t.addUser }];

    return [
    { id: 'addNode', icon: IcPlus, label: t.addNode },
    { id: 'editNode', icon: IcEdit, label: t.editNode },
    { id: 'addUser', icon: IcUserPlus, label: t.addUser }];

  };

  const renderNode = (node, depth, ancestorsHasNext, isLastChild, parentPath) => {
    const isOpen = !!expanded[node.id];
    const hasChildren = (node.children || []).length > 0;
    const showCtx = ctxOpenFor === node.id;

    const ownPath = [...parentPath, node.id];

    return (
      <NodeRow
        key={node.id}
        node={node}
        depth={depth}
        ancestorsHasNext={ancestorsHasNext}
        isLastChild={isLastChild}
        parentPath={parentPath}
        expanded={isOpen}
        onToggle={toggleExpand}
        selected={selected}
        onSelect={selectNode}
        onCtxMenu={handleCtxMenu}
        ctxOpen={showCtx}
        hoveredPath={hoveredPath}
        setHoveredPath={setHoveredPath}
        t={t}
        hideMenus={hideMenus}
        hideChevrons={hideChevrons}>

        {hasChildren && isOpen &&
        <div className="client-children">
            {node.children.map((c, idx) => {
            const childIsLast = idx === node.children.length - 1;
            const childAncestors = [...ancestorsHasNext, !isLastChild];
            return renderNode(c, depth + 1, childAncestors, childIsLast, ownPath);
          })}
          </div>
        }
      </NodeRow>);

  };

  // Root node is special: rendered outside the list with its own section header
  return (
    <>
      {!hideRoot && (
      <div className={`clients-root ${rootClickable && selected === tree.id ? 'selected' : ''}`}>
        <div
          className="clients-root-inner"
          onClick={rootClickable ? () => selectNode(tree.id) : undefined}
          style={{ cursor: rootClickable ? 'pointer' : 'default' }}>
          {tree.type === 'client' ? (
            <BrandLogo brand={tree.brand} size={26} />
          ) : (
            <span className="clients-root-icon"><IcFalcon size={20} /></span>
          )}
          <span title={tree.name}>{tree.name}</span>
        </div>
        {!hideMenus && (
        <button
          ref={rootMenuBtnRef}
          className={`client-menu-btn ${ctxOpenFor === tree.id ? 'open' : ''}`}
          style={{ opacity: 1, pointerEvents: 'auto' }}
          onClick={(e) => {e.stopPropagation();handleCtxMenu(tree.id, rootMenuBtnRef.current);}}>
          <IcMore size={14} />
        </button>
        )}
      </div>
      )}
      {!hideSectionLabel && <div className="clients-section-label">{t.falconClients}</div>}
      <ScrollableTreeList>
        {tree.children.map((c, idx) => {
          const isLast = idx === tree.children.length - 1;
          return renderNode(c, 0, [], isLast, [tree.id]);
        })}
      </ScrollableTreeList>

      {/* Floating menu — fixed-position so it escapes any overflow:hidden ancestor */}
      {ctxOpenFor && menuPos && openNode &&
      <div
        className="ctx-menu ctx-menu-floating"
        style={{
          position: 'fixed',
          top: menuPos.top,
          left: menuPos.left,
          right: menuPos.right,
          insetInlineStart: 'auto'
        }}
        onClick={(e) => e.stopPropagation()}>
          {menuItemsFor(openNode).map((m) =>
        <button key={m.id}
        className={`ctx-menu-item ${m.highlight ? 'highlighted' : ''}`}
        onClick={() => {onCtxAction(m.id, openNode);setCtxOpenFor(null);setMenuAnchor(null);}}>
              <m.icon size={14} stroke={1.8} />
              <span>{m.label}</span>
            </button>
        )}
        </div>
      }
    </>);

};

// Wraps the tree list with horizontal-scroll detection.
// While scrolled (scrollLeft > 0), reveal full node names instead of truncating.
const ScrollableTreeList = ({ children }) => {
  const ref = useRefH(null);
  const [isScrolled, setIsScrolled] = useStateH(false);

  useEffectH(() => {
    const el = ref.current;
    if (!el) return;
    const onScroll = () => {
      setIsScrolled(el.scrollLeft > 0);
    };
    el.addEventListener('scroll', onScroll, { passive: true });
    return () => el.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <div ref={ref} className={`clients-list ${isScrolled ? 'is-scrolled' : ''}`}>
      <div className="clients-tree-scroll">
        {children}
      </div>
    </div>);
};

// ===== Users Table =====
const StatusBadge = ({ status, t }) => {
  const map = {
    active: { cls: 'active', label: t.statusActive },
    suspended: { cls: 'suspended', label: t.statusSuspended },
    deleted: { cls: 'deleted', label: t.statusDeleted },
    locked: { cls: 'locked', label: t.statusLocked },
    pending: { cls: 'pending', label: t.statusPending },
    expired: { cls: 'expired', label: t.statusExpired || 'Expired' },
    disable: { cls: 'disabled', label: t.statusDisable || 'Disabled' },
    inactive: { cls: 'inactive', label: t.statusInactive || 'Inactive' },
    paid: { cls: 'paid', label: t.statusPaid || 'Paid' }
  };
  const s = map[status] || map.active;
  return (
    <span className={`status-badge ${s.cls}`}>
      <span className="dot"></span>
      {s.label}
    </span>);

};

const Checkbox = ({ checked, onChange }) =>
<span className={`cb ${checked ? 'checked' : ''}`} onClick={(e) => {e.stopPropagation();onChange(!checked);}}>
    {checked && <IcCheck size={11} stroke={3} />}
  </span>;


const SortArrow = ({ dir }) =>
<span className="sort-arrow">
    {dir === 'asc' ? '▲' : dir === 'desc' ? '▼' : '▲▼'}
  </span>;


// ===== Reusable Table Pagination =====
const TablePagination = ({ total, page, pageSize, onPageChange, onPageSizeChange, t, pageSizeOptions = [10, 20, 30, 40] }) => {
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
  const start = total === 0 ? 0 : (page - 1) * pageSize + 1;
  const end = Math.min(total, page * pageSize);
  const goto = (p) => onPageChange && onPageChange(Math.max(1, Math.min(totalPages, p)));
  return (
    <div className="table-footer">
      <span className="table-footer-info">
        {t.pagShowing || 'Showing'} {start} - {end} {t.pagFrom || 'from'} {total}
      </span>
      <div className="table-pager">
        <button className="table-pager-icon flip-rtl" onClick={() => goto(1)} disabled={page <= 1} aria-label="First page">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="11 17 6 12 11 7" /><polyline points="18 17 13 12 18 7" />
          </svg>
        </button>
        <button className="table-pager-icon flip-rtl" onClick={() => goto(page - 1)} disabled={page <= 1} aria-label="Previous page">
          <IcChevronLeft size={14} stroke={2} />
        </button>
        <div className="table-pager-pages">
          <span className="table-pager-num">{page}</span>
          <span className="table-pager-of">{t.of || 'of'}</span>
          <span className="table-pager-total">{totalPages}</span>
        </div>
        <button className="table-pager-icon flip-rtl" onClick={() => goto(page + 1)} disabled={page >= totalPages} aria-label="Next page">
          <IcChevronRight size={14} stroke={2} />
        </button>
        <button className="table-pager-icon flip-rtl" onClick={() => goto(totalPages)} disabled={page >= totalPages} aria-label="Last page">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="13 17 18 12 13 7" /><polyline points="6 17 11 12 6 7" />
          </svg>
        </button>
      </div>
      <div className="table-pager-rows">
        <span>{t.pagRowsPerPage || 'Rows per page'}</span>
        <select className="table-pager-rows-select" value={pageSize} onChange={(e) => onPageSizeChange && onPageSizeChange(Number(e.target.value))}>
          {pageSizeOptions.map((n) => <option key={n} value={n}>{n}</option>)}
        </select>
      </div>
    </div>
  );
};


const UsersTable = ({ users, selected, setSelected, sort, setSort, rowMenuFor, setRowMenuFor, onMoreDetails, t }) => {
  const cols = [
  { id: 'username', label: t.colUsername },
  { id: 'firstName', label: t.colFirstName },
  { id: 'email', label: t.colEmail },
  { id: 'phone', label: t.colPhone },
  { id: 'role', label: t.colRole },
  { id: 'permGroup', label: t.colPermGroup },
  { id: 'status', label: t.colStatus }];


  const sorted = users;

  const allSelected = users.length > 0 && users.every((u) => selected.has(u.id));
  const toggleAll = () => {
    const s = new Set(selected);
    if (allSelected) users.forEach((u) => s.delete(u.id));else
    users.forEach((u) => s.add(u.id));
    setSelected(s);
  };
  const toggleOne = (id) => {
    const s = new Set(selected);
    if (s.has(id)) s.delete(id);else s.add(id);
    setSelected(s);
  };

  return (
    <table className="users-table">
      <thead>
        <tr>
          {cols.map((c) =>
          <th key={c.id}>{c.label}</th>
          )}
          <th className="col-actions">{t.colActions}</th>
        </tr>
      </thead>
      <tbody>
        {sorted.map((u) => {
          const isSel = selected.has(u.id);
          const menuOpen = rowMenuFor === u.id;
          return (
            <tr key={u.id} className={isSel ? 'selected' : ''}>
              <td className="col-username">{u.username}</td>
              <td>{u.firstName}</td>
              <td className="col-email">{u.email}</td>
              <td className="col-phone" dir="ltr">{u.phone}</td>
              <td>{u.role}</td>
              <td>{u.permGroup}</td>
              <td><StatusBadge status={u.status} t={t} /></td>
              <td className="col-actions" style={{ position: 'relative' }}>
                <button className={`row-action-btn ${menuOpen ? 'open' : ''}`}
                onClick={(e) => {e.stopPropagation();setRowMenuFor(menuOpen ? null : u.id);}}>
                  <IcMore size={16} />
                </button>
                {menuOpen &&
                <div className="row-menu" onClick={(e) => e.stopPropagation()}>
                    <button className="row-menu-item" onClick={() => { setRowMenuFor(null); onMoreDetails && onMoreDetails(u); }}>
                      <IcInfo size={14} stroke={1.8} />
                      <span>{t.moreDetails}</span>
                    </button>
                  </div>
                }
              </td>
            </tr>);

        })}
      </tbody>
    </table>);

};

// ===== Kanban/Board View (alternate view of the same users data) =====
const UserCard = ({ user, selected, onToggle, t, rowMenuFor, setRowMenuFor, onMoreDetails }) => {
  const initials = user.firstName.slice(0, 2).toUpperCase();
  const menuOpen = rowMenuFor === user.id;
  return (
    <div className={`user-card ${selected ? 'selected' : ''}`} onClick={() => onToggle(user.id)}>
      <div className="user-card-head">
        <div className="user-card-avatar">{initials}</div>
        <div className="user-card-id">
          <div className="user-card-name">{user.firstName}</div>
          <div className="user-card-username">{user.username}</div>
        </div>
        <button className={`row-action-btn ${menuOpen ? 'open' : ''}`}
        onClick={(e) => {e.stopPropagation();setRowMenuFor(menuOpen ? null : user.id);}}>
          <IcMore size={16} />
        </button>
        {menuOpen &&
        <div className="row-menu" style={{ top: 28, insetInlineEnd: 0 }} onClick={(e) => e.stopPropagation()}>
            <button className="row-menu-item" onClick={() => { setRowMenuFor(null); onMoreDetails && onMoreDetails(user); }}>
              <IcInfo size={14} stroke={1.8} />
              <span>{t.moreDetails}</span>
            </button>
          </div>
        }
      </div>
      <div className="user-card-contact">
        <div className="user-card-line">
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="18" height="14" rx="2" /><path d="m3 7 9 6 9-6" /></svg>
          <span>{user.email}</span>
        </div>
        <div className="user-card-line" dir="ltr">
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92Z" /></svg>
          <span>{user.phone}</span>
        </div>
      </div>
      <div className="user-card-foot">
        <span className="role-pill">{user.role}</span>
        <span className="perm-pill">{user.permGroup}</span>
      </div>
    </div>);

};

const KanbanView = ({ users, selected, setSelected, rowMenuFor, setRowMenuFor, onMoreDetails, t }) => {
  const columns = [
  { id: 'active', label: t.statusActive, cls: 'active' },
  { id: 'pending', label: t.statusPending, cls: 'pending' },
  { id: 'suspended', label: t.statusSuspended, cls: 'suspended' },
  { id: 'locked', label: t.statusLocked, cls: 'locked' },
  { id: 'deleted', label: t.statusDeleted, cls: 'deleted' }];

  const toggle = (id) => {
    const s = new Set(selected);
    if (s.has(id)) s.delete(id);else s.add(id);
    setSelected(s);
  };
  return (
    <div className="kanban">
      {columns.map((col) => {
        const colUsers = users.filter((u) => u.status === col.id);
        return (
          <div key={col.id} className="kanban-col">
            <div className="kanban-col-head">
              <span className={`status-badge ${col.cls}`}>
                <span className="dot"></span>{col.label}
              </span>
              <span className="kanban-count">{colUsers.length}</span>
            </div>
            <div className="kanban-col-body">
              {colUsers.length === 0 ?
              <div className="kanban-empty">—</div> :

              colUsers.map((u) =>
              <UserCard
                key={u.id}
                user={u}
                selected={selected.has(u.id)}
                onToggle={toggle}
                t={t}
                rowMenuFor={rowMenuFor}
                setRowMenuFor={setRowMenuFor} />

              )
              }
            </div>
          </div>);

      })}
    </div>);

};

// ===== Org Chart View (visual tree diagram of the hierarchy) =====
const CHART_CARD_W = 180;
const CHART_CARD_H = 56;
const CHART_H_GAP = 60;
const CHART_V_GAP = 14;
const CHART_PAD = 24;

// Recursive layout: returns { width, height, cards: [{node, x, y, depth}], lines: [{d}] }
const layoutChart = (node, x, y, depth = 0) => {
  const cards = [];
  const lines = [];
  const children = node.children || [];
  if (children.length === 0) {
    cards.push({ node, x, y, depth });
    return { width: CHART_CARD_W, height: CHART_CARD_H, cards, lines, selfY: y };
  }
  let childY = y;
  const childResults = [];
  for (const child of children) {
    const childX = x + CHART_CARD_W + CHART_H_GAP;
    const r = layoutChart(child, childX, childY, depth + 1);
    childResults.push(r);
    cards.push(...r.cards);
    lines.push(...r.lines);
    childY += r.height + CHART_V_GAP;
  }
  const totalHeight = childY - y - CHART_V_GAP;
  const height = Math.max(CHART_CARD_H, totalHeight);
  // Center parent card vertically to span of children
  const firstChildCenter = childResults[0].selfY + CHART_CARD_H / 2;
  const lastChildCenter = childResults[childResults.length - 1].selfY + CHART_CARD_H / 2;
  const midY = (firstChildCenter + lastChildCenter) / 2;
  const selfY = midY - CHART_CARD_H / 2;
  cards.push({ node, x, y: selfY, depth });
  // Draw connector lines: from parent's right-center to each child's left-center, bent at midpoint
  const parentRightX = x + CHART_CARD_W;
  const parentCenterY = selfY + CHART_CARD_H / 2;
  const bendX = parentRightX + CHART_H_GAP / 2;
  for (const r of childResults) {
    const childLeftX = r.cards.find((c) => c.node === r.cards[r.cards.length - 1].node)?.x ?? x + CHART_CARD_W + CHART_H_GAP;
    const childCenterY = r.selfY + CHART_CARD_H / 2;
    // L-path: horizontal from parent, vertical bend, horizontal to child
    const d = `M ${parentRightX} ${parentCenterY} L ${bendX} ${parentCenterY} L ${bendX} ${childCenterY} L ${x + CHART_CARD_W + CHART_H_GAP} ${childCenterY}`;
    lines.push({ d });
  }
  // Width: CARD_W + H_GAP + max child subtree width
  const maxChildWidth = Math.max(...childResults.map((r) => r.width));
  const width = CHART_CARD_W + CHART_H_GAP + maxChildWidth;
  return { width, height, cards, lines, selfY };
};

const ChartCard = ({ node, x, y, selected, dimmed, focused, onSelect, t }) => {
  const isRoot = node.type === 'root';
  const isClient = node.type === 'client';
  const childCount = (node.children || []).length;
  const renderLogo = () => {
    if (isRoot) {
      return <span className="chart-card-ic root"><IcFalcon size={16} /></span>;
    }
    if (isClient) return <BrandLogo brand={node.brand} size={28} />;
    const initials = (node.name || '').split(/\s+/).map((w) => w[0]).slice(0, 2).join('').toUpperCase();
    return <span className="chart-card-ic sub">{initials}</span>;
  };
  return (
    <div
      className={`chart-card ${selected ? 'selected' : ''} ${isRoot ? 'is-root' : ''} ${isClient ? 'is-client' : ''} ${dimmed ? 'is-dimmed' : ''} ${focused ? 'is-focused' : ''}`}
      style={{ left: x, top: y, width: CHART_CARD_W, height: CHART_CARD_H }}
      onClick={() => onSelect(node.id)}
      role="button"
      tabIndex={0}>
      
      {renderLogo()}
      <div className="chart-card-text">
        <div className="chart-card-name">{node.name}</div>
        {childCount > 0 &&
        <div className="chart-card-meta">
            {childCount} {childCount === 1 ? t.chartChild : t.chartChildren}
          </div>
        }
      </div>
    </div>);

};

const OrgChartView = ({ tree, selected, onSelect, t }) => {
  const layout = useMemoH(() => layoutChart(tree, CHART_PAD, CHART_PAD), [tree]);
  const totalW = layout.width + CHART_PAD * 2;
  const totalH = layout.height + CHART_PAD * 2;

  const [zoom, setZoom] = useStateH(1);
  const [pan, setPan] = useStateH({ x: 0, y: 0 });
  const [focusedId, setFocusedId] = useStateH(null);
  const [animating, setAnimating] = useStateH(false);
  const dragRef = useRefH({ active: false, startX: 0, startY: 0, origX: 0, origY: 0, moved: 0 });
  const viewportRef = useRefH(null);
  const prevViewRef = useRefH({ zoom: 1, pan: { x: 0, y: 0 } });

  const focusedCard = focusedId ? layout.cards.find((c) => c.node.id === focusedId) : null;
  const focusedNode = focusedCard ? focusedCard.node : null;

  const clampZoom = (z) => Math.min(2, Math.max(0.3, z));

  const withAnim = (fn) => {
    setAnimating(true);
    fn();
    setTimeout(() => setAnimating(false), 520);
  };

  const focusOnCard = (card) => {
    const vp = viewportRef.current;
    if (!vp) return;
    const rect = vp.getBoundingClientRect();
    const targetZoom = 1.6;
    const cx = card.x + CHART_CARD_W / 2;
    const cy = card.y + CHART_CARD_H / 2;
    // Place card near top-third so user circles below are fully visible
    const targetX = rect.width / 2 - cx * targetZoom;
    const targetY = rect.height * 0.26 - cy * targetZoom;
    prevViewRef.current = { zoom, pan: { ...pan } };
    withAnim(() => {
      setZoom(targetZoom);
      setPan({ x: targetX, y: targetY });
      setFocusedId(card.node.id);
    });
  };

  const exitFocus = () => {
    if (!focusedId) return;
    const prev = prevViewRef.current;
    withAnim(() => {
      setFocusedId(null);
      setZoom(prev.zoom);
      setPan(prev.pan);
    });
  };

  const zoomIn = () => {if (focusedId) return;setZoom((z) => clampZoom(+(z + 0.15).toFixed(2)));};
  const zoomOut = () => {
    if (focusedId) {exitFocus();return;}
    setZoom((z) => clampZoom(+(z - 0.15).toFixed(2)));
  };
  const resetView = () => {
    if (focusedId) {exitFocus();return;}
    withAnim(() => {setZoom(1);setPan({ x: 0, y: 0 });});
  };
  const fitToView = () => {
    if (focusedId) {exitFocus();return;}
    const vp = viewportRef.current;
    if (!vp) return;
    const rect = vp.getBoundingClientRect();
    const scale = Math.min(rect.width / totalW, rect.height / totalH, 1);
    withAnim(() => {
      setZoom(+scale.toFixed(2));
      setPan({ x: (rect.width - totalW * scale) / 2, y: (rect.height - totalH * scale) / 2 });
    });
  };

  // Wheel → zoom (at cursor)
  const onWheel = (e) => {
    e.preventDefault();
    if (focusedId) {
      // In focus mode: any zoom-out gesture exits focus
      if (e.deltaY > 10) exitFocus();
      return;
    }
    const delta = -e.deltaY * 0.0015;
    setZoom((prev) => {
      const next = clampZoom(prev + delta);
      if (next === prev) return prev;
      const rect = viewportRef.current.getBoundingClientRect();
      const cx = e.clientX - rect.left;
      const cy = e.clientY - rect.top;
      // Keep the point under cursor stable
      setPan((p) => ({
        x: cx - (cx - p.x) * (next / prev),
        y: cy - (cy - p.y) * (next / prev)
      }));
      return next;
    });
  };

  // Mouse drag pan (skip when clicking a card; disabled in focus)
  const onMouseDown = (e) => {
    if (focusedId) return;
    if (e.target.closest('.chart-card')) return;
    if (e.target.closest('.chart-user-circle')) return;
    e.preventDefault();
    dragRef.current = {
      active: true,
      startX: e.clientX,
      startY: e.clientY,
      origX: pan.x,
      origY: pan.y,
      moved: 0
    };
    viewportRef.current.classList.add('panning');
  };
  const onMouseMove = (e) => {
    const d = dragRef.current;
    if (!d.active) return;
    const dx = e.clientX - d.startX;
    const dy = e.clientY - d.startY;
    d.moved = Math.max(d.moved, Math.abs(dx) + Math.abs(dy));
    setPan({ x: d.origX + dx, y: d.origY + dy });
  };
  const onMouseUp = () => {
    dragRef.current.active = false;
    if (viewportRef.current) viewportRef.current.classList.remove('panning');
  };

  useEffectH(() => {
    const up = () => onMouseUp();
    window.addEventListener('mouseup', up);
    return () => window.removeEventListener('mouseup', up);
  }, []);

  // Attach wheel with {passive:false} so preventDefault works
  useEffectH(() => {
    const el = viewportRef.current;
    if (!el) return;
    const handler = (e) => onWheel(e);
    el.addEventListener('wheel', handler, { passive: false });
    return () => el.removeEventListener('wheel', handler);
  }, [zoom, pan.x, pan.y]);

  return (
    <div className="org-chart-wrap">
      <div className="org-chart-toolbar">
        <div className="chart-legend">
          <span className="chart-legend-item"><span className="dot root"></span>{t.chartLegendRoot}</span>
          <span className="chart-legend-item"><span className="dot client"></span>{t.chartLegendClient}</span>
          <span className="chart-legend-item"><span className="dot sub"></span>{t.chartLegendNode}</span>
        </div>
        <div className="chart-hint">
          {focusedNode ? `${focusedNode.name} — ${(focusedNode.users || []).length} users` : t.chartHint}
        </div>
      </div>
      <div
        className={`org-chart-canvas-scroll ${focusedId ? 'is-focused' : ''}`}
        ref={viewportRef}
        onMouseDown={onMouseDown}
        onMouseMove={onMouseMove}
        onClick={(e) => {
          // Click empty area while focused → exit
          if (focusedId && !e.target.closest('.chart-card') && !e.target.closest('.chart-user-circle') && !e.target.closest('.chart-zoom-controls') && !e.target.closest('.chart-focus-close')) {
            exitFocus();
          }
        }}>
        
        <div
          className={`org-chart-canvas ${animating ? 'animating' : ''}`}
          style={{
            width: totalW,
            height: totalH,
            transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
            transformOrigin: '0 0'
          }}>
          
          <svg className="org-chart-lines" width={totalW} height={totalH}>
            {layout.lines.map((l, i) =>
            <path key={i} d={l.d} fill="none" stroke="#7C82A9" strokeWidth="1.5" strokeOpacity="0.5" />
            )}
          </svg>
          {layout.cards.map(({ node, x, y }) => {
            const isDimmed = focusedId && node.id !== focusedId;
            const isFocused = focusedId === node.id;
            return (
              <ChartCard
                key={node.id}
                node={node}
                x={x}
                y={y}
                selected={selected === node.id}
                dimmed={isDimmed}
                focused={isFocused}
                onSelect={(id) => {
                  if (dragRef.current.moved > 4) return;
                  if (focusedId) {exitFocus();return;}
                  // Clicking root doesn't focus (no meaningful user ring on Falcon)
                  if (node.type === 'root') {onSelect(id);return;}
                  focusOnCard({ node, x, y });
                }}
                t={t} />);


          })}

          {/* User circles around the focused node */}
          {focusedCard && (() => {
            const users = focusedNode.users || [];
            const count = users.length;
            const cardCenterX = focusedCard.x + CHART_CARD_W / 2;
            const cardBottomY = focusedCard.y + CHART_CARD_H;
            const circleSize = 54;
            const spacing = 18;
            const rowWidth = count * circleSize + (count - 1) * spacing;
            const startX = cardCenterX - rowWidth / 2;
            const rowY = cardBottomY + 44;
            return (
              <>
                {/* Connector line from card bottom to user row */}
                <svg className="chart-user-connector" width={totalW} height={totalH} style={{ position: 'absolute', left: 0, top: 0, pointerEvents: 'none' }}>
                  <path
                    d={`M ${cardCenterX} ${cardBottomY} L ${cardCenterX} ${rowY + circleSize / 2}`}
                    stroke="#0d3f44"
                    strokeWidth="1.5"
                    strokeDasharray="3 3"
                    fill="none"
                    opacity="0.4" />
                  
                </svg>
                {users.map((u, i) => {
                  const cx = startX + i * (circleSize + spacing);
                  return (
                    <div
                      key={u.id}
                      className={`chart-user-circle status-${u.status}`}
                      style={{
                        left: cx,
                        top: rowY,
                        width: circleSize,
                        height: circleSize,
                        animationDelay: `${180 + i * 60}ms`
                      }}
                      onClick={(e) => {e.stopPropagation();onSelect(focusedNode.id);}}
                      title={`${u.firstName} — ${u.status}`}>
                      
                      <span className="chart-user-initials">{u.firstName.slice(0, 2).toUpperCase()}</span>
                      <span className="chart-user-status-dot"></span>
                    </div>);

                })}
                {/* Label row below circles */}
                {users.map((u, i) => {
                  const cx = startX + i * (circleSize + spacing);
                  return (
                    <div
                      key={'lbl-' + u.id}
                      className="chart-user-label"
                      style={{
                        left: cx - 8,
                        top: rowY + circleSize + 6,
                        width: circleSize + 16,
                        animationDelay: `${260 + i * 60}ms`
                      }}>
                      
                      <div className="chart-user-name">{u.firstName}</div>
                      <div className="chart-user-role">{u.role}</div>
                    </div>);

                })}
              </>);

          })()}
        </div>

        {/* Focus close button */}
        {focusedId &&
        <button className="chart-focus-close" onClick={exitFocus} aria-label="Exit focus">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" /></svg>
            <span>Exit focus</span>
          </button>
        }

        {/* Zoom controls */}
        <div className="chart-zoom-controls">
          <button className="chart-zoom-btn" onClick={zoomIn} title="Zoom in" aria-label="Zoom in" disabled={!!focusedId}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" /><line x1="11" y1="8" x2="11" y2="14" /><line x1="8" y1="11" x2="14" y2="11" /></svg>
          </button>
          <button className="chart-zoom-btn" onClick={zoomOut} title={focusedId ? 'Exit focus' : 'Zoom out'} aria-label="Zoom out">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" /><line x1="8" y1="11" x2="14" y2="11" /></svg>
          </button>
          <div className="chart-zoom-level">{Math.round(zoom * 100)}%</div>
          <button className="chart-zoom-btn" onClick={fitToView} title="Fit to view" aria-label="Fit">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 7V3h4M21 7V3h-4M3 17v4h4M21 17v4h-4" /></svg>
          </button>
          <button className="chart-zoom-btn" onClick={resetView} title="Reset" aria-label="Reset">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12a9 9 0 1 0 3-6.7L3 8" /><polyline points="3 3 3 8 8 8" /></svg>
          </button>
        </div>
      </div>
    </div>);

};

// ===== Information Panel =====
// Static mock info keyed by node id — falls back to generic values so every node renders cleanly.
const NODE_INFO = {
  aramco: {
    accountName: 'Aramco', financeId: 'SAR-AR-2025',
    classification: 'National Oil & Gas Company', subClassification: 'Energy · Petroleum',
    entityName: 'Saudi Aramco', authorityType: 'Government-Owned Enterprise',
    sector: 'Energy Sector', budget: '489B SAR',
    country: 'Kingdom Of Saudi Arabia', city: 'Riyadh',
    district: 'Dhahran Techno Valley', street: 'King Abdulaziz Road',
    building: '3301', postal: '31311',
    addlAddr: 'Saudi Aramco Headquarters', anotherId: 'CR 2050002313',
    vat: '300001400300003'
  },
  snb: {
    accountName: 'Saudi National Bank', financeId: 'SAR-SNB-2025',
    classification: 'Commercial Bank', subClassification: 'Finance · Banking',
    entityName: 'The Saudi National Bank', authorityType: 'Public Joint Stock Company',
    sector: 'Financial Services', budget: '215B SAR',
    country: 'Kingdom Of Saudi Arabia', city: 'Riyadh',
    district: 'King Abdullah Financial District', street: 'King Fahd Road',
    building: '3208', postal: '12382',
    addlAddr: 'SNB Tower', anotherId: 'CR 1010035319',
    vat: '300000000100003'
  },
  bupa: {
    accountName: 'Bupa Arabia', financeId: 'SAR-BUP-2025',
    classification: 'Health Insurance', subClassification: 'Insurance · Cooperative',
    entityName: 'Bupa Arabia for Cooperative Insurance', authorityType: 'Public Joint Stock Company',
    sector: 'Insurance Sector', budget: '18B SAR',
    country: 'Kingdom Of Saudi Arabia', city: 'Jeddah',
    district: 'Al Salamah', street: 'Prince Sultan Road',
    building: '7682', postal: '23525',
    addlAddr: 'Bupa Arabia Headquarters', anotherId: 'CR 4030178312',
    vat: '300002207300003'
  },
  falcon: {
    accountName: 'Falcon (T2)', financeId: 'SAR-T2-2025',
    classification: 'Platform · Root', subClassification: 'Govt. Comms · Messaging',
    entityName: 'Falcon Platform', authorityType: 'Managed Platform',
    sector: 'Telecom · ICT', budget: '—',
    country: 'Kingdom Of Saudi Arabia', city: 'Riyadh',
    district: 'Al Olaya', street: 'Olaya Street',
    building: '—', postal: '—',
    addlAddr: '—', anotherId: '—', vat: '—'
  }
};
const InfoPanel = ({ node, t, editing, draft, setDraft }) => {
  // Walk up to nearest client for sub-nodes so children inherit sensible defaults
  const info = NODE_INFO[node.id] || NODE_INFO[node.clientId] || {
    accountName: node.name, financeId: 'SAR-' + node.id.toUpperCase() + '-2025',
    classification: node.type === 'client' ? 'Organization' : 'Sub-Node',
    subClassification: '—',
    entityName: node.name, authorityType: 'Organizational Unit',
    sector: '—', budget: '—',
    country: 'Kingdom Of Saudi Arabia', city: '—', district: '—', street: '—',
    building: '—', postal: '—', addlAddr: '—', anotherId: '—', vat: '—'
  };
  const data = editing && draft ? draft : info;
  const update = (k, v) => setDraft && setDraft((d) => ({ ...(d || info), [k]: v }));

  const cleanVal = (v) => v === '—' ? '' : (v || '');

  // Field types matching Add Client Step 1
  const SELECT_OPTIONS = {
    classification:    ['Government', 'Banking', 'Healthcare', 'Energy', 'Retail', 'Organization', 'Sub-Node'],
    subClassification: ['Public Sector', 'Commercial', 'Non-profit'],
    authorityType:     ['Government', 'Private', 'Joint Venture', 'Organizational Unit'],
    country:           ['Kingdom Of Saudi Arabia', 'Saudi Arabia', 'UAE', 'Egypt', 'Jordan'],
    city:              ['Riyadh', 'Jeddah', 'Dammam', 'Mecca']
  };

  const TextField = ({ label, value, fieldKey, placeholder }) => (
    <div className="ac-field info-field">
      <label className="ac-label info-field-label">{label}</label>
      {editing ?
        <input
          className="ac-input"
          placeholder={placeholder || ''}
          value={cleanVal(value)}
          onChange={(e) => update(fieldKey, e.target.value)} /> :
        <span className="info-field-value">{value}</span>
      }
    </div>
  );

  const SelectField = ({ label, value, fieldKey, options }) => (
    <div className="ac-field info-field">
      <label className="ac-label info-field-label">{label}</label>
      {editing ?
        <div className="ac-select-wrap">
          <select className="ac-input" value={cleanVal(value)} onChange={(e) => update(fieldKey, e.target.value)}>
            <option value=""></option>
            {options.map((o) => <option key={o} value={o}>{o}</option>)}
          </select>
          <span className="ac-select-chev"><IcChevronDown size={14} stroke={2} /></span>
        </div> :
        <span className="info-field-value">{value}</span>
      }
    </div>
  );

  const fileRef = React.useRef(null);
  const initials = (data.accountName || node.name || '?').slice(0, 2).toUpperCase();
  const photo = data.clientPhoto || '';
  const onPickFile = (e) => {
    const f = e.target.files && e.target.files[0];
    if (!f) return;
    const r = new FileReader();
    r.onload = (ev) => update('clientPhoto', ev.target.result);
    r.readAsDataURL(f);
  };

  return (
    <div className={`info-panel ${editing ? 'is-editing' : ''}`}>
      <div className="info-panel-header">{t.information}</div>
      <div className="info-panel-body">
        {editing ? (
          <div className="au-avatar-row">
            <div className="au-avatar-left">
              <div className="au-avatar-circle">
                {photo ? (
                  <img src={photo} alt="avatar" style={{ width: '100%', height: '100%', objectFit: 'cover', borderRadius: '50%' }} />
                ) : node.brand ? (
                  <BrandLogo brand={node.brand} size={64} />
                ) : (
                  <span style={{ fontSize: 22, fontWeight: 700, color: '#0d3f44' }}>{initials}</span>
                )}
                {photo && (
                  <>
                    <button type="button" className="au-avatar-edit" aria-label="Edit photo"
                      onClick={(e) => { e.stopPropagation(); fileRef.current && fileRef.current.click(); }}>
                      <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
                        <path d="M12 20h9" /><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" />
                      </svg>
                    </button>
                    <button type="button" className="au-avatar-delete" aria-label="Remove photo"
                      onClick={(e) => { e.stopPropagation(); update('clientPhoto', ''); }}>
                      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
                        <line x1="6" y1="6" x2="18" y2="18" /><line x1="6" y1="18" x2="18" y2="6" />
                      </svg>
                    </button>
                  </>
                )}
              </div>
              <div className="au-avatar-label">
                Client Picture
                <span className="sub">PNG, JPG up to 2MB</span>
              </div>
            </div>
            <div className="au-avatar-right">
              <span className="au-drag-hint">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><polyline points="16 16 12 12 8 16" /><line x1="12" y1="12" x2="12" y2="21" /><path d="M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" /></svg>
                Drag a photo here or
              </span>
              <button type="button" className="btn btn-primary" onClick={() => fileRef.current && fileRef.current.click()}>Upload Photo</button>
              <input ref={fileRef} type="file" accept="image/*" style={{ display: 'none' }} onChange={onPickFile} />
            </div>
          </div>
        ) : (
          <div className="info-client-pic">
            <div className="info-client-pic-circle">
              {photo ? (
                <img src={photo} alt="" />
              ) : node.brand ? (
                <BrandLogo brand={node.brand} size={84} />
              ) : (
                <span className="info-client-pic-initials">{initials}</span>
              )}
            </div>
            <div className="info-client-pic-meta">
              <div className="info-client-pic-name">{data.accountName || node.name}</div>
              <div className="info-client-pic-label">Client Picture</div>
            </div>
          </div>
        )}
        <div className="info-grid info-grid-top">
          <TextField   label={t.infoAccountName}       value={data.accountName}       fieldKey="accountName"       placeholder="Start with letter · Max 30 Characters" />
          <TextField   label={t.infoFinanceId}         value={data.financeId}         fieldKey="financeId" />
          <SelectField label={t.infoClassification}    value={data.classification}    fieldKey="classification"    options={SELECT_OPTIONS.classification} />
          <SelectField label={t.infoSubClassification} value={data.subClassification} fieldKey="subClassification" options={SELECT_OPTIONS.subClassification} />
        </div>
        <div className="info-grid info-grid-bottom">
          <div className="info-section-title">{t.infoAccountOfficial}</div>
          <TextField   label={t.infoEntityName}    value={data.entityName}    fieldKey="entityName" />
          <SelectField label={t.infoAuthorityType} value={data.authorityType} fieldKey="authorityType" options={SELECT_OPTIONS.authorityType} />
          <TextField   label={t.infoSector}        value={data.sector}        fieldKey="sector" />
          <TextField   label={t.infoBudget}        value={data.budget}        fieldKey="budget" />
          <SelectField label={t.infoCountry}       value={data.country}       fieldKey="country"       options={SELECT_OPTIONS.country} />
          <SelectField label={t.infoCity}          value={data.city}          fieldKey="city"          options={SELECT_OPTIONS.city} />
          <TextField   label={t.infoDistrict}      value={data.district}      fieldKey="district" />
          <TextField   label={t.infoStreet}        value={data.street}        fieldKey="street" />
          <TextField   label={t.infoBuilding}      value={data.building}      fieldKey="building" />
          <TextField   label={t.infoPostal}        value={data.postal}        fieldKey="postal" />
          <TextField   label={t.infoAddlAddr}      value={data.addlAddr}      fieldKey="addlAddr" />
          <TextField   label={t.infoAnotherId}     value={data.anotherId}     fieldKey="anotherId" />
          <TextField   label={t.infoVAT}           value={data.vat}           fieldKey="vat" />
        </div>
      </div>
    </div>);

};

// ===== Main Hierarchy Page =====
const HierarchyPage = ({ tree, setTree, selected, selectNode, expanded, toggleExpand, lang, t, pushToast, drawer, setDrawer, ctxOpenFor, setCtxOpenFor }) => {
  const [selectedUsers, setSelectedUsers] = useStateH(new Set(['u3'])); // Hajeer selected per ref
  const [sort, setSort] = useStateH({ col: null, dir: null });
  const [rowMenuFor, setRowMenuFor] = useStateH(null);
  const [activeTab, setActiveTab] = useStateH('hierarchy');
  const [userPage, setUserPage] = useStateH(1);
  const [userPageSize, setUserPageSize] = useStateH(20);
  const [hierarchyView, setHierarchyView] = useStateH('tree'); // 'tree' | 'chart'
  const [infoOpen, setInfoOpen] = useStateH(false);
  const [addUserOpen, setAddUserOpen] = useStateH(false);
  const [addClientOpen, setAddClientOpen] = useStateH(false);
  const [detailUser, setDetailUser] = useStateH(null);
  const [infoEditing, setInfoEditing] = useStateH(false);
  const [infoDraft, setInfoDraft] = useStateH(null);

  // Close info panel when switching to a different node
  useEffectH(() => {setInfoOpen(false); setDetailUser(null); setInfoEditing(false); setInfoDraft(null);}, [selected]);

  // Close menus on outside click
  useEffectH(() => {
    const onDoc = () => {setRowMenuFor(null);setCtxOpenFor(null);};
    document.addEventListener('click', onDoc);
    return () => document.removeEventListener('click', onDoc);
  }, []);

  const selectedNode = findNode(tree, selected) || tree;
  const isRoot = selectedNode.id === tree.id;
  const users = selectedNode.users || [];

  // Handlers for context menu actions
  const handleCtxAction = (action, node) => {
    if (action === 'addClient') {
      setAddClientOpen(true);
    } else if (action === 'addNode') {
      setDrawer({ mode: 'add', targetId: node.id });
    } else if (action === 'editNode') {
      setDrawer({ mode: 'edit', targetId: node.id, initialName: node.name });
    } else if (action === 'addUser') {
      setAddUserOpen(true);
    }
  };

  const tabs = isRoot ?
  [
  { id: 'hierarchy', label: t.tabHierarchy },
  { id: 'settings', label: t.tabSettings }] :

  [
  { id: 'hierarchy', label: t.tabHierarchy },
  { id: 'commChannels', label: t.tabCommChannels },
  { id: 'appsServices', label: t.tabAppsServices },
  { id: 'settings', label: t.tabSettings }];


  return (
    <>
      <div className={`page ${activeTab === 'hierarchy' && hierarchyView === 'chart' ? 'chart-mode' : ''}`}>
      {/* Clients tree panel */}
      <div className="clients-panel">
        <ClientsTree
            tree={tree}
            expanded={expanded}
            toggleExpand={toggleExpand}
            selected={selected}
            selectNode={selectNode}
            ctxOpenFor={ctxOpenFor}
            setCtxOpenFor={setCtxOpenFor}
            onCtxAction={handleCtxAction}
            t={t} />

      </div>

      {/* Content panel */}
      <div className="content-panel">
        {addClientOpen ?
          <AddClientFlow
            onClose={() => setAddClientOpen(false)}
            t={t}
            pushToast={pushToast}
            parentNode={selectedNode} /> :
          addUserOpen ?
          <AddUserFlow
            onClose={() => setAddUserOpen(false)}
            t={t}
            pushToast={pushToast}
            node={selectedNode} /> :
          detailUser ?
          <UserDetailsPage
            user={detailUser}
            node={selectedNode}
            onBack={() => setDetailUser(null)}
            t={t}
            pushToast={pushToast} /> :



          <>
        <div className="tabs-bar tabs-bar-with-toggle">
          <div className="tabs-bar-left">
            {tabs.map((tb) =>
                <button key={tb.id} className={`tab ${activeTab === tb.id ? 'active' : ''}`}
                onClick={() => setActiveTab(tb.id)}>
                {tb.label}
              </button>
                )}
          </div>
          {activeTab === 'hierarchy' &&
              <div className="view-toggle tabs-bar-toggle" role="tablist" aria-label="Hierarchy view">
              <button
                  role="tab"
                  aria-selected={hierarchyView === 'tree'}
                  className={`view-toggle-btn ${hierarchyView === 'tree' ? 'active' : ''}`}
                  onClick={() => setHierarchyView('tree')}>
                  
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="8" y1="6" x2="21" y2="6" /><line x1="8" y1="12" x2="21" y2="12" /><line x1="8" y1="18" x2="21" y2="18" /><line x1="3" y1="6" x2="3.01" y2="6" /><line x1="3" y1="12" x2="3.01" y2="12" /><line x1="3" y1="18" x2="3.01" y2="18" /></svg>
                <span>{t.viewTree}</span>
              </button>
              <button
                  role="tab"
                  aria-selected={hierarchyView === 'chart'}
                  className={`view-toggle-btn ${hierarchyView === 'chart' ? 'active' : ''}`}
                  onClick={() => setHierarchyView('chart')}>
                  
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="4" y="2" width="16" height="6" rx="1" /><rect x="2" y="15" width="7" height="6" rx="1" /><rect x="15" y="15" width="7" height="6" rx="1" /><path d="M12 8v4M5.5 12h13M5.5 12v3M18.5 12v3" /></svg>
                <span>{t.viewChart}</span>
              </button>
            </div>
              }
        </div>

        <div className="content-body">
          {activeTab === 'hierarchy' && hierarchyView === 'chart' ?
              <div className="org-chart-inpanel">
              <OrgChartView
                  tree={tree}
                  selected={selected}
                  onSelect={(id) => {selectNode(id);setHierarchyView('tree');}}
                  t={t} />
                
            </div> :
              activeTab === 'hierarchy' ?
              <>
              <div className="node-header">
                <div className={`node-title ${isRoot ? 'falcon' : ''}`}>
                  {isRoot ?
                    <span className="node-avatar"><IcFalcon size={18} /></span> :

                    selectedNode.type === 'client' ?
                    <BrandLogo brand={selectedNode.brand} size={32} /> :
                    <span className="node-avatar" style={{ background: '#0d3f44', color: 'white' }}>
                          <span style={{ fontSize: 12, fontWeight: 700 }}>{selectedNode.name.slice(0, 1)}</span>
                        </span>
                    }
                  <span>{selectedNode.name}</span>
                </div>
                <div className="node-actions">
                  {infoOpen ?
                    <>
                      {infoEditing ?
                        <>
                          <button className="btn btn-secondary" onClick={() => { setInfoEditing(false); setInfoDraft(null); }}>
                            Cancel
                          </button>
                          <button className="btn btn-primary" onClick={() => { setInfoEditing(false); setInfoDraft(null); pushToast('Information updated ✓'); }}>
                            Save
                          </button>
                        </> :
                        <>
                          <button className="btn btn-secondary" onClick={() => setInfoOpen(false)}>
                            <IcArrowLeft size={15} stroke={1.8} className="flip-rtl" />
                            {t.backToUsers}
                          </button>
                          <button className="btn btn-primary" onClick={() => {
                            const base = NODE_INFO[selectedNode.id] || NODE_INFO[selectedNode.clientId] || {
                              accountName: selectedNode.name,
                              financeId: 'SAR-' + selectedNode.id.toUpperCase() + '-2025',
                              classification: selectedNode.type === 'client' ? 'Organization' : 'Sub-Node',
                              subClassification: '—',
                              entityName: selectedNode.name, authorityType: 'Organizational Unit',
                              sector: '—', budget: '—',
                              country: 'Kingdom Of Saudi Arabia', city: '—', district: '—', street: '—',
                              building: '—', postal: '—', addlAddr: '—', anotherId: '—', vat: '—'
                            };
                            setInfoDraft({ ...base });
                            setInfoEditing(true);
                          }}>
                            <IcEdit size={15} stroke={1.8} />
                            {t.editInfo}
                          </button>
                        </>
                      }
                    </> :

                    <>
                      {!isRoot &&
                      <a
                        href="#"
                        className={`info-link ${infoOpen ? 'active' : ''}`}
                        onClick={(e) => {e.preventDefault();setInfoOpen((v) => !v);}}>
                        
                          <IcInfo size={15} stroke={1.8} />
                          <span>{t.information}</span>
                        </a>
                      }
                      {isRoot ?
                      <button className="btn btn-secondary" onClick={() => setAddClientOpen(true)}>
                          <IcBuilding size={15} stroke={1.8} />
                          {t.addClient}
                        </button> :

                      <button className="btn btn-secondary" onClick={() => setDrawer({ mode: 'add', targetId: selectedNode.id })}>
                          <IcPlus size={15} stroke={2} />
                          {t.addNode}
                        </button>
                      }
                      <button className="btn btn-primary" onClick={() => setAddUserOpen(true)}>
                        <IcUserPlus size={15} stroke={1.8} />
                        Add User
                      </button>
                    </>
                    }
                </div>
              </div>

              {infoOpen ?
                <InfoPanel node={selectedNode} t={t} editing={infoEditing} draft={infoDraft} setDraft={setInfoDraft} /> :

                <div className="table-panel">
                <div className="table-head-bar">
                  <div className="table-head-title">
                    {t.users}
                  </div>
                  <div className="table-head-controls">
                    {isRoot &&
                      <>
                        <button className="filter-btn">
                          <IcFilter size={14} stroke={1.8} />
                          {t.filter}
                        </button>
                        <div className="search-input">
                          <IcSearch size={14} stroke={1.8} />
                          <input placeholder={t.searchHere} />
                        </div>
                      </>
                      }
                  </div>
                </div>
                <div className="table-scroll"><UsersTable
                    users={users.slice((userPage - 1) * userPageSize, userPage * userPageSize)}
                    selected={selectedUsers}
                    setSelected={setSelectedUsers}
                    sort={sort}
                    setSort={setSort}
                    rowMenuFor={rowMenuFor}
                    setRowMenuFor={setRowMenuFor}
                    onMoreDetails={(u) => setDetailUser(u)}
                    t={t} />
                </div>
                <TablePagination
                  total={users.length}
                  page={userPage}
                  pageSize={userPageSize}
                  onPageChange={setUserPage}
                  onPageSizeChange={(n) => { setUserPageSize(n); setUserPage(1); }}
                  t={t}
                />
              </div>
                }
            </> :
              activeTab === 'appsServices' || activeTab === 'commChannels' ?
              <div className="apps-tab-wrap">
              <div className="node-header simple" style={{ paddingTop: 3, paddingBottom: 3 }}>
                <div className={`node-title ${isRoot ? 'falcon' : ''}`}>
                  {isRoot ?
                    <span className="node-avatar"><IcFalcon size={18} /></span> :

                    selectedNode.type === 'client' ?
                    <BrandLogo brand={selectedNode.brand} size={32} /> :
                    <span className="node-avatar" style={{ background: '#0d3f44', color: 'white' }}>
                          <span style={{ fontSize: 12, fontWeight: 700 }}>{selectedNode.name.slice(0, 1)}</span>
                        </span>
                    }
                  <span>{selectedNode.name}</span>
                </div>
              </div>
              <ApplicationsPage tabKey={activeTab} t={t} pushToast={pushToast} nodeId={selectedNode.id} />
            </div> :

              activeTab === 'settings' ?
              <div className="apps-tab-wrap">
              <div className="node-header simple node-header-with-actions">
                <div className={`node-title ${isRoot ? 'falcon' : ''}`}>
                  {isRoot ?
                    <span className="node-avatar"><IcFalcon size={18} /></span> :

                    selectedNode.type === 'client' ?
                    <BrandLogo brand={selectedNode.brand} size={32} /> :
                    <span className="node-avatar" style={{ background: '#0d3f44', color: 'white' }}>
                          <span style={{ fontSize: 12, fontWeight: 700 }}>{selectedNode.name.slice(0, 1)}</span>
                        </span>
                    }
                  <span>{selectedNode.name}</span>
                </div>
                <div id="settings-actions-slot" className="node-header-actions"></div>
              </div>
              <SettingsTab node={selectedNode} t={t} pushToast={pushToast} isRoot={isRoot} />
            </div> :

              <div className="empty-state" style={{ padding: '80px 20px' }}>
              <p style={{ fontSize: 15, marginBottom: 6, color: 'var(--text)' }}>{tabs.find((tb) => tb.id === activeTab)?.label}</p>
              <p>Coming in v2 — this tab is stubbed for the v1 scope (Hierarchy only).</p>
            </div>
              }
        </div>
        </>
          }
      </div>
    </div>
    </>);

};

window.HierarchyPage = HierarchyPage;
window.StatusBadge = StatusBadge;
window.TablePagination = TablePagination;