/* ============================================================================
 * 서명전에 — TDS Menu 컴포넌트 (드롭다운)
 *  · 6 개 서브:
 *      Menu.Dropdown          : 드롭다운 패널 (자식들을 감싸는 컨테이너)
 *      Menu.Header            : 패널 안 작은 라벨
 *      Menu.DropdownItem      : left / right 슬롯이 있는 메뉴 항목
 *      Menu.DropdownIcon      : 슬롯에 들어가는 아이콘 헬퍼 (URL or IOSIcon)
 *      Menu.DropdownCheckItem : DropdownItem + 자동 체크박스
 *      Menu.Trigger           : 자식을 감싸 클릭하면 드롭다운을 띄워 줘요.
 *
 *  · MenuContext 로 DropdownItem 의 onClick 후 자동 close. CheckItem 은 닫지 않음
 *    (스펙대로 — 다중 선택을 위해).
 *  · Trigger 는 controlled (open + onOpenChange) / uncontrolled (defaultOpen).
 *  · 외부 클릭 + ESC 로 닫혀요. document mousedown / keydown 리스너.
 *  · placement 12 종 — CSS 에서 absolute 위치를 결정.
 *  · 패널만 standalone 으로도 쓸 수 있어요 (예: 직접 위치 잡고 싶을 때).
 * ========================================================================== */

const __MENU_PLACEMENTS = {
  "top-start": 1, "top-center": 1, "top-end": 1,
  "bottom-start": 1, "bottom-center": 1, "bottom-end": 1,
  "left-start": 1, "left-center": 1, "left-end": 1,
  "right-start": 1, "right-center": 1, "right-end": 1,
};

// MenuContext: DropdownItem 의 자동 close 를 위해 close 핸들러를 내려보내요.
const __MenuContext = React.createContext({ close: null });

// ---------- Dropdown (panel) ----------
function MenuDropdown({ children, className = "", style, id, ...rest }) {
  const cls = ["tds-menu-dropdown", className].filter(Boolean).join(" ");
  return (
    <div
      id={id}
      className={cls}
      style={style}
      role="menu"
      {...rest}
    >
      {children}
    </div>
  );
}

// ---------- Header ----------
function MenuHeader({ children, className = "", style, ...rest }) {
  const cls = ["tds-menu-dropdown__header", className].filter(Boolean).join(" ");
  return (
    <div className={cls} style={style} role="presentation" {...rest}>
      {children}
    </div>
  );
}

// ---------- DropdownItem ----------
function MenuDropdownItem({
  children,
  left,
  right,
  onClick,
  disabled = false,
  className = "",
  style,
  closeOnClick = true,   // 내부 옵션 — DropdownCheckItem 에서 false 로 넘김
  ...rest
}) {
  const ctx = React.useContext(__MenuContext);

  const handleClick = function (e) {
    if (disabled) return;
    if (typeof onClick === "function") onClick(e);
    if (closeOnClick && ctx && typeof ctx.close === "function") ctx.close();
  };

  const cls = ["tds-menu-dropdown__item", className].filter(Boolean).join(" ");
  return (
    <button
      type="button"
      className={cls}
      style={style}
      onClick={handleClick}
      disabled={disabled}
      role="menuitem"
      {...rest}
    >
      {left != null && (
        <span className="tds-menu-dropdown__item-left">{left}</span>
      )}
      <span className="tds-menu-dropdown__item-label">{children}</span>
      {right != null && (
        <span className="tds-menu-dropdown__item-right">{right}</span>
      )}
    </button>
  );
}

// ---------- DropdownIcon ----------
// 슬롯에 들어가는 아이콘 헬퍼.
//  · name 이 URL/경로면 <img> 로 렌더 (mono 면 mask 트릭으로 currentColor 칠하기)
//  · 그 외엔 IOSIcon 으로 위임 (있을 때만)
function MenuDropdownIcon({ name, mono, size, className = "", style, ...rest }) {
  if (!name) return null;

  const isUrl =
    /^(https?:|\/|\.{1,2}\/)/i.test(name) ||
    /\.(svg|png|jpe?g|gif|webp)(?:\?|#|$)/i.test(name);

  // mono 추론: 파일명에 -mono 들어 있으면 자동 mono 로 봐요.
  const inferredMono =
    typeof mono === "boolean"
      ? mono
      : isUrl && /-mono(?:\.[^/?#]+)?(?:\?[^#]*)?(?:#.*)?$/i.test(name);

  const cls = [
    "tds-menu-dropdown__icon",
    inferredMono ? "tds-menu-dropdown__icon--mono" : "",
    className,
  ].filter(Boolean).join(" ");

  const px = typeof size === "number" ? `${size}px` : (size || undefined);
  const mergedStyle = px ? Object.assign({ width: px, height: px }, style) : style;

  if (isUrl) {
    if (inferredMono) {
      // mask + currentColor 트릭
      const maskStyle = Object.assign(
        {
          WebkitMaskImage: `url("${name}")`,
          maskImage: `url("${name}")`,
        },
        mergedStyle
      );
      return (
        <span className={cls} style={maskStyle} aria-hidden="true" {...rest}>
          {/* 접근성 text 이미지 흔적 — 시각적으론 안보이게 */}
          <img src={name} alt="" />
        </span>
      );
    }
    return (
      <span className={cls} style={mergedStyle} aria-hidden="true" {...rest}>
        <img src={name} alt="" />
      </span>
    );
  }

  // IOSIcon 위임
  if (window.IOSIcon) {
    return (
      <span className={cls} style={mergedStyle} aria-hidden="true" {...rest}>
        <window.IOSIcon name={name} size={typeof size === "number" ? size : 20} />
      </span>
    );
  }

  // 폴백 — 빈 박스
  return <span className={cls} style={mergedStyle} aria-hidden="true" {...rest} />;
}

// ---------- DropdownCheckItem ----------
function MenuDropdownCheckItem({
  children,
  left,
  checked = false,
  onCheckedChange,
  onClick,
  disabled = false,
  className = "",
  style,
  ...rest
}) {
  const handleClick = function (e) {
    if (disabled) return;
    if (typeof onClick === "function") onClick(e);
    if (typeof onCheckedChange === "function") onCheckedChange(!checked);
  };

  // checked 시 클래스 토글로 시각 상태 전환
  const cls = [
    checked ? "tds-menu-dropdown__item--checked" : "",
    className,
  ].filter(Boolean).join(" ");

  // 우측 슬롯에 체크박스 자동 삽입
  const checkbox = (
    <span className="tds-menu-dropdown__check" aria-hidden="true">
      <svg viewBox="0 0 14 14" fill="none">
        <path
          d="M2.5 7.5l3 3 6-6.5"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
        />
      </svg>
    </span>
  );

  return (
    <MenuDropdownItem
      left={left}
      right={checkbox}
      onClick={handleClick}
      disabled={disabled}
      className={cls}
      style={style}
      closeOnClick={false}
      role="menuitemcheckbox"
      aria-checked={checked ? "true" : "false"}
      {...rest}
    >
      {children}
    </MenuDropdownItem>
  );
}

// ---------- Trigger (controlled / uncontrolled wrapper) ----------
function MenuTrigger({
  children,
  dropdown,
  placement = "bottom-start",
  open,                    // controlled
  defaultOpen = false,     // uncontrolled
  onOpenChange,
  closeOnOutsideClick = true,
  closeOnEscape = true,
  className = "",
  style,
  id,
  ...rest
}) {
  const isControlled = typeof open === "boolean";
  const [internalOpen, setInternalOpen] = React.useState(!!defaultOpen);
  const isOpen = isControlled ? open : internalOpen;

  // placement 검증
  if (!__MENU_PLACEMENTS[placement]) {
    if (window.console && console.warn) {
      console.warn(
        `[Menu.Trigger] \`placement\` 가 잘못됐어요: "${placement}". ` +
          `top/bottom/left/right × start/center/end 조합만 가능해요.`
      );
    }
  }
  const safePlacement = __MENU_PLACEMENTS[placement] ? placement : "bottom-start";

  const setOpen = function (next) {
    if (typeof onOpenChange === "function") onOpenChange(next);
    if (!isControlled) setInternalOpen(next);
  };

  const close = React.useCallback(function () { setOpen(false); }, [isControlled, onOpenChange]);
  const toggle = function () { setOpen(!isOpen); };

  const rootRef = React.useRef(null);

  // 외부 클릭 감지 — 패널/트리거 밖 클릭이면 close
  React.useEffect(function () {
    if (!isOpen || !closeOnOutsideClick) return undefined;
    const onDocDown = function (e) {
      const root = rootRef.current;
      if (!root) return;
      if (root.contains(e.target)) return; // 안쪽 클릭이면 무시
      close();
    };
    document.addEventListener("mousedown", onDocDown);
    document.addEventListener("touchstart", onDocDown, { passive: true });
    return function () {
      document.removeEventListener("mousedown", onDocDown);
      document.removeEventListener("touchstart", onDocDown);
    };
  }, [isOpen, closeOnOutsideClick, close]);

  // ESC 닫기
  React.useEffect(function () {
    if (!isOpen || !closeOnEscape) return undefined;
    const onKey = function (e) {
      if (e.key === "Escape" || e.key === "Esc") {
        e.stopPropagation();
        close();
      }
    };
    document.addEventListener("keydown", onKey);
    return function () { document.removeEventListener("keydown", onKey); };
  }, [isOpen, closeOnEscape, close]);

  // children (트리거)에 onClick wrap — 기존 onClick 도 호출
  let triggerChild = children;
  if (React.isValidElement(children)) {
    const childOnClick = children.props.onClick;
    triggerChild = React.cloneElement(children, {
      onClick: function (e) {
        if (typeof childOnClick === "function") childOnClick(e);
        if (e && e.defaultPrevented) return;
        toggle();
      },
      "aria-haspopup": "menu",
      "aria-expanded": isOpen ? "true" : "false",
    });
  }

  const cls = ["tds-menu-trigger", className].filter(Boolean).join(" ");

  return (
    <__MenuContext.Provider value={{ close }}>
      <span
        ref={rootRef}
        id={id}
        className={cls}
        style={style}
        {...rest}
      >
        {triggerChild}
        {isOpen && (
          <div
            className={`tds-menu-trigger__dropdown tds-menu-trigger__dropdown--${safePlacement}`}
          >
            {dropdown}
          </div>
        )}
      </span>
    </__MenuContext.Provider>
  );
}

// ---------- Menu namespace (서브들 부착) ----------
const Menu = {
  Dropdown: MenuDropdown,
  Header: MenuHeader,
  DropdownItem: MenuDropdownItem,
  DropdownIcon: MenuDropdownIcon,
  DropdownCheckItem: MenuDropdownCheckItem,
  Trigger: MenuTrigger,
};

window.Menu = Menu;
window.MenuDropdown = MenuDropdown;
window.MenuHeader = MenuHeader;
window.MenuDropdownItem = MenuDropdownItem;
window.MenuDropdownIcon = MenuDropdownIcon;
window.MenuDropdownCheckItem = MenuDropdownCheckItem;
window.MenuTrigger = MenuTrigger;

Object.assign(window, {
  Menu,
  MenuDropdown,
  MenuHeader,
  MenuDropdownItem,
  MenuDropdownIcon,
  MenuDropdownCheckItem,
  MenuTrigger,
});
