/**
 * Session Persistence
 *
 * pjax遷移をまたいでウィジェットの状態を永続化する。
 * sessionStorage に会話履歴・展開状態・モードを保存し、
 * ページ遷移後に復元する。
 *
 * 設計:
 * - sessionStorage を使用（タブ単位、ブラウザ閉じで消滅）
 * - 保存タイミング: beforeunload / pagehide (+ AI 主導遷移時の明示保存)
 * - 復元条件: 最終保存から「復元有効期間」設定 (既定 30 分) 以内
 */

const STORAGE_KEY = "agent_widget_session";
// 0.3.0-dev.47: 復元 TTL・保存上限は __AGENT_CONFIG__.session (管理画面の
// 「会話を復元」「復元有効期間」「保存する最大メッセージ数」) から取る。
// 従来は 30 秒 / 20 件のハードコードで設定が無視されており、AI 主導の
// ページ遷移後にウィジェットを開き直すのが 30 秒を超えると履歴が消えていた。
// 以下は config が読めない場合のフォールバック (設定既定値と同じ 30 分 / 30 件)。
const DEFAULT_RESTORE_AGE_MS = 30 * 60_000;
const DEFAULT_MAX_PERSISTED_MESSAGES = 30;

function sessionCfg() {
  const cfg =
    (typeof window !== "undefined" &&
      window.__AGENT_CONFIG__ &&
      window.__AGENT_CONFIG__.session) ||
    {};
  const ttlMin = Number(cfg.ttl_minutes);
  const maxMsgs = Number(cfg.max_messages);
  return {
    enabled: cfg.enabled !== false,
    ttlMs: Number.isFinite(ttlMin) && ttlMin > 0 ? ttlMin * 60_000 : DEFAULT_RESTORE_AGE_MS,
    maxMessages: Number.isFinite(maxMsgs) && maxMsgs > 0 ? maxMsgs : DEFAULT_MAX_PERSISTED_MESSAGES,
  };
}

/**
 * セッション状態の型
 * @typedef {object} WidgetSession
 * @property {Array} messages - 会話履歴
 * @property {string} mode - "text" | "realtime"
 * @property {boolean} isExpanded - ウィジェット展開状態
 * @property {object|null} pageContext - 最後のページコンテキスト
 * @property {number} savedAt - 保存タイムスタンプ (ms)
 */

/**
 * セッション状態を保存
 *
 * @param {WidgetSession} session - 保存するセッション状態
 */
export function saveSession(session) {
  try {
    const { enabled, maxMessages } = sessionCfg();
    if (!enabled) return;

    // メッセージ数を制限して sessionStorage 容量超過を防止
    const allMessages = session.messages || [];
    const limitedMessages = allMessages.length > maxMessages
      ? allMessages.slice(-maxMessages)
      : allMessages;

    const data = {
      messages: limitedMessages,
      mode: session.mode || "text",
      isExpanded: session.isExpanded ?? true,
      pageContext: session.pageContext || null,
      savedAt: Date.now(),
    };

    sessionStorage.setItem(STORAGE_KEY, JSON.stringify(data));
  } catch (e) {
    console.warn("[SessionPersistence] Save failed:", e.message);
  }
}

/**
 * セッション状態を復元
 * 最終保存から MAX_RESTORE_AGE_MS 以内のみ有効。
 *
 * @returns {WidgetSession|null} 復元されたセッション or null
 */
export function restoreSession() {
  try {
    const { enabled, ttlMs } = sessionCfg();
    if (!enabled) return null;

    const raw = sessionStorage.getItem(STORAGE_KEY);
    if (!raw) return null;

    const data = JSON.parse(raw);

    // 古すぎるセッションは破棄
    if (Date.now() - data.savedAt > ttlMs) {
      clearSession();
      return null;
    }

    return data;
  } catch (e) {
    console.warn("[SessionPersistence] Restore failed:", e.message);
    return null;
  }
}

/**
 * セッション状態をクリア
 */
export function clearSession() {
  try {
    sessionStorage.removeItem(STORAGE_KEY);
  } catch {
    // ignore
  }
}

/**
 * beforeunload / pagehide リスナーを登録
 * pjax遷移時にセッションを自動保存する。
 *
 * @param {Function} getSessionState - 現在のセッション状態を取得する関数
 * @returns {Function} クリーンアップ関数（リスナー解除）
 */
export function registerPersistenceListeners(getSessionState) {
  const handler = () => {
    const state = getSessionState();
    if (state) {
      saveSession(state);
    }
  };

  window.addEventListener("pagehide", handler);
  window.addEventListener("beforeunload", handler);

  // クリーンアップ関数を返す
  return () => {
    window.removeEventListener("pagehide", handler);
    window.removeEventListener("beforeunload", handler);
  };
}
