import { z } from "zod";
import type { ProviderApiKeys } from "./keys";
import { generateStructuredObject } from "./generate-structured";
import { getModel } from "./provider";
import { filterSuggestedTags, preserveTagsFromPreviousMap } from "./normalize-suggested-tags";
import { buildResearchMapSystemPrompt } from "./prompts/research-map";
import { buildTopicAnchorPromptBlock } from "@/lib/topic-anchor";
import type { ResearchMap } from "@/lib/types/research";

const searchIntentSchema = z.enum([
  "痛點",
  "知識",
  "經驗",
  "對比",
  "工具",
  "語錄",
  "需求",
  "求助",
]);
const searchTypeSchema = z.enum(["短詞", "情境", "帳號", "語錄"]);

const researchMapSchema = z.object({
  audienceSummary: z.string(),
  contentGoal: z.string(),
  questions: z.array(z.string()).min(1).max(12),
  pillars: z.array(z.string()).min(1).max(8),
  suggestedTags: z
    .array(
      z.object({
        tag: z.string(),
        reason: z.string(),
        searchIntent: searchIntentSchema,
        searchType: searchTypeSchema.optional(),
      })
    )
    .min(1)
    .max(15),
  similarAccounts: z
    .array(
      z.object({
        username: z.string(),
        reason: z.string(),
        postUrl: z.string().optional(),
        profileUrl: z.string().optional(),
        source: z.enum(["web", "threads", "scan"]).optional(),
        confidence: z.enum(["high", "medium", "low"]).optional(),
        lastActiveAt: z.string().optional(),
      })
    )
    .optional(),
  exclusions: z.array(z.string()).min(1).max(12),
});

const refineResponseSchema = z.object({
  reply: z.string(),
  researchMap: researchMapSchema,
});

export interface RefineChatMessage {
  role: "user" | "assistant";
  content: string;
}

export interface RefineResearchMapInput {
  label: string;
  query: string;
  brief?: string | null;
  persona?: string | null;
  currentMap: ResearchMap;
  message: string;
  history?: RefineChatMessage[];
  aiProvider: string;
  aiModel: string;
  apiKeys?: ProviderApiKeys;
}

function buildRefineUserPrompt(input: RefineResearchMapInput): string {
  const historyBlock =
    input.history && input.history.length > 0
      ? `\n【先前對話】\n${input.history
          .map((m) => `${m.role === "user" ? "用戶" : "助理"}：${m.content}`)
          .join("\n")}\n`
      : "";

  return `【主題】${input.label}（種子字：${input.query}）
【Brief】${input.brief?.trim() || "（無）"}
${buildTopicAnchorPromptBlock({ label: input.label, query: input.query, brief: input.brief })}
${historyBlock}
【目前研究地圖草稿】
${JSON.stringify(input.currentMap, null, 2)}

【用戶這次的調整請求】
${input.message}

請依請求微調研究地圖。只改用戶提到的部分，其餘盡量保留。reply 用 2～4 句繁體中文說明改了什麼。`;
}

export async function refineResearchMap(input: RefineResearchMapInput): Promise<{
  reply: string;
  researchMap: ResearchMap;
}> {
  const model = getModel(input.aiProvider, input.aiModel, input.apiKeys ?? {});

  const system = `${buildResearchMapSystemPrompt()}

你現在進入「微調模式」。用戶已有一份研究地圖，會告訴你想改什麼、補什麼、刪什麼。
- 精準執行用戶意圖，不要整份重寫除非用戶明確要求
- 維持 Threads 搜尋標籤品質（短詞優先、像真人會搜的字、扣緊種子關鍵字）
- 用戶沒要求刪的標籤盡量保留；複合主題不可拆成過寬單字（如寵物洗毛精≠只搜寵物或洗碗精）
- reply 簡潔說明變更重點，繁體中文台灣用語

回傳 JSON 格式，須包含兩個欄位：
1. reply：字串，2~4 句繁體中文說明本次變更重點
2. researchMap：研究地圖物件，格式與「目前研究地圖草稿」相同`;

  const prompt = buildRefineUserPrompt(input);

  const object = await generateStructuredObject({
    model,
    provider: input.aiProvider,
    modelId: input.aiModel,
    schema: refineResponseSchema,
    system,
    prompt,
  });

  const tagInput = {
    label: input.label,
    query: input.query,
    brief: input.brief,
    exclusions: input.currentMap.exclusions,
  };

  let researchMap = preserveTagsFromPreviousMap(
    object.researchMap as ResearchMap,
    input.currentMap,
    tagInput
  );

  researchMap = {
    ...researchMap,
    suggestedTags: filterSuggestedTags(researchMap.suggestedTags, tagInput),
    similarAccounts: input.currentMap.similarAccounts,
  };

  return {
    reply: object.reply,
    researchMap,
  };
}

