/**
 * Kinh Dịch (I Ching) — gieo quẻ tam tiền (3-coin method).
 *
 * Mỗi lần gieo 3 đồng xu cho ra 1 hào (line):
 *   3 sấp           = 6 (Thái Âm) → âm động → biến hào
 *   2 ngửa 1 sấp    = 7 (Thiếu Dương) → dương tĩnh
 *   1 ngửa 2 sấp    = 8 (Thiếu Âm) → âm tĩnh
 *   3 ngửa          = 9 (Thái Dương) → dương động → biến hào
 *
 * Gieo 6 lần (từ dưới lên) tạo thành 1 quẻ chính (Original Hexagram).
 * Nếu có hào động → đảo bit để được quẻ biến (Changing Hexagram).
 *
 * Bảng 64 quẻ: index = upper * 8 + lower (Bát Quái 0-7).
 * Bát quái:  0=Càn(☰) 1=Đoài(☱) 2=Ly(☲) 3=Chấn(☳)
 *            4=Tốn(☴) 5=Khảm(☵) 6=Cấn(☶) 7=Khôn(☷)
 *
 * Các quẻ + tên Việt được giản lược (tên ngắn). Mục đích: hiển thị quẻ
 * chính + quẻ biến + 6 hào, không phải dịch toàn bộ Chu Dịch.
 */

export type CoinResult = "head" | "tail";
export type Line = 6 | 7 | 8 | 9;

const HEXAGRAMS_64: Array<{ name: string; vn: string; meaning: string }> = [
  // Upper 0 = Càn (Heaven)
  { name: "Qián", vn: "Càn", meaning: "Trời, sáng tạo, khởi đầu mạnh mẽ. Vận lớn." },
  { name: "Lǚ", vn: "Lý", meaning: "Bước cẩn thận, dè dặt qua nguy hiểm." },
  { name: "Tóngrén", vn: "Đồng Nhân", meaning: "Đồng tâm hiệp lực, giao tiếp." },
  { name: "Wúwàng", vn: "Vô Vọng", meaning: "Không vọng tưởng, hành động chân thành." },
  { name: "Gòu", vn: "Cấu", meaning: "Gặp gỡ bất ngờ, cần cảnh giác." },
  { name: "Sòng", vn: "Tụng", meaning: "Tranh chấp, kiện tụng. Tránh đối đầu." },
  { name: "Dùn", vn: "Độn", meaning: "Lui ẩn, rút lui khôn ngoan." },
  { name: "Pǐ", vn: "Bĩ", meaning: "Bế tắc, ngăn cách. Cần kiên nhẫn chờ thời." },
  // Upper 1 = Đoài (Lake)
  { name: "Guài", vn: "Quải", meaning: "Quyết liệt, đột phá vào thời điểm thích hợp." },
  { name: "Duì", vn: "Đoài", meaning: "Hồ nước, vui vẻ, giao tiếp lưu thông." },
  { name: "Gé", vn: "Cách", meaning: "Cải cách, thay đổi triệt để." },
  { name: "Suí", vn: "Tùy", meaning: "Theo thời, thuận theo dòng chảy." },
  { name: "Dàguò", vn: "Đại Quá", meaning: "Vượt mức, gánh nặng quá tải." },
  { name: "Kùn", vn: "Khốn", meaning: "Khó khăn, bế tắc. Giữ lòng tin." },
  { name: "Xián", vn: "Hàm", meaning: "Cảm ứng, gắn kết tự nhiên." },
  { name: "Cuì", vn: "Tụy", meaning: "Tụ hội, đoàn kết." },
  // Upper 2 = Ly (Fire)
  { name: "Dàyǒu", vn: "Đại Hữu", meaning: "Có nhiều của cải, dồi dào." },
  { name: "Kuí", vn: "Khuê", meaning: "Đối lập, cách biệt. Nhìn nhau qua khoảng cách." },
  { name: "Lí", vn: "Ly", meaning: "Lửa, sáng tỏ, gắn kết. Phụ thuộc." },
  { name: "Shìhé", vn: "Phệ Hạp", meaning: "Cắn xé, phá rào cản. Pháp luật." },
  { name: "Dǐng", vn: "Đỉnh", meaning: "Vạc nấu, kiến tạo, đổi mới văn hoá." },
  { name: "Wèijì", vn: "Vị Tế", meaning: "Chưa thành. Còn việc phải làm." },
  { name: "Lǚ", vn: "Lữ", meaning: "Lữ hành, du lịch, ngụ cư." },
  { name: "Jìn", vn: "Tấn", meaning: "Tiến tới, thăng tiến." },
  // Upper 3 = Chấn (Thunder)
  { name: "Dàzhuàng", vn: "Đại Tráng", meaning: "Mạnh mẽ, hành động dũng cảm." },
  { name: "Guīmèi", vn: "Quy Muội", meaning: "Cô gái về nhà chồng, kết duyên." },
  { name: "Fēng", vn: "Phong", meaning: "Phong phú, dồi dào nhưng đỉnh điểm." },
  { name: "Zhèn", vn: "Chấn", meaning: "Sấm động, kích thích, đánh thức." },
  { name: "Héng", vn: "Hằng", meaning: "Bền vững, kiên định lâu dài." },
  { name: "Jiě", vn: "Giải", meaning: "Tan rã, giải toả. Vấn đề được hoá giải." },
  { name: "Xiǎoguò", vn: "Tiểu Quá", meaning: "Vượt nhỏ, sai lệch ít. Khiêm nhường." },
  { name: "Yú", vn: "Dự", meaning: "Vui vẻ, hứng khởi. Chuẩn bị tốt." },
  // Upper 4 = Tốn (Wind)
  { name: "Xiǎochù", vn: "Tiểu Súc", meaning: "Tích lũy nhỏ, chờ thời." },
  { name: "Zhōngfú", vn: "Trung Phu", meaning: "Lòng tin sâu sắc giữa lòng." },
  { name: "Jiārén", vn: "Gia Nhân", meaning: "Gia đình hoà thuận." },
  { name: "Yì", vn: "Ích", meaning: "Tăng lên, có lợi." },
  { name: "Xùn", vn: "Tốn", meaning: "Gió, thấm dần, ảnh hưởng nhẹ nhàng." },
  { name: "Huàn", vn: "Hoán", meaning: "Phân tán, giải toả khí trệ." },
  { name: "Jiàn", vn: "Tiệm", meaning: "Tiến từng bước, tăng trưởng dần." },
  { name: "Guān", vn: "Quan", meaning: "Quan sát, nhìn xa." },
  // Upper 5 = Khảm (Water)
  { name: "Xū", vn: "Nhu", meaning: "Chờ đợi, kiên nhẫn." },
  { name: "Jié", vn: "Tiết", meaning: "Tiết chế, hạn chế đúng mức." },
  { name: "Jìjì", vn: "Ký Tế", meaning: "Đã thành. Hoàn thành. Cẩn thận giữ vững." },
  { name: "Tún", vn: "Truân", meaning: "Khởi đầu khó khăn." },
  { name: "Jǐng", vn: "Tỉnh", meaning: "Giếng nước, nguồn nuôi dưỡng." },
  { name: "Kǎn", vn: "Khảm", meaning: "Hố hiểm, vượt qua khó khăn." },
  { name: "Jiǎn", vn: "Kiển", meaning: "Khập khiễng, khó đi tiếp." },
  { name: "Bǐ", vn: "Tỉ", meaning: "Hợp tác, gắn bó." },
  // Upper 6 = Cấn (Mountain)
  { name: "Dàchù", vn: "Đại Súc", meaning: "Tích lớn, lưu giữ tài năng." },
  { name: "Sǔn", vn: "Tổn", meaning: "Tổn hại, hi sinh để lợi lâu dài." },
  { name: "Bēn", vn: "Bí", meaning: "Trang trí, làm đẹp bề ngoài." },
  { name: "Yí", vn: "Di", meaning: "Nuôi dưỡng, ăn uống điều độ." },
  { name: "Gǔ", vn: "Cổ", meaning: "Sửa chữa cái cũ hỏng." },
  { name: "Méng", vn: "Mông", meaning: "Khai mở trí tuệ, dạy dỗ." },
  { name: "Gèn", vn: "Cấn", meaning: "Núi tĩnh, dừng lại đúng lúc." },
  { name: "Bō", vn: "Bác", meaning: "Bị tước đoạt, suy thoái." },
  // Upper 7 = Khôn (Earth)
  { name: "Tài", vn: "Thái", meaning: "Hanh thông lớn, thuận lợi." },
  { name: "Línlín", vn: "Lâm", meaning: "Đến gần, tiếp cận." },
  { name: "Míngyí", vn: "Minh Di", meaning: "Ánh sáng bị che, ẩn tài chờ thời." },
  { name: "Fù", vn: "Phục", meaning: "Quay về, khôi phục năng lượng." },
  { name: "Shēng", vn: "Thăng", meaning: "Đi lên, thăng tiến chậm mà chắc." },
  { name: "Shī", vn: "Sư", meaning: "Quân đội, lãnh đạo có kỷ luật." },
  { name: "Qiān", vn: "Khiêm", meaning: "Khiêm nhường, đại cát." },
  { name: "Kūn", vn: "Khôn", meaning: "Đất, dung chứa, nuôi dưỡng vạn vật." },
];

const TRIGRAM_NAMES = ["Càn", "Đoài", "Ly", "Chấn", "Tốn", "Khảm", "Cấn", "Khôn"];

/** Cast a single line by flipping 3 coins. */
export function castLine(): { line: Line; coins: CoinResult[] } {
  const coins: CoinResult[] = [
    Math.random() < 0.5 ? "head" : "tail",
    Math.random() < 0.5 ? "head" : "tail",
    Math.random() < 0.5 ? "head" : "tail",
  ];
  const heads = coins.filter((c) => c === "head").length;
  const sum: Line = heads === 0 ? 6 : heads === 1 ? 7 : heads === 2 ? 8 : 9;
  return { line: sum, coins };
}

/** Convert lines (bottom→top) to upper/lower trigram indices and hex name. */
export function hexagramFromLines(lines: Line[]): {
  hexagramIndex: number;
  name: string;
  vn: string;
  meaning: string;
  upper: string;
  lower: string;
  changing: number[]; // 0-based indices of changing lines
} {
  if (lines.length !== 6) throw new Error("Need exactly 6 lines");

  // Static value of each line (yin=0, yang=1) for the original hexagram.
  // 6 (Thái Âm động) = yin; 7 = yang; 8 = yin; 9 (Thái Dương động) = yang
  const orig = lines.map((l) => (l === 7 || l === 9 ? 1 : 0));
  const lower = orig.slice(0, 3).reverse(); // bottom 3 lines, top→bottom
  const upper = orig.slice(3, 6).reverse();
  const lowerIdx = upper.length === 3 ? lower[0] * 4 + lower[1] * 2 + lower[2] : 0;
  const upperIdx = upper[0] * 4 + upper[1] * 2 + upper[2];

  // King Wen ordering convention varies; use upper*8+lower for consistent output
  const hexIdx = upperIdx * 8 + lowerIdx;
  const hex = HEXAGRAMS_64[hexIdx] ?? HEXAGRAMS_64[0];

  const changing: number[] = [];
  lines.forEach((l, i) => {
    if (l === 6 || l === 9) changing.push(i);
  });

  return {
    hexagramIndex: hexIdx,
    name: hex.name,
    vn: hex.vn,
    meaning: hex.meaning,
    upper: TRIGRAM_NAMES[upperIdx] ?? "",
    lower: TRIGRAM_NAMES[lowerIdx] ?? "",
    changing,
  };
}

/** Build a full reading from a question. Includes the changing hexagram. */
export function castReading(): {
  lines: Line[];
  original: ReturnType<typeof hexagramFromLines>;
  changed?: ReturnType<typeof hexagramFromLines>;
} {
  const lines: Line[] = [];
  for (let i = 0; i < 6; i++) lines.push(castLine().line);
  const original = hexagramFromLines(lines);

  if (original.changing.length === 0) {
    return { lines, original };
  }

  // Flip changing lines to get the new hexagram
  const flipped: Line[] = lines.map((l) => {
    if (l === 6) return 7; // yin động → yang tĩnh
    if (l === 9) return 8; // yang động → yin tĩnh
    return l;
  });
  const changed = hexagramFromLines(flipped);
  return { lines, original, changed };
}
