import { z } from "zod";
import { withAgentSystem } from "./agent";
import type { ProviderApiKeys } from "./keys";
import { generateStructuredObject } from "./generate-structured";
import { getModel } from "./provider";
import {
  getProviderLabel,
  isBraveSearchConfigured,
  searchWebThorough,
  type SearchProvider,
} from "@/lib/services/web-search";

const classifySchema = z.object({
  isKnowledgeContent: z.boolean(),
  reason: z.string().optional().default(""),
  claims: z.array(z.string()).max(5).default([]),
});

const verdictSchema = z.object({
  passed: z.boolean(),
  summary: z.string(),
  issues: z.array(z.string()),
  verifiedPoints: z.array(z.string()),
  sources: z.array(
    z.object({
      title: z.string(),
      link: z.string(),
    })
  ),
});

export interface FactCheckResult {
  isKnowledgeContent: boolean;
  passed: boolean;
  summary: string;
  issues: string[];
  verifiedPoints: string[];
  sources: Array<{ title: string; link: string }>;
  searchProvider: SearchProvider | "none";
  searchProviderLabel: string;
  skipped?: boolean;
  skipReason?: string;
}

export async function factCheckDraft(params: {
  text: string;
  angle?: string | null;
  searchTag?: string | null;
  topicLabel?: string | null;
  aiProvider: string;
  aiModel: string;
  apiKeys?: ProviderApiKeys;
}): Promise<FactCheckResult> {
  const model = getModel(params.aiProvider, params.aiModel, params.apiKeys ?? {});

  const classified = await generateStructuredObject({
    model,
    provider: params.aiProvider,
    modelId: params.aiModel,
    schema: classifySchema,
    system: withAgentSystem(
      "判斷 Threads 貼文是否屬於「知識型」內容（含健康、醫療、營養、數據、科學、法規、步驟教學等可被查證的陳述）。"
    ),
    prompt: `貼文：
${params.text}

${params.angle ? `角度：${params.angle}` : ""}
${params.searchTag ? `標籤：${params.searchTag}` : ""}
${params.topicLabel ? `主題：${params.topicLabel}` : ""}

若主要是語錄、心情、故事、觀點抒發且無具體可驗證事實 → isKnowledgeContent=false。
若是知識型，列出 1～5 個需要網路搜尋查證的關鍵陳述（claims）。`,
  });

  if (!classified.isKnowledgeContent) {
    return {
      isKnowledgeContent: false,
      passed: true,
      summary: classified.reason || "非知識型內容，無需查證即可發布。",
      issues: [],
      verifiedPoints: [],
      sources: [],
      searchProvider: "none",
      searchProviderLabel: "略過",
      skipped: true,
      skipReason: classified.reason,
    };
  }

  const claims = classified.claims.filter(Boolean).slice(0, 5);
  if (claims.length === 0) {
    return {
      isKnowledgeContent: true,
      passed: false,
      summary: "判定為知識型內容，但無法提取可查證陳述，請改寫得更具體或人工確認後再發。",
      issues: ["無法提取可查證的關鍵陳述"],
      verifiedPoints: [],
      sources: [],
      searchProvider: "none",
      searchProviderLabel: "無",
    };
  }

  const searchBlocks: string[] = [];
  let primaryProvider: SearchProvider = "brave";
  let providerLabel = isBraveSearchConfigured() ? "Brave Search" : "未設定";
  const allResults: Array<{ title: string; link: string; snippet: string }> = [];

  for (const claim of claims) {
    const query = `${claim} ${params.topicLabel ?? ""}`.trim();
    const { results, provider, providerLabel: label } = await searchWebThorough(query, 5, {
      patrolMode: false,
      threadsOnly: false,
    });
    primaryProvider = provider;
    providerLabel = label;
    for (const r of results) {
      allResults.push({ title: r.title, link: r.link, snippet: r.snippet });
      searchBlocks.push(
        `【查詢：${query}】（${getProviderLabel(r.provider)}）\n- ${r.title}\n  ${r.snippet}\n  ${r.link}`
      );
    }
  }

  if (allResults.length === 0) {
    return {
      isKnowledgeContent: true,
      passed: false,
      summary:
        "網路搜尋暫無結果，知識型內容暫不建議發布。請稍後重試或改寫成較好查證的表述。",
      issues: ["查無可參考來源（請設定 BRAVE_SEARCH_API_KEY 或稍後重試）"],
      verifiedPoints: [],
      sources: [],
      searchProvider: primaryProvider,
      searchProviderLabel: providerLabel,
    };
  }

  const verdict = await generateStructuredObject({
    model,
    provider: params.aiProvider,
    modelId: params.aiModel,
    schema: verdictSchema,
    system: withAgentSystem(`你是事實查核編輯。知識型 Threads 貼文發布前，必須根據網路搜尋結果判斷是否可發。

規則：
- 只有搜尋結果能支持或合理支持的核心陳述才算通過
- 醫療健康：保守判斷，有疑慮就 passed=false
- issues 列出具體哪句話有問題、為什麼
- verifiedPoints 列出已獲搜尋結果支持的陳述
- sources 從搜尋結果選 2～5 個最相關連結
- 繁體中文台灣用語`),
    prompt: `待發布貼文：
${params.text}

需查證陳述：
${claims.map((c, i) => `${i + 1}. ${c}`).join("\n")}

網路搜尋結果（來源：${providerLabel}）：
${searchBlocks.join("\n\n")}

請判斷是否可發布。`,
  });

  return {
    isKnowledgeContent: true,
    passed: verdict.passed,
    summary: verdict.summary,
    issues: verdict.issues,
    verifiedPoints: verdict.verifiedPoints,
    sources: verdict.sources,
    searchProvider: primaryProvider,
    searchProviderLabel: providerLabel,
  };
}