/**
 * OpenAI Realtime API レスポンスエラー分類モジュール
 *
 * response.done イベントで status === "failed" が返された場合の
 * error.type に基づくエラー分類とユーザー向けメッセージの生成を行う。
 *
 * 分類は以下の4カテゴリ:
 *   - user_error:        ユーザー（設定）起因のエラー
 *   - rate_limit:        利用制限（時間経過で回復）
 *   - quota_exhausted:   クォータ枯渇（課金切れ等、時間経過では回復しない）
 *   - server_error:      OpenAI側の障害・接続問題
 */

import { t } from "../ns/ns-rest.js";

// ---------------------------------------------------------------------------
// エラーカテゴリ定義
// ---------------------------------------------------------------------------

/**
 * エラーカテゴリの定数
 * @readonly
 * @enum {string}
 */
export const ERROR_CATEGORIES = Object.freeze({
    USER_ERROR: "user_error",
    RATE_LIMIT: "rate_limit",
    QUOTA_EXHAUSTED: "quota_exhausted",
    SERVER_ERROR: "server_error",
});

/**
 * カテゴリごとのユーザー向けメッセージ
 *
 * INV-12: 文言は §4.4 の window.__NS_I18N__ 辞書から引き、ソース上のリテラルは
 * 英語フォールバックのみ。凍結済み定数ではなく関数にしてあるのは、辞書の解決を
 * 呼び出し時点まで遅らせ、module 評価順に依存しないようにするため。
 *
 * @returns {Record<string, string>}
 */
function categoryMessages() {
    return {
        [ERROR_CATEGORIES.USER_ERROR]:
            t("err_ai_user_error", "⚠️ There is a configuration problem. Please contact the administrator."),
        [ERROR_CATEGORIES.RATE_LIMIT]:
            t("err_ai_rate_limit", "⚠️ The AI service is temporarily rate limited. Please wait a moment for recovery."),
        [ERROR_CATEGORIES.QUOTA_EXHAUSTED]:
            t("err_ai_quota_exhausted", "⚠️ This service is currently unavailable. Please contact the administrator."),
        [ERROR_CATEGORIES.SERVER_ERROR]:
            t("err_ai_server_error", "⚠️ The AI service is experiencing a temporary problem. Please wait a moment."),
    };
}

/**
 * デフォルト（未分類）のユーザー向けメッセージ
 * @returns {string}
 */
function defaultMessage() {
    return t("err_ai_unknown", "⚠️ An unexpected error occurred in the AI service. Please wait a moment.");
}

// ---------------------------------------------------------------------------
// error.type → カテゴリ マッピング
// ---------------------------------------------------------------------------

/**
 * OpenAI Realtime API の error.type をカテゴリに分類するマッピング。
 * 新しい error.type が追加された場合はここにエントリを追加するだけで対応可能。
 *
 * @type {Record<string, string>}
 */
const ERROR_TYPE_TO_CATEGORY = Object.freeze({
    // ① ユーザー（設定）起因
    invalid_request_error: ERROR_CATEGORIES.USER_ERROR,
    authentication_error: ERROR_CATEGORIES.USER_ERROR,
    permission_error: ERROR_CATEGORIES.USER_ERROR,
    not_found_error: ERROR_CATEGORIES.USER_ERROR,

    // ② 利用制限（時間経過で回復）
    rate_limit_error: ERROR_CATEGORIES.RATE_LIMIT,
    inference_rate_limit_exceeded: ERROR_CATEGORIES.RATE_LIMIT,

    // ③ クォータ枯渇（課金切れ等、時間経過では回復しない）
    insufficient_quota: ERROR_CATEGORIES.QUOTA_EXHAUSTED,

    // ④ OpenAI側障害
    server_error: ERROR_CATEGORIES.SERVER_ERROR,
    realtime_connection_error: ERROR_CATEGORIES.SERVER_ERROR,
});

// ---------------------------------------------------------------------------
// 公開API
// ---------------------------------------------------------------------------

/**
 * error.type からエラーカテゴリを判定する
 * @param {string} errorType - OpenAI error.type の値
 * @returns {string} ERROR_CATEGORIES のいずれか、または未知の場合は SERVER_ERROR
 */
export function classifyErrorType(errorType) {
    return ERROR_TYPE_TO_CATEGORY[errorType] || ERROR_CATEGORIES.SERVER_ERROR;
}

/**
 * error.type からユーザー向けメッセージを取得する
 * @param {string} errorType - OpenAI error.type の値
 * @returns {string} ユーザーに表示するメッセージ
 */
export function getErrorMessage(errorType) {
    const category = classifyErrorType(errorType);
    return categoryMessages()[category] || defaultMessage();
}

/**
 * レスポンスエラー情報を分類し、表示用の情報を返す
 * @param {Object} params
 * @param {string} params.errorType  - error.type の値
 * @param {string} [params.errorCode]    - error.code の値（ログ用）
 * @param {string} [params.errorMessage] - error.message の値（ログ用）
 * @returns {{ category: string, userMessage: string, errorType: string, errorCode: string, errorMessage: string }}
 */
export function classifyResponseError({ errorType, errorCode = "", errorMessage = "" }) {
    let category = classifyErrorType(errorType);

    // errorCode が insufficient_quota の場合も QUOTA_EXHAUSTED に分類
    // （OpenAI API は error.type ではなく error.code で返す場合がある）
    if (errorCode === "insufficient_quota") {
        category = ERROR_CATEGORIES.QUOTA_EXHAUSTED;
    }

    const userMessage = categoryMessages()[category] || defaultMessage();

    return {
        category,
        userMessage,
        errorType,
        errorCode,
        errorMessage,
    };
}
