/**
 * Hợp tuổi — Vietnamese marriage / business compatibility scoring.
 *
 * Tổng hợp 4 yếu tố truyền thống:
 *   1. Thiên Can         (10 stems)  · 6 cặp xung
 *   2. Địa Chi           (12 chi)    · tam hợp / lục hợp / lục xung / lục hại
 *   3. Ngũ Hành Mệnh     (Nạp Âm)    · sinh, khắc, đồng
 *   4. Cung Phi Bát Trạch (Đông/Tây) · cùng nhóm = hợp
 *
 * Mỗi yếu tố cho điểm 0-25 → tổng 0-100. Có lý giải riêng cho từng yếu tố.
 *
 * Phạm vi: kết hôn, làm ăn, đối tác — cùng công thức nhưng trọng số khác.
 *   marriage: bằng nhau 25/25/25/25
 *   business: nặng Mệnh + Cung Phi (30/20/30/20)
 *   couple:   thiên Địa Chi + Mệnh (20/30/30/20)
 */

import { elementFromYear, type Element } from "@/lib/feng-shui/colors";
import { compat as branchCompat } from "@/lib/zodiac";

// 10 Thiên Can — Giáp Tý 1924 anchor
const STEMS = ["Giáp", "Ất", "Bính", "Đinh", "Mậu", "Kỷ", "Canh", "Tân", "Nhâm", "Quý"] as const;

// 12 Địa Chi — Tý anchor
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;

// Cặp xung Thiên Can: Giáp-Canh, Ất-Tân, Bính-Nhâm, Đinh-Quý, Mậu-Kỷ (đối nhau trong vòng 10)
const STEM_CLASH: Record<string, string> = {
  Giáp: "Canh",
  Canh: "Giáp",
  Ất: "Tân",
  Tân: "Ất",
  Bính: "Nhâm",
  Nhâm: "Bính",
  Đinh: "Quý",
  Quý: "Đinh",
};

// Element generation cycle: A sinh B
const SINH: Record<Element, Element> = {
  Kim: "Thuỷ",
  Thuỷ: "Mộc",
  Mộc: "Hoả",
  Hoả: "Thổ",
  Thổ: "Kim",
};

// Element conquest cycle: A khắc B
const KHAC: Record<Element, Element> = {
  Kim: "Mộc",
  Mộc: "Thổ",
  Thổ: "Thuỷ",
  Thuỷ: "Hoả",
  Hoả: "Kim",
};

// Cung phi bát trạch — Đông tứ mệnh / Tây tứ mệnh
type CungPhi = "Khảm" | "Ly" | "Chấn" | "Tốn" | "Càn" | "Khôn" | "Cấn" | "Đoài";
const DONG_TU_MENH: CungPhi[] = ["Khảm", "Ly", "Chấn", "Tốn"];

// Branch index 0=Tý, ..., 11=Hợi (slug map)
const BRANCH_SLUGS = [
  "ty",
  "suu",
  "dan",
  "mao",
  "thin",
  "ti",
  "ngo",
  "mui",
  "than",
  "dau",
  "tuat",
  "hoi",
] as const;

export type ZodiacSlug = (typeof BRANCH_SLUGS)[number];

export type Person = {
  year: number; // dương lịch
  gender: "nam" | "nu";
  name?: string;
};

export type CanChi = { stem: string; branch: string; branchSlug: ZodiacSlug };

export function canChiOfYear(year: number): CanChi {
  // 1924 = Giáp Tý → stem 0, branch 0
  const stemIdx = (((year - 1924) % 10) + 10) % 10;
  const branchIdx = (((year - 1924) % 12) + 12) % 12;
  return {
    stem: STEMS[stemIdx],
    branch: BRANCHES[branchIdx],
    branchSlug: BRANCH_SLUGS[branchIdx],
  };
}

/** Cung Phi calculation per Bát Trạch (1900-2099 simplified). */
export function cungPhiOf(year: number, gender: "nam" | "nu"): CungPhi {
  const sumDigits = (n: number): number => {
    while (n >= 10)
      n = String(n)
        .split("")
        .reduce((s, c) => s + Number(c), 0);
    return n;
  };
  const last2 = year % 100;
  const sum = sumDigits(last2);

  let v: number;
  if (year < 2000) {
    v = gender === "nam" ? 10 - sum : sum + 5;
  } else {
    v = gender === "nam" ? 9 - sum : sum + 6;
  }
  v = sumDigits(v);
  if (v === 5) v = gender === "nam" ? 2 : 8; // Trung cung quy định

  const map: Record<number, CungPhi> = {
    1: "Khảm",
    2: "Khôn",
    3: "Chấn",
    4: "Tốn",
    6: "Càn",
    7: "Đoài",
    8: "Cấn",
    9: "Ly",
  };
  return map[v] ?? "Khảm";
}

// ============================================================
// Sub-scorers — each returns { score: 0-25, reason: string }
// ============================================================

function stemScore(a: CanChi, b: CanChi): { score: number; reason: string } {
  if (STEM_CLASH[a.stem] === b.stem) {
    return {
      score: 5,
      reason: `Thiên Can ${a.stem}–${b.stem} xung khắc — dễ va chạm về quan điểm và cách hành xử.`,
    };
  }
  if (a.stem === b.stem) {
    return {
      score: 18,
      reason: `Cùng Thiên Can ${a.stem} — đồng điệu nhưng đôi khi thiếu sự bổ sung.`,
    };
  }
  return {
    score: 22,
    reason: `Thiên Can ${a.stem}–${b.stem} không xung không khắc — bình hòa.`,
  };
}

function branchScore(a: CanChi, b: CanChi): { score: number; reason: string } {
  const result = branchCompat(a.branchSlug, b.branchSlug);
  const map: Record<string, number> = {
    "Tam Hợp": 25,
    "Lục Hợp": 23,
    "Bình Hòa": 18,
    "Lục Hại": 10,
    "Lục Xung": 5,
  };
  return {
    score: map[result.level] ?? 18,
    reason: `Địa Chi ${a.branch}–${b.branch}: ${result.level} (${result.hint})`,
  };
}

function elementScore(
  year1: number,
  year2: number
): {
  score: number;
  reason: string;
  e1: Element;
  e2: Element;
} {
  const e1 = elementFromYear(year1);
  const e2 = elementFromYear(year2);
  if (e1 === e2) {
    return {
      score: 18,
      reason: `Cùng Mệnh ${e1} — vượng lẫn nhau, nhưng dễ thiếu yếu tố bổ sung.`,
      e1,
      e2,
    };
  }
  if (SINH[e1] === e2 || SINH[e2] === e1) {
    return {
      score: 25,
      reason: `${e1}–${e2} tương sinh — bổ trợ và nuôi dưỡng nhau.`,
      e1,
      e2,
    };
  }
  if (KHAC[e1] === e2 || KHAC[e2] === e1) {
    return {
      score: 8,
      reason: `${e1}–${e2} tương khắc — dễ kìm hãm năng lượng của nhau, cần Mệnh thứ ba điều hoà.`,
      e1,
      e2,
    };
  }
  return {
    score: 20,
    reason: `${e1}–${e2} bình hoà — không sinh không khắc.`,
    e1,
    e2,
  };
}

function cungPhiScore(
  year1: number,
  g1: "nam" | "nu",
  year2: number,
  g2: "nam" | "nu"
): {
  score: number;
  reason: string;
  c1: CungPhi;
  c2: CungPhi;
} {
  const c1 = cungPhiOf(year1, g1);
  const c2 = cungPhiOf(year2, g2);
  const sameGroup = DONG_TU_MENH.includes(c1) === DONG_TU_MENH.includes(c2);
  if (sameGroup) {
    return {
      score: 23,
      reason: `Cùng nhóm ${DONG_TU_MENH.includes(c1) ? "Đông Tứ Mệnh" : "Tây Tứ Mệnh"} — hợp về hướng nhà, hướng giường, hướng làm việc.`,
      c1,
      c2,
    };
  }
  return {
    score: 12,
    reason: `Khác nhóm Đông/Tây Tứ Mệnh — hướng tốt của một người là hướng xấu của người kia. Cần thiết kế nhà tinh tế khi sống chung.`,
    c1,
    c2,
  };
}

// ============================================================
// Public API
// ============================================================

export type Mode = "marriage" | "business" | "couple";

export type CompatReport = {
  mode: Mode;
  total: number; // 0-100
  rating: "Rất hợp" | "Hợp" | "Bình hòa" | "Cần lưu ý" | "Khắc kỵ";
  factors: Array<{ label: string; score: number; max: number; reason: string }>;
  hint: string;
};

export function compatReport(p1: Person, p2: Person, mode: Mode): CompatReport {
  const cc1 = canChiOfYear(p1.year);
  const cc2 = canChiOfYear(p2.year);

  const stem = stemScore(cc1, cc2);
  const branch = branchScore(cc1, cc2);
  const element = elementScore(p1.year, p2.year);
  const cungPhi = cungPhiScore(p1.year, p1.gender, p2.year, p2.gender);

  // Weighting: each factor scaled relative to max=25
  const weights: Record<Mode, [number, number, number, number]> = {
    marriage: [25, 25, 25, 25],
    business: [20, 20, 30, 30],
    couple: [20, 30, 30, 20],
  };
  const [wStem, wBranch, wElement, wCung] = weights[mode];
  const total = Math.round(
    (stem.score / 25) * wStem +
      (branch.score / 25) * wBranch +
      (element.score / 25) * wElement +
      (cungPhi.score / 25) * wCung
  );

  let rating: CompatReport["rating"] = "Bình hòa";
  if (total >= 85) rating = "Rất hợp";
  else if (total >= 70) rating = "Hợp";
  else if (total >= 55) rating = "Bình hòa";
  else if (total >= 40) rating = "Cần lưu ý";
  else rating = "Khắc kỵ";

  let hint = "";
  if (mode === "marriage") {
    hint =
      total >= 70
        ? "Cặp đôi có nền tảng tốt. Tập trung vun đắp tình cảm thay vì lo các yếu tố kỵ."
        : total >= 55
          ? "Mức trung bình — hôn nhân thành công phụ thuộc vào sự thấu hiểu hơn là tuổi tác."
          : "Có một số yếu tố khắc. Nên giải bằng phong thuỷ nhà ở, chọn ngày cưới hợp, và đặc biệt là sự kiên nhẫn.";
  } else if (mode === "business") {
    hint =
      total >= 70
        ? "Đối tác tiềm năng. Hợp tác dài hạn và chia sẻ tài nguyên thuận lợi."
        : total >= 55
          ? "Có thể hợp tác nhưng nên có quy chế rõ ràng và phân vai trò bù đắp."
          : "Cẩn trọng khi góp vốn lớn. Nên có hợp đồng pháp lý chặt chẽ và người trung gian.";
  } else {
    hint =
      total >= 70
        ? "Duyên phận sâu. Nuôi dưỡng bằng giao tiếp chân thành và thời gian chất lượng."
        : total >= 55
          ? "Tình cảm cần cố gắng từ cả hai. Hiểu nhau là chìa khoá."
          : "Có yếu tố khắc kỵ. Cân nhắc kỹ trước khi gắn bó dài hạn.";
  }

  return {
    mode,
    total,
    rating,
    factors: [
      { label: "Thiên Can", score: stem.score, max: 25, reason: stem.reason },
      { label: "Địa Chi", score: branch.score, max: 25, reason: branch.reason },
      {
        label: "Ngũ Hành Mệnh",
        score: element.score,
        max: 25,
        reason: element.reason,
      },
      {
        label: "Cung Phi (Bát Trạch)",
        score: cungPhi.score,
        max: 25,
        reason: cungPhi.reason,
      },
    ],
    hint,
  };
}
