/* Memo: この script は defer をつけて読み込んでいる （DOMパース後に読み込まれます） */

/**
 * モーダル処理
 */
setNavigationModal();

/**
 * 要素がアニメーション中の場合、完了まで待機する
 */
async function waitAnimation(el) {
  const animations = el.getAnimations();
  if (animations.length > 0) {
    // allSettled を使うことで、キャンセルされた場合もrejectせずに完了扱いになる
    await Promise.allSettled(animations.map((a) => a.finished));
  }
}

/**
 * ナビゲーションメニューの開閉処理
 */
function setNavigationModal() {
  // ナビゲーションメニュー関連の要素を取得
  const openBtn = document.getElementById("menu-open-btn");
  const closeBtn = document.getElementById("menu-close-btn");
  const dialog = document.getElementById("nav-dialog");

  // いずれかがなければ何もしない
  if (!openBtn || !closeBtn || !dialog) return;

  /**
   * ダイアログを開く処理
   *   Point: showModal() してから、CSSアニメーション用の data-open属性を付与する
   */
  const openDialog = () => {
    // すでに open & data-open が付いていれば何もしない（連打防止）
    if (dialog.open && dialog.hasAttribute("data-open")) return;

    // showModal() でモーダルを開く（ open 属性の付与）
    dialog.showModal();

    // 次フレームで data-open を付与（CSS側でフェードインアニメーション開始）
    requestAnimationFrame(() => {
      dialog.dataset.open = "1";
    });
  };

  /**
   * ダイアログを閉じる処理
   *   Point: data-open属性を削除してCSSアニメーションが終わってから、close() を実行する
   */
  const closeDialog = async () => {
    // すでに閉じている場合は何もしない
    if (!dialog.hasAttribute("data-open")) {
      return;
    }

    // data-open 属性を削除（CSS側でフェードアウトアニメーション開始）
    delete dialog.dataset.open;

    // アニメーション完了を待機（子要素も取得する場合は { subtree: true } を指定）
    await waitAnimation(dialog);

    // アニメーション終了後、dialog を閉じる（open属性の削除）
    dialog.close();
  };

  // メニューを開く処理をボタンに登録
  openBtn.addEventListener("click", openDialog);

  // メニューを閉じる処理をボタンに登録
  closeBtn.addEventListener("click", closeDialog);

  // ナビクリック・キーボード選択時にダイアログを閉じる
  // Enterキー押下時も自動的にclickイベントが発火するため、clickイベントだけで処理
  dialog.querySelectorAll("a").forEach((link) => {
    link.addEventListener("click", closeDialog);
  });

  // 余白クリックで閉じる
  dialog.addEventListener("click", (e) => {
    // dialog自体、またはnav-dialog__bodyの空白部分をクリックした場合に閉じる
    if (
      e.target === dialog ||
      e.target.classList.contains("nav-dialog__body")
    ) {
      closeDialog();
    }
  });

  /**
   * ESCキーで閉じた時もアニメーションを実行する処理
   */
  dialog.addEventListener("cancel", (e) => {
    e.preventDefault(); // デフォルトの即時 close() を防ぐ
    closeDialog(); // 自分で用意したクローズ処理
  });
}
