import { z } from "zod";
import type { ProviderApiKeys } from "./keys";
import { withAgentSystem } from "./agent";
import { generateStructuredObject } from "./generate-structured";
import { getModel } from "./provider";
import type { QualityAssessment, QualityTier, ResearchMap } from "@/lib/types/research";
import { formatProductContextForPrompt } from "@/lib/types/product-context";
import { buildContentBandPromptBlock } from "@/lib/research-content-band";
import { buildTopicAnchorPromptBlock } from "@/lib/topic-anchor";
import {
  formatPlacementTimingHint,
  formatPostAgeLabel,
  PLACEMENT_IDEAL_MAX_AGE_DAYS,
  PLACEMENT_MAX_POST_AGE_DAYS,
} from "@/lib/scan-recency";

const filterSchema = z.object({
  items: z.array(
    z.object({
      index: z.number().int().min(0),
      placementScore: z.number().min(0).max(100),
      qualityTier: z.enum(["GOOD", "OK", "EXCLUDE"]),
      placementReason: z.string(),
    })
  ),
});

export interface FilterPlacementInput {
  topicLabel: string;
  query: string;
  brief?: string | null;
  productContext?: string | null;
  researchMap?: ResearchMap | null;
  aiProvider: string;
  aiModel: string;
  apiKeys?: ProviderApiKeys;
  posts: Array<{
    id: string;
    text: string;
    authorName?: string | null;
    searchTag?: string | null;
    postedAt?: Date | null;
    likeCount?: number | null;
    replyCount?: number | null;
    replies?: string[] | null;
  }>;
}

export async function filterPostPlacement(input: FilterPlacementInput): Promise<QualityAssessment[]> {
  if (input.posts.length === 0) return [];

  const model = getModel(input.aiProvider, input.aiModel, input.apiKeys ?? {});

  const researchBlock = input.researchMap
    ? `
研究地圖：
- 受眾：${input.researchMap.audienceSummary}
- 目標：${input.researchMap.contentGoal}
`
    : "";
  const contentBandBlock = buildContentBandPromptBlock(input.researchMap);

  const postsBlock = input.posts
    .map((post, i) => {
      const replyLines = (post.replies ?? []).filter(Boolean).slice(0, 2);
      const replyBlock =
        replyLines.length > 0
          ? `\n留言區（觀眾反應）：${replyLines.map((r) => `「${r.slice(0, 60)}」`).join(" ")}`
          : "";
      return `[${i}] 標籤：${post.searchTag ?? input.query} | 發文：${formatPostAgeLabel(post.postedAt)}（${formatPlacementTimingHint(post.postedAt)}） | @${post.authorName ?? "匿名"} | ${post.likeCount ?? 0}讚 ${post.replyCount ?? 0}留言
${post.text.slice(0, 280)}${replyBlock}`;
    })
    .join("\n\n");

  const object = await generateStructuredObject({
    model,
    provider: input.aiProvider,
    modelId: input.aiModel,
    schema: filterSchema,
    system: withAgentSystem(`你是 Threads 產品置入機會審核員。核心任務：找出「作者正在煩產品怎麼選、現在留言還來得及、且能自然帶入產品」的貼文。

你的 TA 不是「有養寵物的人在閒聊」，而是「正在遇到困擾、會主動發文求助或求推薦的人」。

評分標準（需求明確度 > 置入自然度 > 時間窗口 > 互動熱度）：
- placementScore 0-100：綜合「需求明確度 × 置入自然度 × 時間窗口」
- **需求明確度（最重要）**：
  - GOOD 典型（以寵物洗毛精為例）：在家幫狗洗澡、狗皮膚癢/過敏、不知道用什麼洗毛精、求推薦沐浴用品、第一次自己洗狗很怕
  - 必須能看出「產品可解決的困擾」或「正在選購」；只有提到寵物但沒有困擾/選購訊號 → EXCLUDE
  - 純晒照、日常閒聊、萌寵廢文、心情分享、已完成購買的開箱、明顯業配 → 一律 EXCLUDE
  - 只沾邊「狗」「寵物」但沒有洗澡/皮膚/沐浴/洗毛精/選購相關 → EXCLUDE
- **時間窗口**：
  - 今天～3 天內的求助／求推薦帖 → 大幅加分
  - ${PLACEMENT_IDEAL_MAX_AGE_DAYS} 天內仍可考慮，但分數應低於 3 天內
  - 超過 ${PLACEMENT_MAX_POST_AGE_DAYS} 天 → 一律 EXCLUDE
  - 發文日期未知 → 最高只能 OK，且 placementScore 不超過 55
- **置入自然度**：
  - 留言區若有人附和困擾、追問解法 → 加分；若已被業配／他牌洗版、問題已解決 → 降分或 EXCLUDE
- **內容區間（硬性）**：
  - 貼文須呼應「受眾會問什麼」至少一項，或符合「內容支柱」至少一項
  - 觸及「不要碰」任一項 → 一律 EXCLUDE
  - 有求助語氣但完全不在內容區間 → EXCLUDE
- **主題相關**：
  - 嚴格剔除跑題：洗碗精≠洗毛精、人類洗髮≠寵物沐浴、不同產品類別
- qualityTier：
  - GOOD：近期 + 明確求助/痛點/求推薦 + 扣緊產品情境 + 留言區還能自然插入建議
  - OK：相關且有困擾訊號，但需求不夠明確、或已超過 3 天
  - EXCLUDE：閒聊、晒照、跑題、過舊、已推他牌、無法自然置入

placementReason 用台灣用語繁體中文，**第一句先說有無產品需求**，再說時間窗口與置入自然度。`),
    prompt: `主題：${input.topicLabel}
種子關鍵字：${input.query}
${input.brief ? `受眾 Brief：${input.brief}` : ""}
${input.productContext ? `品牌與產品：\n${formatProductContextForPrompt(input.productContext)}` : ""}
${buildTopicAnchorPromptBlock({
  label: input.topicLabel,
  query: input.query,
  brief: input.brief,
  exclusions: input.researchMap?.exclusions,
})}
${researchBlock}
${contentBandBlock}

待評估貼文：
${postsBlock}`,
  });

  return object.items
    .filter((item) => item.index >= 0 && item.index < input.posts.length)
    .map((item) => ({
      id: input.posts[item.index].id,
      relevanceScore: item.placementScore,
      placementScore: item.placementScore,
      qualityTier: item.qualityTier as QualityTier,
      qualityReason: item.placementReason,
      placementReason: item.placementReason,
    }));
}
