import { Solar } from "lunar-javascript";
import {
  adjustToTrueSolarTime,
  formatDateTime,
  parseDateTime,
} from "@/lib/calc/time";

export interface BaziInput {
  date: string;
  time: string;
  gender: "male" | "female";
  longitude: number;
  unknownHour?: boolean;
}

export interface PillarInfo {
  ganZhi: string;
  shiShenGan: string;
  shiShenZhi: string[];
  hideGan: string[];
  naYin: string;
}

export interface DaYunInfo {
  ganZhi: string;
  startAge: number;
}

export interface BaziChart {
  birthTime: string;
  trueSolarTime: string;
  unknownHour: boolean;
  lunarDate: string;
  pillars: {
    year: PillarInfo;
    month: PillarInfo;
    day: PillarInfo;
    time: PillarInfo;
  };
  daYun: {
    startYear: number;
    startMonth: number;
    startDay: number;
    items: DaYunInfo[];
  };
  liuNian: { year: number; ganZhi: string }[];
  shenSha: {
    ji: string[];
    xiong: string[];
  };
}

function buildPillar(
  ganZhi: string,
  shiShenGan: string,
  shiShenZhi: string[],
  hideGan: string[],
  naYin: string,
): PillarInfo {
  return { ganZhi, shiShenGan, shiShenZhi, hideGan, naYin };
}

export function calculateBazi(input: BaziInput): BaziChart {
  const localTime = parseDateTime(input.date, input.time);
  const trueSolar = adjustToTrueSolarTime(localTime, input.longitude);

  const solar = Solar.fromYmdHms(
    trueSolar.getFullYear(),
    trueSolar.getMonth() + 1,
    trueSolar.getDate(),
    input.unknownHour ? 12 : trueSolar.getHours(),
    input.unknownHour ? 0 : trueSolar.getMinutes(),
    0,
  );

  const lunar = solar.getLunar();
  const ec = lunar.getEightChar();
  const genderCode = input.gender === "male" ? 1 : 0;
  const yun = ec.getYun(genderCode);

  const currentYear = new Date().getFullYear();
  const liuNian: { year: number; ganZhi: string }[] = [];
  for (let year = currentYear - 2; year <= currentYear + 3; year++) {
    const yearSolar = Solar.fromYmdHms(year, 6, 1, 12, 0, 0);
    liuNian.push({
      year,
      ganZhi: yearSolar.getLunar().getYearInGanZhi(),
    });
  }

  const daYunList = yun.getDaYun();
  const daYunItems: DaYunInfo[] = [];
  let age = yun.getStartYear();
  for (const dy of daYunList) {
    const gz = dy.getGanZhi();
    if (!gz) {
      continue;
    }
    daYunItems.push({ ganZhi: gz, startAge: age });
    age += 10;
    if (daYunItems.length >= 8) {
      break;
    }
  }

  return {
    birthTime: formatDateTime(localTime),
    trueSolarTime: formatDateTime(trueSolar),
    unknownHour: !!input.unknownHour,
    lunarDate: lunar.toString(),
    pillars: {
      year: buildPillar(
        ec.getYear(),
        ec.getYearShiShenGan(),
        ec.getYearShiShenZhi(),
        ec.getYearHideGan(),
        ec.getYearNaYin(),
      ),
      month: buildPillar(
        ec.getMonth(),
        ec.getMonthShiShenGan(),
        ec.getMonthShiShenZhi(),
        ec.getMonthHideGan(),
        ec.getMonthNaYin(),
      ),
      day: buildPillar(
        ec.getDay(),
        ec.getDayShiShenGan(),
        ec.getDayShiShenZhi(),
        ec.getDayHideGan(),
        ec.getDayNaYin(),
      ),
      time: buildPillar(
        input.unknownHour ? "不详" : ec.getTime(),
        input.unknownHour ? "—" : ec.getTimeShiShenGan(),
        input.unknownHour ? [] : ec.getTimeShiShenZhi(),
        input.unknownHour ? [] : ec.getTimeHideGan(),
        input.unknownHour ? "—" : ec.getTimeNaYin(),
      ),
    },
    daYun: {
      startYear: yun.getStartYear(),
      startMonth: yun.getStartMonth(),
      startDay: yun.getStartDay(),
      items: daYunItems,
    },
    liuNian,
    shenSha: {
      ji: lunar.getDayJiShen(),
      xiong: lunar.getDayXiongSha(),
    },
  };
}

export function formatBaziForPrompt(chart: BaziChart): string {
  const p = chart.pillars;
  const lines = [
    `出生时间：${chart.birthTime}`,
    `真太阳时：${chart.trueSolarTime}${chart.unknownHour ? "（时辰不详，按中午排盘）" : ""}`,
    `农历：${chart.lunarDate}`,
    "",
    "【四柱】",
    `年柱：${p.year.ganZhi}（天干十神：${p.year.shiShenGan}，地支十神：${p.year.shiShenZhi.join("、")}，藏干：${p.year.hideGan.join("、")}，纳音：${p.year.naYin}）`,
    `月柱：${p.month.ganZhi}（天干十神：${p.month.shiShenGan}，地支十神：${p.month.shiShenZhi.join("、")}，藏干：${p.month.hideGan.join("、")}，纳音：${p.month.naYin}）`,
    `日柱：${p.day.ganZhi}（天干十神：${p.day.shiShenGan}，地支十神：${p.day.shiShenZhi.join("、")}，藏干：${p.day.hideGan.join("、")}，纳音：${p.day.naYin}）`,
    `时柱：${p.time.ganZhi}（天干十神：${p.time.shiShenGan}，地支十神：${p.time.shiShenZhi.join("、") || "—"}，藏干：${p.time.hideGan.join("、") || "—"}，纳音：${p.time.naYin}）`,
    "",
    `【大运】起运 ${chart.daYun.startYear} 年 ${chart.daYun.startMonth} 月 ${chart.daYun.startDay} 天`,
    chart.daYun.items.map((d) => `${d.startAge}岁起 ${d.ganZhi}`).join(" → "),
    "",
    `【流年】${chart.liuNian.map((l) => `${l.year}(${l.ganZhi})`).join("、")}`,
    "",
    `【神煞】吉神：${chart.shenSha.ji.join("、") || "无"}；凶煞：${chart.shenSha.xiong.join("、") || "无"}`,
  ];
  return lines.join("\n");
}
