"use client";

import { useState } from "react";
import { readStreamableValue } from "ai/rsc";
import { Compass, ListRestart } 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 DateTimePicker, {
  nowDateString,
  nowTimeString,
} from "@/components/shared/datetime-picker";
import HexagramInput from "@/components/shared/hexagram-input";
import RegionSelect, {
  useRegionLocation,
} from "@/components/shared/region-select";
import { getLiuyaoAnswer } from "@/app/actions/liuyao";
import type { GuaResult } from "@/lib/calc/hexagram";
import { ERROR_PREFIX } from "@/lib/constant";
import todayJson from "@/lib/data/today.json";

const todayData: string[] = todayJson;

export default function LiuyaoForm() {
  const [question, setQuestion] = useState("");
  const [provinceCode, setProvinceCode] = useState("");
  const [cityCode, setCityCode] = useState("");
  const [calcDate, setCalcDate] = useState(nowDateString);
  const [calcTime, setCalcTime] = useState(nowTimeString);
  const [castMode, setCastMode] = useState<"online" | "offline">("online");
  const [guaData, setGuaData] = useState<GuaResult | null>(null);
  const [completion, setCompletion] = useState("");
  const [error, setError] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const [showAi, setShowAi] = useState(false);

  const location = useRegionLocation(provinceCode, cityCode);
  const formReady = question.trim() !== "" && location !== null;

  function validate(): string | null {
    if (!question.trim()) {
      return "请输入问事";
    }
    if (!location) {
      return "请选择起卦地域";
    }
    if (!guaData) {
      return "请先完成起卦（线上摇卦或线下录入）";
    }
    return null;
  }

  async function handleAnalyze() {
    const err = validate();
    if (err) {
      setError(err);
      return;
    }

    setError("");
    setCompletion("");
    setIsLoading(true);
    setShowAi(true);

    try {
      const { data, error: apiError } = await getLiuyaoAnswer({
        question,
        calcDate,
        calcTime,
        locationName: location!.name,
        longitude: location!.longitude,
        guaMark: guaData!.result.guaMark,
        guaTitle: guaData!.result.guaTitle,
        guaResult: guaData!.result.guaResult,
        guaChange: guaData!.result.guaChange,
      });

      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);
    }
  }

  function handleReset() {
    setQuestion("");
    setProvinceCode("");
    setCityCode("");
    setCalcDate(nowDateString());
    setCalcTime(nowTimeString());
    setGuaData(null);
    setCompletion("");
    setError("");
    setShowAi(false);
    setIsLoading(false);
  }

  function handleGuaResult(data: GuaResult) {
    setGuaData(data);
    setShowAi(false);
    setCompletion("");
  }

  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-5">
        <section className="space-y-2">
          <label className="text-sm font-medium">问事</label>
          <Textarea
            placeholder="您想算点什么？"
            value={question}
            onChange={(e) => setQuestion(e.target.value)}
            rows={3}
          />
          <div className="flex flex-wrap gap-2">
            {todayData.map((item, index) => (
              <button
                key={index}
                type="button"
                onClick={() => setQuestion(item)}
                className="rounded-md border bg-secondary px-2 py-1 text-xs text-muted-foreground transition hover:bg-accent"
              >
                {item}
              </button>
            ))}
          </div>
        </section>

        <RegionSelect
          label="起卦地域"
          provinceCode={provinceCode}
          cityCode={cityCode}
          onProvinceChange={setProvinceCode}
          onCityChange={setCityCode}
        />

        <DateTimePicker
          label="起卦时辰"
          date={calcDate}
          time={calcTime}
          onDateChange={setCalcDate}
          onTimeChange={setCalcTime}
        />

        <section className="space-y-2">
          <label className="text-sm font-medium">起卦方式</label>
          <div className="flex gap-2">
            <Button
              type="button"
              size="sm"
              variant={castMode === "online" ? "default" : "outline"}
              onClick={() => {
                setCastMode("online");
                setGuaData(null);
                setShowAi(false);
              }}
            >
              线上摇卦
            </Button>
            <Button
              type="button"
              size="sm"
              variant={castMode === "offline" ? "default" : "outline"}
              onClick={() => {
                setCastMode("offline");
                setGuaData(null);
                setShowAi(false);
              }}
            >
              线下录入
            </Button>
          </div>
        </section>

        <HexagramInput
          key={castMode}
          mode={castMode}
          enabled={formReady}
          onResult={handleGuaResult}
          onClear={() => setGuaData(null)}
        />

        {guaData && (
          <div className="rounded-lg border bg-card p-4">
            <Result {...guaData.result} />
          </div>
        )}

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

        <div className="flex gap-2">
          <Button variant="outline" onClick={handleReset} className="flex-1">
            <ListRestart size={16} className="mr-1" />
            重来
          </Button>
          <Button
            onClick={handleAnalyze}
            disabled={!guaData || isLoading}
            className="flex-1"
          >
            <Compass size={16} className="mr-1" />
            测算
          </Button>
        </div>
      </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>
  );
}
