/**
 * 本頁說明（不進正文）
 *
 * 入口放在 PageHeader 標題旁（視線落在「這頁」時就找得到），
 * 不佔頂欄工具列。說明本體用 portal 抽屜，避免 sticky header 裁切 fixed。
 * 快捷鍵「?」仍可用。
 */
import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useId,
  useMemo,
  useRef,
  useState,
  type ReactNode,
} from "react";
import { createPortal } from "react-dom";
import { Link, useLocation } from "react-router-dom";
import { AppIcon } from "../ui/AppIcons";
import { useI18n } from "../../i18n/I18nContext";
import {
  PAGE_HELP_RELATED,
  pageHelpKeys,
  resolvePageHelpId,
  type PageHelpId,
} from "../../lib/pageHelp";

type PageHelpContextValue = {
  open: () => void;
  close: () => void;
  toggle: () => void;
  isOpen: boolean;
  helpId: PageHelpId;
};

const PageHelpContext = createContext<PageHelpContextValue | null>(null);

function isTypingTarget(el: EventTarget | null): boolean {
  if (!(el instanceof HTMLElement)) return false;
  const tag = el.tagName;
  if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
  if (el.isContentEditable) return true;
  return Boolean(el.closest("[contenteditable='true']"));
}

export function usePageHelp(): PageHelpContextValue {
  const ctx = useContext(PageHelpContext);
  if (!ctx) {
    throw new Error("usePageHelp must be used within PageHelpProvider");
  }
  return ctx;
}

/** 可選：在沒有 Provider 的測試裡不炸 */
export function usePageHelpOptional(): PageHelpContextValue | null {
  return useContext(PageHelpContext);
}

export function PageHelpProvider({ children }: { children: ReactNode }) {
  const { pathname } = useLocation();
  const [isOpen, setOpen] = useState(false);
  const titleId = useId();
  const panelId = useId();
  const helpId = resolvePageHelpId(pathname);

  const open = useCallback(() => setOpen(true), []);
  const close = useCallback(() => setOpen(false), []);
  const toggle = useCallback(() => setOpen((v) => !v), []);

  useEffect(() => {
    setOpen(false);
  }, [pathname]);

  useEffect(() => {
    if (!isOpen) return;
    function onKey(e: KeyboardEvent) {
      if (e.key === "Escape") {
        e.preventDefault();
        close();
      }
    }
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [isOpen, close]);

  useEffect(() => {
    function onKey(e: KeyboardEvent) {
      if (e.key !== "?" && !(e.shiftKey && e.key === "/")) return;
      if (isTypingTarget(e.target)) return;
      if (e.metaKey || e.ctrlKey || e.altKey) return;
      e.preventDefault();
      setOpen((v) => !v);
    }
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, []);

  useEffect(() => {
    if (!isOpen) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.body.style.overflow = prev;
    };
  }, [isOpen]);

  const value = useMemo(
    () => ({ open, close, toggle, isOpen, helpId }),
    [open, close, toggle, isOpen, helpId],
  );

  const portal =
    typeof document !== "undefined" && isOpen
      ? createPortal(
          <PageHelpDrawer
            helpId={helpId}
            titleId={titleId}
            panelId={panelId}
            onClose={close}
          />,
          document.body,
        )
      : null;

  return (
    <PageHelpContext.Provider value={value}>
      {children}
      {portal}
    </PageHelpContext.Provider>
  );
}

/**
 * 標題旁的說明入口：小圓標「?」，不塞教學文字。
 * 沒有 Provider 時不渲染（例如公開頁）。
 */
export function PageHelpTrigger({ className = "" }: { className?: string }) {
  const ctx = usePageHelpOptional();
  const { t } = useI18n();
  if (!ctx) return null;

  return (
    <button
      type="button"
      className={`hb-page-help-trigger ${className}`.trim()}
      onClick={ctx.toggle}
      aria-label={t("help.open")}
      aria-expanded={ctx.isOpen}
      aria-haspopup="dialog"
      title={`${t("help.open")} (? )`}
    >
      <AppIcon name="help" size={18} />
    </button>
  );
}

/** @deprecated 頂欄入口已移除；保留名稱以免外部誤用，等同 Trigger */
export function PageHelpButton() {
  return <PageHelpTrigger />;
}

function PageHelpDrawer({
  helpId,
  titleId,
  panelId,
  onClose,
}: {
  helpId: PageHelpId;
  titleId: string;
  panelId: string;
  onClose: () => void;
}) {
  const { t } = useI18n();
  const keys = pageHelpKeys(helpId);
  const related = PAGE_HELP_RELATED[helpId] ?? [];
  const closeRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    closeRef.current?.focus();
  }, []);

  const steps = keys.steps
    .map((k) => t(k))
    .filter((s) => s && !s.startsWith("help.page."));

  return (
    <div className="hb-page-help" role="presentation">
      <button
        type="button"
        className="hb-page-help__scrim"
        aria-label={t("common.cancel")}
        onClick={onClose}
      />
      <aside
        id={panelId}
        className="hb-page-help__panel"
        role="dialog"
        aria-modal="true"
        aria-labelledby={titleId}
      >
        <header className="hb-page-help__head">
          <div>
            <p className="hb-page-help__kicker">{t("help.kicker")}</p>
            <h2 id={titleId} className="hb-page-help__title">
              {t(keys.title)}
            </h2>
          </div>
          <button
            ref={closeRef}
            type="button"
            className="hb-btn hb-btn--ghost"
            onClick={onClose}
          >
            {t("common.close")}
          </button>
        </header>

        <div className="hb-page-help__body">
          <section className="hb-page-help__section">
            <h3 className="hb-page-help__section-title">{t("help.section.what")}</h3>
            <p className="hb-page-help__text">{t(keys.what)}</p>
          </section>

          {steps.length > 0 ? (
            <section className="hb-page-help__section">
              <h3 className="hb-page-help__section-title">{t("help.section.how")}</h3>
              <ol className="hb-page-help__steps">
                {steps.map((s, i) => (
                  <li key={`${i}-${s.slice(0, 24)}`}>{s}</li>
                ))}
              </ol>
            </section>
          ) : null}

          <section className="hb-page-help__section">
            <h3 className="hb-page-help__section-title">{t("help.section.tips")}</h3>
            <p className="hb-page-help__text">{t(keys.tips)}</p>
          </section>

          {related.length > 0 ? (
            <section className="hb-page-help__section">
              <h3 className="hb-page-help__section-title">{t("help.section.related")}</h3>
              <ul className="hb-page-help__related">
                {related.map((r) => (
                  <li key={r.path}>
                    <Link className="hb-page-help__link" to={r.path} onClick={onClose}>
                      {t(r.labelKey)}
                    </Link>
                  </li>
                ))}
              </ul>
            </section>
          ) : null}
        </div>

        <footer className="hb-page-help__foot">
          <p className="hb-page-help__hint">{t("help.shortcutHint")}</p>
        </footer>
      </aside>
    </div>
  );
}
