"use client"; import { useEffect, useState } from "react"; import { Compass } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { ZenCard } from "@/components/ui/zen-card"; import { ModeWorkspace } from "@/components/layout/mode-workspace"; import Result from "@/components/result"; import ResultAI from "@/components/result-ai"; import BaziChartDisplay from "@/components/modes/bazi-chart"; import LunarBirthPicker, { todaySolarYmd, } from "@/components/shared/lunar-birth-picker"; import DateTimePicker, { nowDateString, nowTimeString, } from "@/components/shared/datetime-picker"; import HexagramInput from "@/components/shared/hexagram-input"; import RegionSelect, { useRegionLocation, } from "@/components/shared/region-select"; import { calculateBazi, type BaziChart } from "@/lib/calc/bazi"; import type { GuaResult } from "@/lib/calc/hexagram"; import { streamAiCompletion } from "@/lib/ai/client-stream"; import { saveHistoryEntry } from "@/lib/history/storage"; export default function CombinedForm() { const [birthDate, setBirthDate] = useState(todaySolarYmd()); const [birthTime, setBirthTime] = useState("12:00"); const [unknownHour, setUnknownHour] = useState(false); const [gender, setGender] = useState<"male" | "female">("male"); const [birthProvince, setBirthProvince] = useState(""); const [birthCity, setBirthCity] = useState(""); const [currentProvince, setCurrentProvince] = useState(""); const [currentCity, setCurrentCity] = useState(""); const [calcDate, setCalcDate] = useState(nowDateString); const [calcTime, setCalcTime] = useState(nowTimeString); const [question, setQuestion] = useState(""); const [withHexagram, setWithHexagram] = useState(false); const [castMode, setCastMode] = useState<"online" | "offline">("online"); const [castActive, setCastActive] = useState(false); const [guaData, setGuaData] = useState(null); const [chart, setChart] = useState(null); const [completion, setCompletion] = useState(""); const [error, setError] = useState(""); const [isLoading, setIsLoading] = useState(false); const birthLocation = useRegionLocation(birthProvince, birthCity); const currentLocation = useRegionLocation(currentProvince, currentCity); const hexagramReady = !withHexagram || (question.trim() !== "" && currentLocation !== null && guaData !== null); useEffect(() => { setCastActive(false); setGuaData(null); }, [currentProvince, currentCity, castMode, question, withHexagram]); function validate(): string | null { if (!birthLocation) { return "请选择出生地域"; } if (!currentLocation) { return "请选择当前所在地域"; } if (!question.trim()) { return "请输入问事内容"; } if (withHexagram && !guaData) { return "请完成六爻起卦,或取消附加六爻"; } return null; } function handlePreview() { const err = validate(); if (err) { setError(err); return; } setError(""); setChart( calculateBazi({ date: birthDate, time: unknownHour ? "12:00" : birthTime, gender, longitude: birthLocation!.longitude, unknownHour, }), ); setCompletion(""); } async function handleAnalyze() { const err = validate(); if (err) { setError(err); return; } if (!chart) { setChart( calculateBazi({ date: birthDate, time: unknownHour ? "12:00" : birthTime, gender, longitude: birthLocation!.longitude, unknownHour, }), ); } setError(""); setCompletion(""); setIsLoading(true); const activeChart = chart ?? calculateBazi({ date: birthDate, time: unknownHour ? "12:00" : birthTime, gender, longitude: birthLocation!.longitude, unknownHour, }); try { const text = await streamAiCompletion( { mode: "combined", payload: { birth: { date: birthDate, time: unknownHour ? "12:00" : birthTime, gender, longitude: birthLocation!.longitude, unknownHour, }, birthPlaceName: birthLocation!.name, currentPlaceName: currentLocation!.name, currentLongitude: currentLocation!.longitude, calcDate, calcTime, question, hexagram: withHexagram && guaData ? { guaMark: guaData.result.guaMark, guaTitle: guaData.result.guaTitle, guaResult: guaData.result.guaResult, guaChange: guaData.result.guaChange, } : undefined, }, }, setCompletion, ); await saveHistoryEntry({ mode: "combined", title: "综合测算解读", question, summary: activeChart.lunarDate, completion: text, baziInput: { date: birthDate, time: unknownHour ? "12:00" : birthTime, gender, longitude: birthLocation!.longitude, unknownHour, birthPlaceName: birthLocation!.name, }, baziChart: activeChart, hexagram: withHexagram && guaData ? { guaMark: guaData.result.guaMark, guaTitle: guaData.result.guaTitle, guaResult: guaData.result.guaResult, guaChange: guaData.result.guaChange, } : undefined, meta: { 出生地域: birthLocation!.name, 当前地域: currentLocation!.name, 测算时间: `${calcDate} ${calcTime}`, 农历: activeChart.lunarDate, 性别: gender === "male" ? "男" : "女", 四柱: `${activeChart.pillars.year.ganZhi} ${activeChart.pillars.month.ganZhi} ${activeChart.pillars.day.ganZhi} ${activeChart.pillars.time.ganZhi}`, 六爻: withHexagram && guaData ? guaData.result.guaTitle : "无", }, }); } catch (e) { setError(e instanceof Error ? e.message : String(e)); } finally { setIsLoading(false); } } const downloadPreamble = completion && birthLocation && currentLocation ? `# 综合测算 AI 解读\n\n- 问事:${question}\n- 出生地域:${birthLocation.name}\n- 当前地域:${currentLocation.name}\n- 测算时间:${calcDate} ${calcTime}\n${chart ? `- 农历:${chart.lunarDate}\n` : ""}${withHexagram && guaData ? `- 六爻:${guaData.result.guaTitle}\n` : ""}` : undefined; return ( } >
{(["male", "female"] as const).map((g) => ( ))}