import { describe, it, expect } from "vitest";
import {
  buildFlyingStarChart,
  centerStarOfYear,
  findCellByDirection,
  getStarInfo,
} from "./flying-stars";

describe("centerStarOfYear", () => {
  it("returns known center stars per year", () => {
    expect(centerStarOfYear(2024)).toBe(3);
    expect(centerStarOfYear(2025)).toBe(2);
    expect(centerStarOfYear(2026)).toBe(1);
    expect(centerStarOfYear(2027)).toBe(9);
    expect(centerStarOfYear(2028)).toBe(8);
    expect(centerStarOfYear(2029)).toBe(7);
    expect(centerStarOfYear(2030)).toBe(6);
    expect(centerStarOfYear(2031)).toBe(5);
    expect(centerStarOfYear(2032)).toBe(4);
    expect(centerStarOfYear(2033)).toBe(3);
  });

  it("cycles correctly for past years", () => {
    expect(centerStarOfYear(2023)).toBe(4);
    expect(centerStarOfYear(2020)).toBe(7);
    expect(centerStarOfYear(2015)).toBe(3);
  });
});

describe("buildFlyingStarChart", () => {
  it("when 5 is in center (year 2031), grid is Lo Shu base", () => {
    const chart = buildFlyingStarChart(2031);
    expect(chart.centerStar).toBe(5);
    // Lo Shu: ĐN=4 N=9 TN=2 / Đ=3 TC=5 T=7 / ĐB=8 B=1 TB=6
    expect(findCellByDirection(chart, "Đông Nam")?.star.number).toBe(4);
    expect(findCellByDirection(chart, "Nam")?.star.number).toBe(9);
    expect(findCellByDirection(chart, "Tây Nam")?.star.number).toBe(2);
    expect(findCellByDirection(chart, "Đông")?.star.number).toBe(3);
    expect(findCellByDirection(chart, "Trung cung")?.star.number).toBe(5);
    expect(findCellByDirection(chart, "Tây")?.star.number).toBe(7);
    expect(findCellByDirection(chart, "Đông Bắc")?.star.number).toBe(8);
    expect(findCellByDirection(chart, "Bắc")?.star.number).toBe(1);
    expect(findCellByDirection(chart, "Tây Bắc")?.star.number).toBe(6);
  });

  it("year 2026: 1 nhập trung cung — verify all 9 cells", () => {
    const chart = buildFlyingStarChart(2026);
    expect(chart.centerStar).toBe(1);
    // 1 vào trung, sao 5 chuyển ra TB (vì 6→7 đẩy chuỗi)
    // Công thức: cellStar = ((loShu + 1 - 6) mod 9) + 1 = ((loShu - 5) mod 9) + 1
    // Lo Shu - 5 mod 9: 4→8, 9→4, 2→6, 3→7, 5→0→9... wait check
    // ĐN: ((4 - 5 + 1 - 1) mod 9) + 1 = ((-1) mod 9) + 1 = 8 + 1 = 9
    // Nam: ((9 - 5 + 0) mod 9) + 1 = 4 + 1 = 5
    // TN: ((2 - 5) mod 9) + 1 = (-3 mod 9) + 1 = 6 + 1 = 7
    // Đ: ((3 - 5) mod 9) + 1 = -2+9 → 7+1=8
    // TC: ((5 - 5) mod 9) + 1 = 0 + 1 = 1
    // T: ((7 - 5) mod 9) + 1 = 2+1 = 3
    // ĐB: ((8 - 5) mod 9) + 1 = 3+1 = 4
    // B: ((1 - 5) mod 9) + 1 = (-4+9)+1 = 5+1 = 6
    // TB: ((6 - 5) mod 9) + 1 = 1+1 = 2
    expect(findCellByDirection(chart, "Đông Nam")?.star.number).toBe(9);
    expect(findCellByDirection(chart, "Nam")?.star.number).toBe(5);
    expect(findCellByDirection(chart, "Tây Nam")?.star.number).toBe(7);
    expect(findCellByDirection(chart, "Đông")?.star.number).toBe(8);
    expect(findCellByDirection(chart, "Trung cung")?.star.number).toBe(1);
    expect(findCellByDirection(chart, "Tây")?.star.number).toBe(3);
    expect(findCellByDirection(chart, "Đông Bắc")?.star.number).toBe(4);
    expect(findCellByDirection(chart, "Bắc")?.star.number).toBe(6);
    expect(findCellByDirection(chart, "Tây Bắc")?.star.number).toBe(2);
  });

  it("each chart has exactly 9 unique stars", () => {
    for (const year of [2024, 2025, 2026, 2027, 2030, 2035]) {
      const chart = buildFlyingStarChart(year);
      const nums = new Set(chart.cells.map((c) => c.star.number));
      expect(nums.size).toBe(9);
      expect([...nums].sort()).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]);
    }
  });

  it("center cell direction is Trung cung", () => {
    const chart = buildFlyingStarChart(2026);
    const center = chart.cells[4];
    expect(center.direction).toBe("Trung cung");
    expect(center.star.number).toBe(chart.centerStar);
  });
});

describe("getStarInfo", () => {
  it("star 5 is Ngũ Hoàng Liêm Trinh", () => {
    const s = getStarInfo(5);
    expect(s.name).toBe("Ngũ Hoàng");
    expect(s.tone).toBe("very-bad");
    expect(s.element).toBe("Thổ");
  });

  it("star 8 is Bát Bạch — great wealth", () => {
    const s = getStarInfo(8);
    expect(s.name).toBe("Bát Bạch");
    expect(s.tone).toBe("great");
  });

  it("star 9 is Cửu Tử — đương vận", () => {
    const s = getStarInfo(9);
    expect(s.name).toBe("Cửu Tử");
    expect(s.tone).toBe("great");
    expect(s.element).toBe("Hỏa");
  });
});
