import type { BrandProduct, ScoutRunBrief, ScoutScanContext } from "../domain/types";

/** 簡單相關詞表：有命中才擴，避免假圖譜 */
const RELATED: Record<string, string[]> = {
  無香: ["香精過敏", "刺鼻", "低敏洗劑"],
  敏感肌: ["換季刺癢", "成分表", "溫和"],
  香精: ["無香", "刺鼻", "過敏"],
  刺鼻: ["無香", "香精"],
  洗衣精: ["洗淨力", "殘留", "寶寶衣物"],
  寶寶: ["嬰幼兒", "溫和", "洗不乾淨"],
  插座: ["不限時", "筆電", "久坐"],
  咖啡廳: ["第三空間", "安靜", "插座"],
  筆電: ["插座", "工作座位"],
  頭皮: ["換季", "無香", "刺癢"],
  刺癢: ["敏感肌", "換季", "成分"],
  第三空間: ["咖啡廳", "插座", "久坐"],
  週末: ["去哪", "人少", "不限時"],
};

const STOP = new Set([
  "的",
  "了",
  "在",
  "是",
  "我",
  "有",
  "和",
  "就",
  "不",
  "人",
  "都",
  "一",
  "這",
  "次",
  "想",
  "找",
  "海",
  "巡",
  "主題",
  "關於",
  "可以",
  "什麼",
  "為",
  "或",
  "與",
  "到",
  "會",
  "被",
  "讓",
]);

function expandFromSeeds(seeds: string[]): string[] {
  const out: string[] = [];
  const seen = new Set(seeds.map((s) => s.toLowerCase()));
  for (const s of seeds) {
    const key = Object.keys(RELATED).find((k) => s.includes(k) || k.includes(s));
    if (!key) continue;
    for (const r of RELATED[key] || []) {
      if (seen.has(r.toLowerCase())) continue;
      seen.add(r.toLowerCase());
      out.push(r);
      if (out.length >= 6) return out;
    }
  }
  return out;
}

/** 從意圖粗抽關鍵詞（mock，非 NLP） */
export function extractIntentTerms(intent: string): string[] {
  const raw = intent
    .replace(/[，。！？、；：\s\n\r#@「」『』（）()[\]{}]/g, " ")
    .split(/\s+/)
    .map((s) => s.trim())
    .filter((s) => s.length >= 2 && !STOP.has(s));
  // 也抓 RELATED 鍵是否出現在全文
  const hits: string[] = [];
  for (const k of Object.keys(RELATED)) {
    if (intent.includes(k) && !hits.includes(k)) hits.push(k);
  }
  const merged = [...hits, ...raw];
  const seen = new Set<string>();
  const out: string[] = [];
  for (const t of merged) {
    const key = t.toLowerCase();
    if (seen.has(key)) continue;
    seen.add(key);
    out.push(t);
    if (out.length >= 8) break;
  }
  return out;
}

export function buildScoutScanContext(
  brandId: string,
  products: BrandProduct[],
): ScoutScanContext {
  const pains = [...new Set(products.flatMap((p) => p.pain_points).filter(Boolean))];
  const tags = [...new Set(products.flatMap((p) => p.match_tags).filter(Boolean))];
  const seeds = [...pains, ...tags, ...products.map((p) => p.label)];
  const expand_terms = expandFromSeeds(seeds);
  return {
    brand_id: brandId,
    product_ids: products.map((p) => p.id),
    pains: pains.slice(0, 8),
    tags: tags.slice(0, 12),
    expand_terms,
  };
}

/**
 * 從意圖 + 可選產品組 brief。
 * purpose=activity → 關鍵字活躍；否則有 product → product，否則 theme。
 */
export function prepareScoutBrief(opts: {
  intent: string;
  brandId?: string | null;
  product?: BrandProduct | null;
  purpose?: "value" | "activity";
}): ScoutRunBrief {
  const intent = opts.intent.trim();
  if (!intent) throw new Error("請先寫這次想找什麼／關鍵字");

  const intentTerms = extractIntentTerms(intent);
  const product = opts.product || null;
  const purpose = opts.purpose || "value";

  // 活躍度：只吃關鍵字，輕量、不強制功課感
  if (purpose === "activity") {
    const focus = intentTerms.length ? intentTerms : [intent.slice(0, 20)];
    const periphery = expandFromSeeds(focus).slice(0, 4);
    const scan_terms = [...new Set([...focus, ...periphery])].slice(0, 10);
    const theme_label = `活躍 · ${intent.slice(0, 28)}${intent.length > 28 ? "…" : ""}`;
    const theme_key = ["activity", "", intent.slice(0, 48)].join("|");
    return {
      intent,
      mode: "activity",
      brand_id: opts.brandId || null,
      product_id: null,
      product_label: null,
      pains: focus.slice(0, 4),
      tags: focus.slice(0, 8),
      periphery,
      scan_terms,
      theme_key,
      theme_label,
      response_stance:
        "短回、自然、有溫度；目的是活躍與互動率，不硬銷、不長文說教。可接一句同感或小問題。",
    };
  }

  if (product) {
    const pains = [...(product.pain_points || [])].filter(Boolean);
    const tags = [...(product.match_tags || [])].filter(Boolean);
    // 意圖與產品語境對齊：意圖詞若與痛／標籤重疊優先
    const aligned = intentTerms.filter(
      (t) =>
        pains.some((p) => p.includes(t) || t.includes(p)) ||
        tags.some((g) => g.includes(t) || t.includes(g)) ||
        (product.label && (product.label.includes(t) || t.includes(product.label))),
    );
    const periphery = expandFromSeeds([...pains, ...tags, ...intentTerms, product.label]);
    const scan_terms = [
      ...new Set([
        ...aligned,
        ...pains.slice(0, 4),
        ...tags.slice(0, 4),
        ...intentTerms.slice(0, 3),
        ...periphery.slice(0, 3),
      ]),
    ].slice(0, 12);
    const theme_label = product.label;
    const theme_key = ["product", product.id, intent.slice(0, 48)].join("|");

    return {
      intent,
      mode: "product",
      brand_id: opts.brandId || product.brand_id,
      product_id: product.id,
      product_label: product.label,
      pains: pains.slice(0, 8),
      tags: tags.slice(0, 10),
      periphery,
      scan_terms,
      theme_key,
      theme_label,
      placement_note:
        product.product_context?.trim() ||
        `共感對方痛點後，輕帶「${product.label}」使用情境（勿硬銷）。`,
    };
  }

  // 主題模式
  const focus = intentTerms.length ? intentTerms : [intent.slice(0, 16)];
  const periphery = expandFromSeeds(focus);
  const scan_terms = [...new Set([...focus, ...periphery])].slice(0, 12);
  const theme_label = intent.slice(0, 36) + (intent.length > 36 ? "…" : "");
  const theme_key = ["theme", "", intent.slice(0, 48)].join("|");

  return {
    intent,
    mode: "theme",
    brand_id: opts.brandId || null,
    product_id: null,
    product_label: null,
    pains: focus.slice(0, 4), // 主題焦點展示
    tags: focus.slice(0, 8),
    periphery,
    scan_terms,
    theme_key,
    theme_label,
    response_stance: "接話、分享經驗、可留問句；不硬銷、不提產品連結。",
  };
}

/** mock 命中正文模板 */
export function mockHitTextsForTerm(
  term: string,
  mode: "product" | "theme" | "activity",
  productLabel?: string | null,
): string[] {
  if (mode === "product") {
    return [
      `有人也被「${term}」搞到很煩嗎？求真正用過的經驗，不要業配腔。`,
      `最近一直卡在${term}，試了幾個都不對…有人有務實建議嗎？`,
      productLabel
        ? `想問有沒有比較溫和的解法（想到${term}），不一定要貴的。`
        : `關於「${term}」想聽真實心得。`,
    ];
  }
  if (mode === "activity") {
    return [
      `隨便聊聊：「${term}」你們最近有感嗎？`,
      `路過刷到「${term}」，想聽一句真心話就好。`,
      `今天就想跟「${term}」相關的人講兩句，有人也在嗎？`,
    ];
  }
  return [
    `最近在想「${term}」這件事，有人也有興趣聊聊嗎？`,
    `有人在跟「${term}」相關的坑嗎？想聽故事。`,
    `週末如果聊「${term}」，你們會先問什麼？`,
  ];
}
