import { prisma } from "@/lib/db";

/**
 * AI provider helper — reads OpenAI-compatible config from the Setting table
 * (so the user can change provider/model/key from /admin/settings without a
 * redeploy) and exposes a thin chat completion wrapper.
 *
 * Settings keys (category=ai):
 *   ai.openai_base_url   — e.g. https://api.openai.com/v1
 *   ai.openai_api_key    — secret
 *   ai.openai_model      — e.g. gpt-4o-mini
 */

export type AiConfig = {
  baseUrl: string;
  apiKey: string;
  model: string;
};

export async function loadAiConfig(): Promise<AiConfig | null> {
  const rows = await prisma.setting.findMany({
    where: { category: "ai" },
    select: { key: true, value: true },
  });
  const map = new Map(rows.map((r) => [r.key, r.value]));
  const baseUrl = (map.get("ai.openai_base_url") ?? "").trim();
  const apiKey = (map.get("ai.openai_api_key") ?? "").trim();
  const model = (map.get("ai.openai_model") ?? "").trim();
  if (!baseUrl || !apiKey || !model) return null;
  return { baseUrl: baseUrl.replace(/\/+$/, ""), apiKey, model };
}

export type ChatMessage = { role: "system" | "user" | "assistant"; content: string };

export type ChatResult = {
  content: string;
  usage?: { promptTokens?: number; completionTokens?: number; totalTokens?: number };
  model: string;
  latencyMs: number;
};

export async function chat(
  cfg: AiConfig,
  messages: ChatMessage[],
  opts: { temperature?: number; maxTokens?: number } = {},
): Promise<ChatResult> {
  const url = `${cfg.baseUrl}/chat/completions`;
  const body = {
    model: cfg.model,
    messages,
    temperature: opts.temperature ?? 0.6,
    max_tokens: opts.maxTokens ?? 800,
  };
  const t0 = Date.now();
  const res = await fetch(url, {
    method: "POST",
    headers: {
      "content-type": "application/json",
      authorization: `Bearer ${cfg.apiKey}`,
    },
    body: JSON.stringify(body),
    cache: "no-store",
  });
  const latencyMs = Date.now() - t0;
  if (!res.ok) {
    const errText = await res.text().catch(() => "");
    throw new Error(`AI ${res.status}: ${errText.slice(0, 240)}`);
  }
  const data = (await res.json()) as {
    choices?: Array<{ message?: { content?: string } }>;
    model?: string;
    usage?: {
      prompt_tokens?: number;
      completion_tokens?: number;
      total_tokens?: number;
    };
  };
  const content = data.choices?.[0]?.message?.content ?? "";
  return {
    content,
    usage: data.usage
      ? {
          promptTokens: data.usage.prompt_tokens,
          completionTokens: data.usage.completion_tokens,
          totalTokens: data.usage.total_tokens,
        }
      : undefined,
    model: data.model ?? cfg.model,
    latencyMs,
  };
}
