/**
 * Settings 共享工具函数
 */
import { useSettingsStore } from './store';
import { hanaFetch } from './api';
import registry from '../../shared/theme-registry.cjs';
import { lookupReferenceModelMeta } from '../utils/model-metadata';
import { API_PROVIDER_PRESETS, getProviderPresetLabel } from '../utils/provider-presets';

export function t(key: string, params?: Record<string, any>): any {
  return window.t?.(key, params) ?? key;
}

export function escapeHtml(str: string): string {
  const div = document.createElement('div');
  div.textContent = str;
  return div.innerHTML;
}

export function formatContext(n: number): string {
  if (!n) return '';
  if (n >= 1000000) {
    const m = n / 1000000;
    return (Number.isInteger(m) ? m : +m.toFixed(1)) + 'M';
  }
  const k = n / 1024;
  if (Number.isInteger(k)) return k + 'K';
  return Math.round(n / 1000) + 'K';
}

/**
 * 查模型元数据（合并 known-models / user-yaml / legacy overrides）。
 *
 * 契约：调用方尽可能传 provider，消除多 provider 同名歧义。
 * UI 展示场景仅有 id 可不传，接受展示层降级（取第一个命中）。
 * 运行时查找/比较**必须**用 shared/model-ref.js 的 findModel。
 */
export function lookupModelMeta(modelId: string, provider?: string): any {
  if (!modelId) return null;
  const reference = lookupReferenceModelMeta(modelId, provider);

  // 从 provider summaries 提取用户在 added-models.yaml 中设置的模型元数据
  const { providersSummary, settingsConfig } = useSettingsStore.getState();
  let userEntry: Record<string, any> | null = null;
  if (providersSummary) {
    if (provider && providersSummary[provider]) {
      const found = (providersSummary[provider].models || []).find(
        (m: any) => typeof m === 'object' && m?.id === modelId,
      );
      if (found) userEntry = found as unknown as Record<string, any>;
    } else {
      // 展示降级
      for (const summary of Object.values(providersSummary)) {
        const found = (summary.models || []).find(
          (m: any) => typeof m === 'object' && m?.id === modelId,
        );
        if (found) { userEntry = found as unknown as Record<string, any>; break; }
      }
    }
  }

  // 兼容旧数据：仍然读 config.models.overrides 的 displayName
  const legacyOverride = settingsConfig?.models?.overrides?.[modelId];

  if (!reference && !userEntry && !legacyOverride) return null;
  return {
    ...(reference || {}),
    ...(userEntry || {}),
    ...(legacyOverride?.displayName ? { displayName: legacyOverride.displayName } : {}),
  };
}

/** 通用 per-agent 自动保存 */
export async function autoSaveConfig(
  partial: Record<string, any>,
  opts: { silent?: boolean } = {},
): Promise<boolean> {
  const store = useSettingsStore.getState();
  try {
    const agentId = store.getSettingsAgentId();
    const res = await hanaFetch(`/api/agents/${agentId}/config`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(partial),
    });
    const data = await res.json();
    if (data.error) throw new Error(data.error);
    if (!opts.silent) store.showToast(t('settings.autoSaved'), 'success');
    // 刷新 config 快照，保留 _identity / _ishiki / _userProfile
    const cfgRes = await hanaFetch(`/api/agents/${agentId}/config`);
    const newConfig = await cfgRes.json();
    const prev = useSettingsStore.getState().settingsConfig || {};
    for (const k of ['_identity', '_ishiki', '_publicIshiki', '_userProfile', '_experience']) {
      if (k in prev && !(k in newConfig)) newConfig[k] = (prev as any)[k];
    }
    useSettingsStore.setState({ settingsConfig: newConfig });
    return true;
  } catch (err: any) {
    store.showToast(t('settings.saveFailed') + ': ' + err.message, 'error');
    return false;
  }
}

/** 全局模型自动保存 */
export async function autoSaveGlobalModels(
  partial: Record<string, any>,
  opts: { silent?: boolean } = {},
) {
  const store = useSettingsStore.getState();
  try {
    const res = await hanaFetch('/api/preferences/models', {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(partial),
    });
    const data = await res.json();
    if (data.error) throw new Error(data.error);
    if (!opts.silent) store.showToast(t('settings.autoSaved'), 'success');
    const refreshRes = await hanaFetch('/api/preferences/models');
    const newGlobal = await refreshRes.json();
    useSettingsStore.setState({ globalModelsConfig: newGlobal });
  } catch (err: any) {
    store.showToast(t('settings.saveFailed') + ': ' + err.message, 'error');
  }
}

let _savePinsTimer: ReturnType<typeof setTimeout> | null = null;
export function savePins() {
  if (_savePinsTimer) clearTimeout(_savePinsTimer);
  _savePinsTimer = setTimeout(async () => {
    const store = useSettingsStore.getState();
    try {
      const agentId = store.getSettingsAgentId();
      const res = await hanaFetch(`/api/agents/${agentId}/pinned`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ pins: store.currentPins }),
      });
      const data = await res.json();
      if (data.error) throw new Error(data.error);
      store.showToast(t('settings.autoSaved'), 'success');
    } catch (err: any) {
      store.showToast(t('settings.saveFailed') + ': ' + err.message, 'error');
    }
  }, 300);
}

export const PROVIDER_PRESETS = API_PROVIDER_PRESETS.map(preset => ({
  ...preset,
  label: getProviderPresetLabel(preset),
}));

export const API_FORMAT_OPTIONS = [
  { value: 'openai-completions', label: 'OpenAI Compatible' },
  { value: 'google-generative-ai', label: 'Google Gemini' },
  { value: 'anthropic-messages', label: 'Anthropic Messages' },
  { value: 'openai-responses', label: 'OpenAI Responses' },
  { value: 'openai-codex-responses', label: 'ChatGPT Codex (Plus/Pro)' },
];

export const CONTEXT_PRESETS = [
  { label: '64K', value: 65536 },
  { label: '128K', value: 131072 },
  { label: '200K', value: 200000 },
  { label: '256K', value: 262144 },
  { label: '1M', value: 1048576 },
];

export const OUTPUT_PRESETS = [
  { label: '8K', value: 8192 },
  { label: '16K', value: 16384 },
  { label: '32K', value: 32768 },
  { label: '64K', value: 65536 },
];

const _ids = registry.getThemeIds();
export const VALID_THEMES = [
  _ids[0],                    // warm-paper
  _ids[1],                    // midnight
  registry.AUTO_OPTION.id,    // auto (第 3 位，保持原顺序)
  ..._ids.slice(2),           // high-contrast, grass-aroma, contemplation, absolutely, delve, deep-think, new-warm-paper
];
