import { describe, expect, it } from "vitest";
import {
  checkThreadsTerm,
  expandIncludeTerms,
  isThreadsSearchable,
  normalizeSearchTerm,
  searchableTermVariants,
  selectThreadsSearchTerms,
  threadsPostIdentity,
} from "./threadsTerm";

describe("threadsTerm", () => {
  it("normalizes full-width spaces", () => {
    expect(normalizeSearchTerm("  保母　求推薦  ")).toBe("保母 求推薦");
  });

  it("accepts short Threads terms", () => {
    expect(isThreadsSearchable("保母 求推薦")).toBe(true);
    expect(isThreadsSearchable("到府保母")).toBe(true);
    expect(isThreadsSearchable("wedding photo")).toBe(true);
  });

  it("rejects overlong or multi-token or punctuated terms", () => {
    expect(isThreadsSearchable("台北 婚攝 推薦")).toBe(false);
    expect(isThreadsSearchable("這是一個超長關鍵字超過十二字")).toBe(false);
    expect(isThreadsSearchable("保母 AND 求推薦")).toBe(false);
    expect(isThreadsSearchable("保母#推薦")).toBe(false);
    expect(isThreadsSearchable("a")).toBe(false);
    expect(checkThreadsTerm("")).toEqual({ ok: false, reason: "empty" });
  });

  it("shortens long CJK sentences into searchable windows", () => {
    expect(searchableTermVariants("保母 求推薦")).toEqual(["保母 求推薦"]);
    const variants = searchableTermVariants("晚上睡覺容易口乾舌燥怎麼辦");
    expect(variants.length).toBeGreaterThan(0);
    expect(variants.every(isThreadsSearchable)).toBe(true);
    expect(variants).toContain("晚上睡覺");
    expect(variants).toContain("口乾舌燥");
    expect(searchableTermVariants("台北 婚攝 推薦 價格")[0]).toBe("台北 婚攝");
    expect(expandIncludeTerms(["求推薦", "晚上睡覺容易口乾舌燥怎麼辦"])).toEqual(
      expect.arrayContaining(["求推薦", "晚上睡覺", "口乾舌燥"]),
    );
  });

  it("selects inferred work queries when the original has too many tokens", () => {
    expect(
      selectThreadsSearchTerms("外包 工程師 後端", [
        "後端 外包",
        "後端 接案",
        "後端 工程師",
        "外包 案件",
      ]),
    ).toEqual(["後端 外包", "後端 接案", "後端 工程師"]);
  });

  it("keeps an exact title and adds discovery variants", () => {
    expect(selectThreadsSearchTerms("鬼滅之刃", ["鬼滅之刃", "鬼滅之刃 熱門", "鬼滅之刃 最新"]))
      .toEqual(["鬼滅之刃", "鬼滅之刃 熱門", "鬼滅之刃 最新"]);
  });

  it("dedupes Threads host aliases and share URLs by post shortcode", () => {
    const aliases = [
      "https://www.threads.net/@alice/post/AbC123?xmt=AQG",
      "https://threads.com/@alice/post/AbC123/",
      "https://m.threads.net/@renamed/post/AbC123#reply",
      "https://www.threads.com/t/AbC123",
    ];
    expect(aliases.map(threadsPostIdentity)).toEqual([
      "threads-post:AbC123",
      "threads-post:AbC123",
      "threads-post:AbC123",
      "threads-post:AbC123",
    ]);
    expect(threadsPostIdentity("https://threads.net/@alice/post/OtherCode"))
      .toBe("threads-post:OtherCode");
  });
});
