import type { Persona, TrendItem, TrendKind } from "../domain/types";
import { newId } from "./id";
import { mockDelay, mockGenerateInspiration } from "./mockAi";
import { nowUnixNano } from "./time";

const EXTRA_POOL: Omit<TrendItem, "id" | "observed_at" | "heat">[] = [
  {
    kind: "threads_tag",
    label: "#辦公室零食",
    summary: "午休話題回溫；「同事搶食」與「健康零食」兩極討論。",
    keywords: ["零食", "辦公室", "午休"],
    samples: ["抽屜裡永遠少一包，有人也是嗎？"],
    source_label: "Threads 熱門標籤",
  },
  {
    kind: "threads_tag",
    label: "#早起失敗",
    summary: "作息自我吐槽串；適合輕鬆人設接「前一晚到底在幹嘛」。",
    keywords: ["早起", "賴床", "作息"],
    samples: ["鬧鐘響了七次還是起不來，求物理方法。"],
    source_label: "Threads 熱門標籤",
  },
  {
    kind: "web_keyword",
    label: "低敏洗面乳",
    summary: "成分表關鍵字搜索上升；真實「用完刺癢」留言比評測更有熱度。",
    keywords: ["洗面乳", "低敏", "成分"],
    samples: ["標榜低敏還是刺，有人也遇過嗎？"],
    source_label: "網搜熱門關鍵字",
  },
  {
    kind: "web_keyword",
    label: "筆電咖啡廳 台北",
    summary: "在地搜尋熱；「不限時 + 插座密度」是決策關鍵字。",
    keywords: ["咖啡廳", "筆電", "台北", "不限時"],
    samples: ["文山區能坐下午的店還有嗎？"],
    source_label: "網搜熱門關鍵字",
  },
  {
    kind: "news",
    label: "週末賽事／轉播話題",
    summary: "運動時事帶流量；非粉也可用「不懂但陪看」角度切入生活感。",
    keywords: ["賽事", "週末", "陪看"],
    samples: ["不懂規則但被氣氛感染，你們會看嗎？"],
    source_label: "最近熱門時事",
  },
  {
    kind: "news",
    label: "暑期／開學倒數",
    summary: "季節節點；家長與學生族群討論度上升，可做輕量生活開問。",
    keywords: ["暑假", "開學", "作息"],
    samples: ["作息還沒調回來，只剩三天怎麼救？"],
    source_label: "最近熱門時事",
  },
];

function jitterHeat(heat: number): number {
  const delta = Math.floor(Math.random() * 17) - 8;
  return Math.max(35, Math.min(99, heat + delta));
}

function pickSamples(samples: string[]): string[] {
  if (samples.length <= 1) return samples;
  const shuffled = [...samples].sort(() => Math.random() - 0.5);
  return shuffled.slice(0, Math.min(2, shuffled.length));
}

/** 刷新：抖動熱度、更新時間；有機會換入池中新標 */
export async function mockRefreshTrends(
  current: TrendItem[],
  kind: TrendKind | "all" = "all",
): Promise<TrendItem[]> {
  await mockDelay(700);
  const now = nowUnixNano();
  let next = current.map((t) => ({
    ...t,
    heat: jitterHeat(t.heat),
    samples: pickSamples(t.samples.length ? t.samples : ["（刷新後暫無新片段）"]),
    observed_at: now - Math.floor(Math.random() * 4) * 3_600_000_000_000,
  }));

  if (Math.random() > 0.35) {
    const used = new Set(next.map((t) => t.label));
    const candidates = EXTRA_POOL.filter((p) => !used.has(p.label));
    const pool =
      kind === "all" ? candidates : candidates.filter((p) => p.kind === kind);
    if (pool.length) {
      const pick = pool[Math.floor(Math.random() * pool.length)]!;
      const injected: TrendItem = {
        ...pick,
        id: newId("trend"),
        heat: 55 + Math.floor(Math.random() * 40),
        observed_at: now,
      };
      // drop lowest heat of same kind filter scope
      const sortable = kind === "all" ? next : next.filter((t) => t.kind === kind);
      const drop = [...sortable].sort((a, b) => a.heat - b.heat)[0];
      if (drop) next = next.filter((t) => t.id !== drop.id);
      next = [injected, ...next];
    }
  }

  return next.sort((a, b) => b.heat - a.heat);
}

/** 上網搜：回傳與 query 相關的「熱關鍵字 / 時事」假資料 */
export async function mockSearchTrends(query: string): Promise<TrendItem[]> {
  await mockDelay(800);
  const q = query.trim() || "熱門";
  const now = nowUnixNano();
  const results: TrendItem[] = [
    {
      id: newId("trend"),
      kind: "web_keyword",
      label: `${q} 是什麼`,
      summary: `網搜「${q}」相關：解釋向與清單文並存；真實經驗文互動通常高於純定義。`,
      heat: 70 + Math.floor(Math.random() * 20),
      keywords: [q, `${q} 推薦`, `${q} 心得`],
      samples: [`最近一直刷到「${q}」，有人能用一句話解釋嗎？`],
      source_label: "網搜熱門關鍵字",
      observed_at: now,
    },
    {
      id: newId("trend"),
      kind: "web_keyword",
      label: `${q} 踩雷`,
      summary: `負向關鍵字組合熱度偏高；適合「避雷條件」開問，比直接推品安全。`,
      heat: 60 + Math.floor(Math.random() * 25),
      keywords: [q, "踩雷", "注意"],
      samples: [`買 ${q} 前一定要看什麼？求過來人。`],
      source_label: "網搜熱門關鍵字",
      observed_at: now - 2_000_000_000_000,
    },
    {
      id: newId("trend"),
      kind: "news",
      label: `近日與「${q}」相關討論`,
      summary: `時事／社群交叉討論：可從生活感受切入，再輕帶你的專業視角。`,
      heat: 55 + Math.floor(Math.random() * 30),
      keywords: [q, "近況", "討論"],
      samples: [`大家都在聊 ${q}，我卻還停在…`],
      source_label: "最近熱門時事",
      observed_at: now - 5_000_000_000_000,
    },
    {
      id: newId("trend"),
      kind: "threads_tag",
      label: `#${q.replace(/\s+/g, "")}`,
      summary: `Threads 上與「${q}」相近標籤正在累積回覆；開場宜具體情境。`,
      heat: 65 + Math.floor(Math.random() * 28),
      keywords: [q],
      samples: [`標了 #${q.replace(/\s+/g, "")} 求真實經驗，別業配。`],
      source_label: "Threads 熱門標籤",
      observed_at: now - 1_000_000_000_000,
    },
  ];
  return results.sort((a, b) => b.heat - a.heat);
}

export function sparkCopyFromTrend(
  trend: TrendItem,
  persona?: Persona | null,
): { title: string; hook: string; angle: string } {
  const base = mockGenerateInspiration(trend.label.replace(/^#/, ""), persona);
  const sample = trend.samples[0] || trend.summary;
  return {
    title: `${trend.label} · 切入`,
    hook:
      trend.kind === "threads_tag"
        ? `順著 ${trend.label} 的熱度：用一句貼近「${sample.slice(0, 28)}…」的開問，比空泛跟風標籤好回。`
        : trend.kind === "news"
          ? `時事「${trend.label}」→ 落到日常：${base.hook}`
          : `搜尋熱度在「${trend.label}」：${base.hook}`,
    angle: [
      trend.summary,
      `關鍵字：${trend.keywords.slice(0, 4).join("、")}`,
      base.angle,
    ].join(" "),
  };
}

export function trendKindLabel(kind: TrendKind): string {
  switch (kind) {
    case "threads_tag":
      return "Threads";
    case "web_keyword":
      return "網搜";
    case "news":
      return "時事";
  }
}

/** 帶進寫一則的正文：乾淨、無 meta 尾巴 */
export function seedTextFromTrend(trend: TrendItem, sampleIndex = 0): string {
  const sample = trend.samples[sampleIndex] || trend.samples[0] || "";
  if (sample) return sample;
  return `${trend.label}\n\n${trend.summary}`;
}

/** 列表次行：短摘要 */
export function trendListMeta(trend: TrendItem): string {
  const short =
    trend.summary.length > 42 ? `${trend.summary.slice(0, 42)}…` : trend.summary;
  return `${trendKindLabel(trend.kind)} · ${trend.heat} · ${short}`;
}
