import { describe, it, expect } from "vitest";
import { buildPreferenceMap, scoreCandidate, rankForYou } from "../for-you-ranking";

describe("buildPreferenceMap", () => {
  it("counts tags and true dietary-tag keys across liked recipes", () => {
    const map = buildPreferenceMap([
      { tags: ["spicy", "quick"], dietaryTags: { vegan: true, glutenFree: false } },
      { tags: ["spicy"], dietaryTags: null },
    ]);
    expect(map.get("spicy")).toBe(2);
    expect(map.get("quick")).toBe(1);
    expect(map.get("vegan")).toBe(1);
    expect(map.get("glutenFree")).toBeUndefined();
  });

  it("returns an empty map for no liked recipes", () => {
    expect(buildPreferenceMap([]).size).toBe(0);
  });
});

describe("scoreCandidate", () => {
  it("sums preference weights for overlapping tags", () => {
    const prefs = new Map([["spicy", 3], ["vegan", 1]]);
    const score = scoreCandidate({ tags: ["spicy"], dietaryTags: { vegan: true } }, prefs);
    expect(score).toBe(4);
  });

  it("scores 0 when nothing overlaps", () => {
    const prefs = new Map([["spicy", 3]]);
    expect(scoreCandidate({ tags: ["sweet"], dietaryTags: null }, prefs)).toBe(0);
  });
});

describe("rankForYou", () => {
  const base = { dietaryTags: null };

  it("sorts by score descending", () => {
    const prefs = new Map([["spicy", 5]]);
    const candidates = [
      { id: "a", tags: ["sweet"], createdAt: new Date("2024-01-01"), ...base },
      { id: "b", tags: ["spicy"], createdAt: new Date("2024-01-01"), ...base },
    ];
    const ranked = rankForYou(candidates, prefs);
    expect(ranked.map((r) => r.id)).toEqual(["b", "a"]);
  });

  it("breaks ties by recency", () => {
    const prefs = new Map<string, number>();
    const candidates = [
      { id: "old", tags: [], createdAt: new Date("2024-01-01"), ...base },
      { id: "new", tags: [], createdAt: new Date("2024-06-01"), ...base },
    ];
    const ranked = rankForYou(candidates, prefs);
    expect(ranked.map((r) => r.id)).toEqual(["new", "old"]);
  });
});
