// Shared admin controls with portaled menus, RTL and keyboard support.

function AdminControlsStyles() {
  return <style>{`
    .admin-select-trigger {
      width:100%; min-width:0; min-height:44px; display:flex; align-items:center;
      justify-content:space-between; gap:12px; padding:10px 12px;
      border:1px solid #44372d; border-radius:10px; background:#201811;
      color:#fff4e2; font-size:13px; line-height:1.5; text-align:start;
      transition:border-color .16s ease,background .16s ease,box-shadow .16s ease;
    }
    .admin-select-trigger:hover:not(:disabled) { background:#2a2018; border-color:#75604c; }
    .admin-select-trigger:focus-visible,.admin-select-trigger[data-open="true"] {
      outline:none; border-color:var(--brand); box-shadow:0 0 0 3px rgba(217,70,30,.2);
    }
    .admin-select-value { display:flex; align-items:center; gap:9px; min-width:0; }
    .admin-select-value>span:last-child { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .admin-select-dot { width:7px; height:7px; flex:none; border-radius:50%; background:var(--status-color); }
    .admin-select-chevron { flex:none; width:16px; height:16px; color:#c8b8a7; transition:transform .16s ease; }
    .admin-select-trigger[data-open="true"] .admin-select-chevron { transform:rotate(180deg); }
    .admin-select-menu {
      position:fixed; z-index:200; overflow-y:auto; overscroll-behavior:contain;
      padding:5px; border:1px solid #514033; border-radius:12px;
      background:#211912; color:#fff4e2; box-shadow:0 12px 38px rgba(0,0,0,.48);
      font-family:var(--fa); font-size:13px; line-height:1.5;
      animation:adminSelectIn .12s ease-out;
    }
    .admin-select-menu[dir="ltr"] { font-family:var(--en); }
    .admin-select-option {
      display:flex; align-items:center; justify-content:space-between; gap:12px;
      width:100%; min-height:44px; padding:9px 10px; border-radius:7px;
      color:inherit; font-size:inherit; text-align:start;
    }
    .admin-select-option[data-active="true"] { background:#3a2b20; }
    .admin-select-option[aria-selected="true"] { color:#fff; font-weight:700; }
    .admin-select-check { width:16px; height:16px; flex:none; color:var(--gold); }
    .admin-switch {
      width:48px; height:44px; min-width:48px; min-height:44px; flex:none;
      display:inline-flex; align-items:center; justify-content:center; padding:0;
      background:transparent; border:0; border-radius:10px; vertical-align:middle;
    }
    .admin-switch-track {
      position:relative; display:block; width:44px; height:24px; flex:none;
      border-radius:999px; background:#564739; box-shadow:inset 0 0 0 1px rgba(255,244,226,.14);
      transition:background .18s ease;
    }
    .admin-switch[aria-checked="true"] .admin-switch-track { background:var(--switch-color); }
    .admin-switch-thumb {
      position:absolute; top:3px; inset-inline-start:3px; width:18px; height:18px;
      border-radius:50%; background:#fff; box-shadow:0 1px 4px rgba(0,0,0,.3);
      transition:inset-inline-start .18s ease;
    }
    .admin-switch[aria-checked="true"] .admin-switch-thumb { inset-inline-start:23px; }
    .admin-switch:hover .admin-switch-track { box-shadow:0 0 0 3px rgba(255,244,226,.08); }
    .admin-switch:focus-visible { outline:2px solid var(--gold); outline-offset:2px; }
    @keyframes adminSelectIn { from { opacity:0; transform:translateY(-3px); } to { opacity:1; transform:translateY(0); } }
    @media(prefers-reduced-motion:reduce) {
      .admin-select-menu { animation:none; }
      .admin-select-trigger,.admin-select-chevron,.admin-switch-track,.admin-switch-thumb { transition:none; }
    }
  `}</style>;
}

function AdminSelect({ value, onValueChange, options, label, disabled = false, style }) {
  const { lang } = useLang();
  const listId = React.useId();
  const triggerRef = useRef(null);
  const menuRef = useRef(null);
  const typeahead = useRef({ text: "", time: 0 });
  const [open, setOpen] = useState(false);
  const [active, setActive] = useState(0);
  const [position, setPosition] = useState(null);
  const selectedIndex = options.findIndex(option => option.value === value);
  const selected = options[selectedIndex];

  const close = (restoreFocus = false) => {
    setOpen(false);
    if (restoreFocus) triggerRef.current?.focus({ preventScroll: true });
  };
  const choose = index => {
    const option = options[index];
    if (!option || option.disabled) return;
    onValueChange(option.value);
    close(true);
  };
  const openMenu = index => {
    if (disabled || !options.length) return;
    setActive(index ?? Math.max(0, selectedIndex));
    setOpen(true);
  };

  React.useLayoutEffect(() => {
    if (!open) return;
    const update = event => {
      if (event && menuRef.current?.contains(event.target)) return;
      const rect = triggerRef.current?.getBoundingClientRect();
      if (!rect) return;
      const width = Math.min(Math.max(rect.width, 180), window.innerWidth - 16);
      const below = window.innerHeight - rect.bottom - 16;
      const above = rect.top - 16;
      const height = Math.min(options.length * 44 + 12, 280);
      const flip = below < height && above > below;
      const maxHeight = Math.max(44, Math.min(height, flip ? above : below));
      const left = lang === "fa" ? rect.right - width : rect.left;
      setPosition({
        width, maxHeight,
        left: Math.max(8, Math.min(left, window.innerWidth - width - 8)),
        top: flip ? Math.max(8, rect.top - maxHeight - 6) : rect.bottom + 6,
      });
    };
    const outside = event => {
      if (!triggerRef.current?.contains(event.target) && !menuRef.current?.contains(event.target)) setOpen(false);
    };
    update();
    window.addEventListener("resize", update);
    document.addEventListener("scroll", update, true);
    document.addEventListener("pointerdown", outside, true);
    return () => {
      window.removeEventListener("resize", update);
      document.removeEventListener("scroll", update, true);
      document.removeEventListener("pointerdown", outside, true);
    };
  }, [open, lang, options.length]);

  React.useLayoutEffect(() => {
    if (!open || !menuRef.current) return;
    const option = menuRef.current.children[active];
    if (!option) return;
    const menu = menuRef.current;
    if (option.offsetTop < menu.scrollTop) menu.scrollTop = option.offsetTop;
    if (option.offsetTop + option.offsetHeight > menu.scrollTop + menu.clientHeight) {
      menu.scrollTop = option.offsetTop + option.offsetHeight - menu.clientHeight;
    }
  }, [open, active]);

  const onKeyDown = event => {
    if (event.key === "Tab") { close(); return; }
    if (event.key === "Escape" && open) {
      event.preventDefault(); event.stopPropagation(); close(true); return;
    }
    if (["Enter", " "].includes(event.key)) {
      event.preventDefault();
      open ? choose(active) : openMenu();
      return;
    }
    if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
      event.preventDefault();
      if (!open) { openMenu(event.key === "End" ? options.length - 1 : Math.max(0, selectedIndex)); return; }
      const delta = event.key === "ArrowUp" ? -1 : 1;
      setActive(index => event.key === "Home" ? 0 : event.key === "End" ? options.length - 1 : (index + delta + options.length) % options.length);
      return;
    }
    if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
      const time = Date.now();
      const previous = typeahead.current;
      const text = (time - previous.time < 700 ? previous.text : "") + event.key.toLowerCase();
      typeahead.current = { text, time };
      const match = options.findIndex(option => option.label.toLowerCase().startsWith(text));
      if (match >= 0) {
        event.preventDefault();
        open ? setActive(match) : onValueChange(options[match].value);
      }
    }
  };

  return <>
    <button ref={triggerRef} type="button" role="combobox" className="admin-select-trigger"
      dir={lang === "fa" ? "rtl" : "ltr"} disabled={disabled || !options.length} style={style}
      aria-label={label} aria-haspopup="listbox" aria-expanded={open}
      aria-controls={open ? listId : undefined}
      aria-activedescendant={open ? `${listId}-${active}` : undefined}
      data-open={open} onKeyDown={onKeyDown}
      onBlur={() => setOpen(false)}
      onClick={() => open ? close() : openMenu()}>
      <span className="admin-select-value">
        {selected?.color && <span className="admin-select-dot" aria-hidden="true" style={{ "--status-color": selected.color }} />}
        <span>{selected?.label || (lang === "fa" ? "انتخاب کنید" : "Select an option")}</span>
      </span>
      <svg className="admin-select-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" aria-hidden="true"><path d="m6 9 6 6 6-6" /></svg>
    </button>
    {open && ReactDOM.createPortal(
      <div ref={menuRef} id={listId} role="listbox" aria-label={label} className="admin-select-menu"
        dir={lang === "fa" ? "rtl" : "ltr"}
        style={{ ...position, visibility: position ? "visible" : "hidden" }}
        onKeyDown={onKeyDown}>
        {options.map((option, index) => <button key={option.value} id={`${listId}-${index}`}
          type="button" role="option" tabIndex={-1} aria-selected={option.value === value}
          disabled={option.disabled} className="admin-select-option" data-active={index === active}
          onPointerMove={() => setActive(index)}
          onMouseDown={event => event.preventDefault()} onClick={() => choose(index)}>
          <span className="admin-select-value">
            {option.color && <span className="admin-select-dot" aria-hidden="true" style={{ "--status-color": option.color }} />}
            <span>{option.label}</span>
          </span>
          {option.value === value && <svg className="admin-select-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true"><path d="m5 12 4 4 10-10" /></svg>}
        </button>)}
      </div>, document.body
    )}
  </>;
}

Object.assign(window, { AdminSelect, AdminControlsStyles });
