"use client"; import { useEffect, useState } from "react"; import { bool } from "aimless.js"; import Coin from "@/components/coin"; import Hexagram from "@/components/hexagram"; import { Button } from "@/components/ui/button"; import { buildHexagramList, COIN_OPTIONS, computeGuaResult, type GuaResult, YAO_LABELS, } from "@/lib/calc/hexagram"; const AUTO_DELAY = 600; interface HexagramInputProps { mode: "online" | "offline"; enabled: boolean; onResult: (data: GuaResult) => void; onClear: () => void; } export default function HexagramInput({ mode, enabled, onResult, onClear, }: HexagramInputProps) { const [frontList, setFrontList] = useState([true, true, true]); const [rotation, setRotation] = useState(false); const [hexagramList, setHexagramList] = useState< GuaResult["list"] >([]); const [count, setCount] = useState(0); const [offlineCounts, setOfflineCounts] = useState<(number | null)[]>( Array(6).fill(null), ); useEffect(() => { setHexagramList([]); setCount(0); setOfflineCounts(Array(6).fill(null)); setRotation(false); }, [mode]); useEffect(() => { if ( mode !== "online" || !enabled || rotation || hexagramList.length >= 6 || count >= 6 ) { return; } const timer = setTimeout(startOnlineCast, AUTO_DELAY); return () => clearTimeout(timer); }, [mode, enabled, rotation, count, hexagramList.length]); function finishList(list: GuaResult["list"]) { const result = computeGuaResult(list); if (result) { onResult({ list, result }); } } function onTransitionEnd() { setRotation(false); const frontCount = frontList.reduce( (acc, val) => (val ? acc + 1 : acc), 0, ); setHexagramList((list) => { const newList = [ ...list, { change: frontCount === 0 || frontCount === 3, yang: frontCount >= 2, separate: list.length === 3, }, ]; if (newList.length === 6) { finishList(newList); } return newList; }); } function startOnlineCast() { if (rotation || !enabled || hexagramList.length >= 6) { return; } setFrontList([bool(), bool(), bool()]); setRotation(true); setCount((c) => c + 1); } function handleOfflineSelect(index: number, frontCount: number) { const next = [...offlineCounts]; next[index] = frontCount; setOfflineCounts(next); } function confirmOffline() { if (offlineCounts.some((v) => v === null)) { return; } const list = buildHexagramList(offlineCounts as number[]); finishList(list); setHexagramList(list); } function handleReset() { setHexagramList([]); setCount(0); setOfflineCounts(Array(6).fill(null)); setRotation(false); onClear(); } const complete = hexagramList.length === 6; const offlineReady = offlineCounts.every((v) => v !== null); if (!enabled) { return (
请先填写问事、地域和起卦时辰
); } return (人工抛铜钱后,按从下到上(初爻→上爻)录入每爻结果
{YAO_LABELS.map((label, index) => (六爻已齐,请在下方点击「AI 解读」
> )}