/**
 * Tử Vi Số · Vietnamese traditional "hạn" (annual omens) helpers.
 *
 * Computes the five hạn most consulted in Vietnamese folk astrology when
 * planning weddings, building houses, or starting businesses:
 *
 *   - Tam Tai (Three Disasters): a 3-year band tied to the native's
 *     birth-branch trine (Tam Hợp). Triggered when the year-branch lands
 *     in the trine's "tail" branches.
 *   - Kim Lâu: a 4-mod-9 cycle on Vietnamese age (tuổi mụ). Splits into
 *     Kim Lâu Thân / Thê / Tử / Lục Súc — each phá in a different domain.
 *   - Hoàng Ốc: a 6-mod cycle on age. Six labels alternate between
 *     auspicious and inauspicious for building/repairing the house.
 *   - Tang Môn / Tuế Phá: branch positions relative to the year's branch.
 *     Both sit at fixed offsets from Thái Tuế and indicate funeral-omen
 *     and break-omen years respectively.
 *
 * All formulas follow the standard popular references (Lịch Vạn Sự,
 * Tuvico, Lịch Vạn Niên VN). They are deterministic and easily testable.
 */

export type Gender = "Nam" | "Nữ";

const BRANCHES = [
  "Tý",
  "Sửu",
  "Dần",
  "Mão",
  "Thìn",
  "Tỵ",
  "Ngọ",
  "Mùi",
  "Thân",
  "Dậu",
  "Tuất",
  "Hợi",
] as const;
export type Branch = (typeof BRANCHES)[number];

/** branch index 0..11 with Tý=0 (zodiac order, NOT iztro Dần-first). */
function branchIndex(b: string): number {
  const i = BRANCHES.indexOf(b as Branch);
  if (i < 0) throw new Error(`Branch không hợp lệ: ${b}`);
  return i;
}

// ---------- Tam Tai ----------

/**
 * Tam Tai map (per popular VN reference):
 *   - Thân-Tý-Thìn → Tam Tai năm Dần, Mão, Thìn
 *   - Dần-Ngọ-Tuất → Tam Tai năm Thân, Dậu, Tuất
 *   - Hợi-Mão-Mùi → Tam Tai năm Tỵ, Ngọ, Mùi
 *   - Tỵ-Dậu-Sửu → Tam Tai năm Hợi, Tý, Sửu
 *
 * Returned `position` indicates the year within the 3-year band:
 *   1 = first year (nhập Tam Tai — chưa nặng)
 *   2 = peak year (giữa Tam Tai — nặng nhất)
 *   3 = exit year (xuất Tam Tai — đã nhẹ)
 */
const TAM_TAI_MAP: Record<Branch, { years: [Branch, Branch, Branch] }> = {
  Thân: { years: ["Dần", "Mão", "Thìn"] },
  Tý: { years: ["Dần", "Mão", "Thìn"] },
  Thìn: { years: ["Dần", "Mão", "Thìn"] },

  Dần: { years: ["Thân", "Dậu", "Tuất"] },
  Ngọ: { years: ["Thân", "Dậu", "Tuất"] },
  Tuất: { years: ["Thân", "Dậu", "Tuất"] },

  Hợi: { years: ["Tỵ", "Ngọ", "Mùi"] },
  Mão: { years: ["Tỵ", "Ngọ", "Mùi"] },
  Mùi: { years: ["Tỵ", "Ngọ", "Mùi"] },

  Tỵ: { years: ["Hợi", "Tý", "Sửu"] },
  Dậu: { years: ["Hợi", "Tý", "Sửu"] },
  Sửu: { years: ["Hợi", "Tý", "Sửu"] },
};

export type TamTaiResult =
  | { active: false }
  | {
      active: true;
      /** 1 = first, 2 = peak, 3 = exit */
      position: 1 | 2 | 3;
      label: string;
    };

export function computeTamTai(birthBranch: string, yearBranch: string): TamTaiResult {
  const map = TAM_TAI_MAP[birthBranch as Branch];
  if (!map) return { active: false };
  const i = map.years.indexOf(yearBranch as Branch);
  if (i < 0) return { active: false };
  const labels = ["Nhập Tam Tai", "Chính Tam Tai", "Xuất Tam Tai"] as const;
  return { active: true, position: (i + 1) as 1 | 2 | 3, label: labels[i] };
}

// ---------- Kim Lâu ----------

/**
 * Kim Lâu — based on age%9 ∈ {1, 3, 6, 8}.
 *   - 1 → Kim Lâu Thân (tổn thân chủ)
 *   - 3 → Kim Lâu Thê (tổn vợ/chồng)
 *   - 6 → Kim Lâu Tử (tổn con cái)
 *   - 8 → Kim Lâu Lục Súc (tổn gia súc / tài sản)
 *
 * Vietnamese folk practice phạm Kim Lâu các tuổi 12, 15, 19, 21, 24, 26,
 * 28, 30, 33, 35, 37 ... (trừ một số tuổi <=10 không xét).
 */
export type KimLauResult =
  | { active: false }
  | {
      active: true;
      kind: "Thân" | "Thê" | "Tử" | "Lục Súc";
      label: string;
    };

export function computeKimLau(age: number): KimLauResult {
  if (age <= 0) return { active: false };
  const m = age % 9;
  if (m === 1) return { active: true, kind: "Thân", label: "Kim Lâu Thân" };
  if (m === 3) return { active: true, kind: "Thê", label: "Kim Lâu Thê" };
  if (m === 6) return { active: true, kind: "Tử", label: "Kim Lâu Tử" };
  if (m === 8) return { active: true, kind: "Lục Súc", label: "Kim Lâu Lục Súc" };
  return { active: false };
}

// ---------- Hoàng Ốc ----------

/**
 * Hoàng Ốc — 6-cycle on age, starting at age 10. Sequence repeats:
 *   10→Nhất Cát · 11→Nhì Nghi · 12→Tam Địa Sát · 13→Tứ Tấn Tài
 *   · 14→Ngũ Thọ Tử · 15→Lục Hoang Ốc · 16→Nhất Cát ...
 *
 * Cát (good): Nhất Cát, Nhì Nghi, Tứ Tấn Tài.
 * Hung (bad): Tam Địa Sát, Ngũ Thọ Tử, Lục Hoang Ốc.
 */
export type HoangOcResult = {
  label: string;
  good: boolean;
  index: number;
};

const HOANG_OC_LABELS = [
  { label: "Nhất Cát", good: true },
  { label: "Nhì Nghi", good: true },
  { label: "Tam Địa Sát", good: false },
  { label: "Tứ Tấn Tài", good: true },
  { label: "Ngũ Thọ Tử", good: false },
  { label: "Lục Hoang Ốc", good: false },
];

export function computeHoangOc(age: number): HoangOcResult {
  // popular convention: count from age 10
  const offset = Math.max(0, age - 10);
  const index = offset % 6;
  const entry = HOANG_OC_LABELS[index];
  return { label: entry.label, good: entry.good, index };
}

// ---------- Tang Môn / Tuế Phá / Thái Tuế ----------

/**
 * Position helpers anchored on the year's earthly branch.
 *   - Thái Tuế: same branch as year
 *   - Tang Môn: +2 (theo thuận chi)
 *   - Tuế Phá: +6 (đối xung với Thái Tuế)
 *
 * Year is "phạm" if the native's birth-branch lands at the same position.
 */
export type FixedHan = {
  /** Tên hạn */
  name: string;
  /** Branch the hạn falls on this year */
  branch: string;
  /** True nếu phạm — tức trùng với chi sinh của native */
  active: boolean;
};

function offsetBranch(yearBranch: string, offset: number): string {
  const yi = branchIndex(yearBranch);
  return BRANCHES[(yi + offset + 12) % 12];
}

export function computeFixedHan(birthBranch: string, yearBranch: string): FixedHan[] {
  const thaiTue = yearBranch;
  const tangMon = offsetBranch(yearBranch, 2);
  const tuePha = offsetBranch(yearBranch, 6);
  return [
    { name: "Thái Tuế", branch: thaiTue, active: birthBranch === thaiTue },
    { name: "Tang Môn", branch: tangMon, active: birthBranch === tangMon },
    { name: "Tuế Phá", branch: tuePha, active: birthBranch === tuePha },
  ];
}

// ---------- aggregate ----------

export type AnnualHanReport = {
  /** Vietnamese age (tuổi mụ) the report is for */
  age: number;
  /** Branch của năm xem (e.g. "Ngọ") */
  yearBranch: string;
  /** Branch sinh của native */
  birthBranch: string;
  tamTai: TamTaiResult;
  kimLau: KimLauResult;
  hoangOc: HoangOcResult;
  fixed: FixedHan[];
  /** True nếu có ÍT NHẤT một hạn xấu phạm trong năm */
  hasBadHan: boolean;
};

export function buildAnnualHanReport(args: {
  birthBranch: string;
  yearBranch: string;
  age: number;
}): AnnualHanReport {
  const tamTai = computeTamTai(args.birthBranch, args.yearBranch);
  const kimLau = computeKimLau(args.age);
  const hoangOc = computeHoangOc(args.age);
  const fixed = computeFixedHan(args.birthBranch, args.yearBranch);
  const hasBadHan =
    (tamTai.active && tamTai.position === 2) ||
    kimLau.active ||
    !hoangOc.good ||
    fixed.some((f) => f.active && f.name !== "Thái Tuế");
  return {
    age: args.age,
    yearBranch: args.yearBranch,
    birthBranch: args.birthBranch,
    tamTai,
    kimLau,
    hoangOc,
    fixed,
    hasBadHan,
  };
}
