import { describe, it, expect } from "vitest";
import { buildChart, findPalaceByBranch } from "./engine";

describe("buildChart", () => {
  it("builds a Mệnh Thân chart for 1990-3-15 00:30 male solar", () => {
    const chart = buildChart({
      date: "1990-3-15",
      timeIndex: 0, // 23:00–01:00 early Tý
      gender: "Nam",
      calendar: "solar",
      fullName: "Nguyễn Văn A",
    });

    expect(chart.solarDate).toBe("1990-3-15");
    expect(chart.lunarDate).toContain("一九九〇年");
    expect(chart.zodiac).toBe("Ngựa");
    expect(chart.sign).toContain("Song Ngư");
    expect(chart.fiveElements).toBe("Thổ Ngũ Cục");
    expect(chart.soulStar).toBe("Văn Khúc");
    expect(chart.bodyStar).toBe("Hỏa Tinh");
    expect(chart.palaces).toHaveLength(12);

    // Body palace = Mệnh per iztro for this input
    const menh = chart.palaces.find((p) => p.name === "Mệnh");
    expect(menh).toBeDefined();
    expect(menh?.isBodyPalace).toBe(true);
    expect(menh?.earthlyBranch).toBe("Mão");
    expect(menh?.majorStars.map((s) => s.name).sort()).toEqual(["Cự Môn", "Thiên Cơ"]);
  });

  it("returns 12 distinct palaces, each with branch and stem", () => {
    const chart = buildChart({
      date: "1985-7-20",
      timeIndex: 6, // Ngọ
      gender: "Nữ",
      calendar: "solar",
    });

    const branches = chart.palaces.map((p) => p.earthlyBranch);
    expect(new Set(branches).size).toBe(12);
    chart.palaces.forEach((p) => {
      expect(p.heavenlyStem).toBeTruthy();
      expect(p.earthlyBranch).toBeTruthy();
      expect(p.name).toBeTruthy();
    });
  });

  it("findPalaceByBranch returns the right palace", () => {
    const chart = buildChart({
      date: "1990-3-15",
      timeIndex: 0,
      gender: "Nam",
      calendar: "solar",
    });
    const tý = findPalaceByBranch(chart, "Tý");
    expect(tý?.earthlyBranch).toBe("Tý");
    const undef = findPalaceByBranch(chart, "Tỵ");
    expect(undef?.earthlyBranch).toBe("Tỵ");
  });

  it("supports lunar input", () => {
    const chart = buildChart({
      date: "1990-2-19",
      timeIndex: 0,
      gender: "Nam",
      calendar: "lunar",
    });
    // 1990 lunar Feb 19 = solar 1990-3-15 — should match the solar test
    expect(chart.solarDate).toBe("1990-3-15");
    expect(chart.fiveElements).toBe("Thổ Ngũ Cục");
  });

  it("rejects invalid date format", () => {
    expect(() =>
      buildChart({
        date: "1990/03/15",
        timeIndex: 0,
        gender: "Nam",
        calendar: "solar",
      })
    ).toThrow(/định dạng/);
  });

  it("rejects out-of-range timeIndex", () => {
    expect(() =>
      buildChart({
        date: "1990-3-15",
        timeIndex: 13,
        gender: "Nam",
        calendar: "solar",
      })
    ).toThrow(/0\.\.12/);
  });
});
