"use client";

import { useState } from "react";
import { readStreamableValue } from "ai/rsc";
import { Compass } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import Result from "@/components/result";
import ResultAI from "@/components/result-ai";
import BaziChartDisplay from "@/components/modes/bazi-chart";
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 { getCombinedAnswer } from "@/app/actions/combined";
import { ERROR_PREFIX } from "@/lib/constant";

export default function CombinedForm() {
  const [birthDate, setBirthDate] = useState("1990-01-01");
  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 [guaData, setGuaData] = useState<GuaResult | null>(null);

  const [chart, setChart] = useState<BaziChart | null>(null);
  const [completion, setCompletion] = useState("");
  const [error, setError] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const [showAi, setShowAi] = useState(false);

  const birthLocation = useRegionLocation(birthProvince, birthCity);
  const currentLocation = useRegionLocation(currentProvince, currentCity);
  const hexagramReady =
    !withHexagram ||
    (question.trim() !== "" && currentLocation !== null && guaData !== null);

  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,
      }),
    );
    setShowAi(false);
    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);
    setShowAi(true);

    try {
      const { data, error: apiError } = await getCombinedAnswer({
        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,
      });

      if (apiError) {
        setError(apiError);
        return;
      }
      if (data) {
        let ret = "";
        for await (const delta of readStreamableValue(data)) {
          if (typeof delta === "string" && delta.startsWith(ERROR_PREFIX)) {
            setError(delta.slice(ERROR_PREFIX.length));
            return;
          }
          ret += delta ?? "";
          setCompletion(ret);
        }
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setIsLoading(false);
    }
  }

  return (
    <div className="flex flex-1 flex-col gap-4 px-4 py-6">
      <div className="mx-auto w-full max-w-lg space-y-6">
        <section className="space-y-3">
          <h2 className="text-sm font-semibold text-primary">人和 · 生辰八字</h2>
          <DateTimePicker
            label="出生日期 / 时间"
            date={birthDate}
            time={birthTime}
            timeDisabled={unknownHour}
            onDateChange={setBirthDate}
            onTimeChange={setBirthTime}
          />
          <label className="flex items-center gap-2 text-xs text-muted-foreground">
            <input
              type="checkbox"
              checked={unknownHour}
              onChange={(e) => setUnknownHour(e.target.checked)}
            />
            时辰不详
          </label>
          <div className="flex gap-4">
            {(["male", "female"] as const).map((g) => (
              <label key={g} className="flex items-center gap-2 text-sm">
                <input
                  type="radio"
                  name="combined-gender"
                  checked={gender === g}
                  onChange={() => setGender(g)}
                />
                {g === "male" ? "男" : "女"}
              </label>
            ))}
          </div>
          <RegionSelect
            label="出生地域"
            provinceCode={birthProvince}
            cityCode={birthCity}
            onProvinceChange={setBirthProvince}
            onCityChange={setBirthCity}
          />
        </section>

        <section className="space-y-3">
          <h2 className="text-sm font-semibold text-primary">地利 · 当前位置</h2>
          <RegionSelect
            label="所在地域"
            provinceCode={currentProvince}
            cityCode={currentCity}
            onProvinceChange={setCurrentProvince}
            onCityChange={setCurrentCity}
          />
        </section>

        <section className="space-y-3">
          <h2 className="text-sm font-semibold text-primary">天时 · 测算时刻</h2>
          <DateTimePicker
            label="日期 / 时间"
            date={calcDate}
            time={calcTime}
            onDateChange={setCalcDate}
            onTimeChange={setCalcTime}
          />
        </section>

        <section className="space-y-3">
          <h2 className="text-sm font-semibold text-primary">问事</h2>
          <Textarea
            placeholder="具体所求..."
            value={question}
            onChange={(e) => setQuestion(e.target.value)}
            rows={3}
          />
        </section>

        <section className="space-y-3">
          <label className="flex items-center gap-2 text-sm font-medium">
            <input
              type="checkbox"
              checked={withHexagram}
              onChange={(e) => {
                setWithHexagram(e.target.checked);
                setGuaData(null);
                setShowAi(false);
              }}
            />
            附加六爻（可选）
          </label>
          {withHexagram && (
            <div className="space-y-3 rounded-md border p-3">
              <div className="flex gap-2">
                <Button
                  type="button"
                  size="sm"
                  variant={castMode === "online" ? "default" : "outline"}
                  onClick={() => {
                    setCastMode("online");
                    setGuaData(null);
                  }}
                >
                  线上摇卦
                </Button>
                <Button
                  type="button"
                  size="sm"
                  variant={castMode === "offline" ? "default" : "outline"}
                  onClick={() => {
                    setCastMode("offline");
                    setGuaData(null);
                  }}
                >
                  线下录入
                </Button>
              </div>
              <HexagramInput
                key={castMode}
                mode={castMode}
                enabled={question.trim() !== "" && currentLocation !== null}
                onResult={setGuaData}
                onClear={() => setGuaData(null)}
              />
              {guaData && (
                <div className="rounded-md border bg-card p-3">
                  <Result {...guaData.result} />
                </div>
              )}
            </div>
          )}
        </section>

        {error && !showAi && (
          <p className="text-sm text-destructive">{error}</p>
        )}

        <div className="flex gap-2">
          <Button variant="outline" onClick={handlePreview} className="flex-1">
            预览排盘
          </Button>
          <Button
            onClick={handleAnalyze}
            disabled={withHexagram && !hexagramReady}
            className="flex-1"
          >
            <Compass size={16} className="mr-1" />
            综合测算
          </Button>
        </div>
      </div>

      {chart && (
        <div className="mx-auto w-full max-w-lg">
          <BaziChartDisplay chart={chart} />
        </div>
      )}

      {showAi && (
        <div className="mx-auto h-96 w-full max-w-lg flex-1">
          <ResultAI
            completion={completion}
            isLoading={isLoading}
            onCompletion={handleAnalyze}
            error={error}
          />
        </div>
      )}
    </div>
  );
}
