import type { SettingsService } from './SettingsService.js';

// v0.3.1 Cut F final fix — gemma 시리즈 default 정정. 본인 dogfood 환경 = gemma4:e4b
// (텍스트). vision 변종은 gemma3 (현재 vision-capable) 또는 gemma4 (향후 출시 시).
// 양 family 모두 hint 에 포함 — capability detection 이 future-proof.
const VISION_FAMILIES = new Set(['gemma3', 'gemma4', 'llava', 'llama3.2-vision', 'minicpm-v', 'pixtral']);
const VISION_NAME_HINTS = ['vision', 'vl', 'multimodal', 'gemma3', 'gemma4'];

export interface OllamaModel {
  name: string;
  details?: { family?: string; families?: string[] };
}

export function isVisionCapable(model: OllamaModel): boolean {
  if (model.details?.family && VISION_FAMILIES.has(model.details.family)) return true;
  if (model.details?.families?.some((f) => VISION_FAMILIES.has(f))) return true;
  const lower = model.name.toLowerCase();
  return VISION_NAME_HINTS.some((h) => lower.includes(h));
}

export interface RefreshDeps {
  settings: SettingsService;
  endpoint: string;
  now?: () => Date;
  fetchImpl?: typeof fetch;
}

export async function refreshVisionCache(
  deps: RefreshDeps
): Promise<{ ok: true; models: string[] } | { ok: false; reason: string }> {
  if (!(await deps.settings.isAiEnabled())) {
    return { ok: false, reason: 'ai_disabled' };
  }
  const fetchFn = deps.fetchImpl ?? fetch;
  let body: { models?: OllamaModel[] };
  try {
    const r = await fetchFn(`${deps.endpoint}/api/tags`);
    if (!r.ok) return { ok: false, reason: `tags http ${r.status}` };
    body = (await r.json()) as { models?: OllamaModel[] };
  } catch (e) {
    return { ok: false, reason: `unreachable: ${(e as Error).message}` };
  }
  const capable = (body.models ?? []).filter(isVisionCapable).map((m) => m.name);
  const now = deps.now ? deps.now() : new Date();
  await deps.settings.setVisionCapableCache(capable, now);
  return { ok: true, models: capable };
}
