"use client";
import { useEffect, useReducer, useRef, useState } from "react";
import {
  ArrowLeft,
  ArrowRight,
  BarChart3,
  Check,
  ChevronRight,
  Dumbbell,
  Flame,
  Play,
  RotateCcw,
  Timer,
  TrendingUp,
  User,
  X,
  Zap,
} from "lucide-react";
import {
  exercises,
  initialState,
  isComplete,
  restoreState,
  trainingReducer,
  type TrainingState,
} from "./session";
import styles from "./jinjie.module.css";
const STORAGE = "ui-lab:jinjie:1";
export function Jinjie({
  initialScreen = "home",
  persist = true,
}: {
  initialScreen?: TrainingState["screen"];
  persist?: boolean;
}) {
  const [state, dispatch] = useReducer(
    trainingReducer,
    initialScreen,
    initialState,
  );
  const [ready, setReady] = useState(false);
  const [weight, setWeight] = useState("30");
  const [reps, setReps] = useState("8");
  const [rir, setRir] = useState(2);
  const [rest, setRest] = useState(90);
  const [seconds, setSeconds] = useState(0);
  const [dialog, setDialog] = useState<
    "tips" | "exit" | "details" | "reset" | null
  >(null);
  const [storageError, setStorageError] = useState(false);
  const dialogRef = useRef<HTMLDialogElement>(null);
  const canPersist = persist && initialScreen === "home";
  // Seed previews never write to or read the real demo session.
  const [restored, setRestored] = useState<TrainingState | null>(null);
  useEffect(() => {
    if (canPersist) {
      try {
        setRestored(restoreState(localStorage.getItem(STORAGE)));
      } catch {
        setStorageError(true);
      }
    }
    setReady(true);
  }, [canPersist]);
  const active = restored ?? state;
  function act(action: Parameters<typeof trainingReducer>[1]) {
    if (restored) setRestored(trainingReducer(restored, action));
    else dispatch(action);
  }
  useEffect(() => {
    if (ready && canPersist) {
      try {
        localStorage.setItem(STORAGE, JSON.stringify(active));
      } catch {
        setStorageError(true);
      }
    }
  }, [active, ready, canPersist]);
  useEffect(() => {
    const tick = () =>
      setSeconds(
        active.restUntil
          ? Math.max(0, Math.ceil((active.restUntil - Date.now()) / 1000))
          : 0,
      );
    tick();
    const timer = window.setInterval(tick, 500);
    return () => window.clearInterval(timer);
  }, [active.restUntil]);
  useEffect(() => {
    if (dialog) dialogRef.current?.showModal();
    else dialogRef.current?.close();
  }, [dialog]);
  const session = active.session;
  const records = session?.records ?? [];
  const currentRecords = records.filter((r) => r.exercise === active.exercise);
  const complete = isComplete(session);
  const week = Math.min(4, 3 + active.completedIds.length);
  const previewComplete = session?.demo && active.screen === "complete";
  const shownWeek = previewComplete ? 4 : week;
  const minutes =
    session?.endedAt !== undefined
      ? Math.max(1, Math.round((session.endedAt - session.startedAt) / 60000))
      : 0;
  const start = () => {
    act({ type: "start", now: Date.now(), id: crypto.randomUUID() });
    setWeight("30");
    setReps("8");
    setRir(2);
  };
  const valid =
    weight.trim() !== "" &&
    reps.trim() !== "" &&
    Number.isFinite(Number(weight)) &&
    Number(weight) >= 0 &&
    Number(weight) <= 500 &&
    Number.isInteger(Number(reps)) &&
    Number(reps) >= 1 &&
    Number(reps) <= 100;
  return (
    <div className={styles.app}>
      <div className={styles.statusbar}>
        <span>9:41</span>
        <div className={styles.statusIcons}>
          <span>▮▮▮</span>
          <span>◔</span>
          <span className={styles.battery} />
        </div>
      </div>
      <div className={styles.demo}>
        {initialScreen !== "home"
          ? "独立演示 · 预置示例状态"
          : "进阶 · 本地演示数据"}
      </div>
      {!ready ? (
        <main className={styles.main}>
          <p>正在载入训练…</p>
        </main>
      ) : (
        <>
          {active.screen === "home" && (
            <>
              <main className={`${styles.main} ${styles.homeMain}`}>
                <header className={styles.homeHeader}>
                  <span className={styles.brand}>
                    <span className={styles.brandMark}>↗</span> 进阶
                  </span>
                  <span className={styles.avatar}>J</span>
                </header>
                {active.tab === "training" && (
                  <>
                    <p className={styles.eyebrow}>每一次训练，都算数</p>
                    <h1>
                      今天，
                      <br />
                      练得更好<span className={styles.green}>。</span>
                    </h1>
                    <div className={styles.week}>
                      <div>
                        <span>本周训练</span>
                        <strong>已完成 {week} / 4 次</strong>
                      </div>
                      <div className={styles.days}>
                        {["一", "二", "三", "四", "五", "六", "日"].map(
                          (day, i) => (
                            <span
                              key={day}
                              className={i < week ? styles.dayDone : ""}
                            >
                              {i < week ? <Check size={15} /> : day}
                            </span>
                          ),
                        )}
                      </div>
                    </div>
                    <div className={styles.plan}>
                      <div className={styles.planTop}>
                        <span>
                          <Flame size={14} /> 今日计划
                        </span>
                        <span>力量训练</span>
                      </div>
                      <h2>胸肩增肌</h2>
                      <p>4 个动作 · 12 组 · 预计 50 分钟</p>
                      <div className={styles.equipment} aria-hidden="true">
                        <Dumbbell size={100} strokeWidth={1.1} />
                      </div>
                      <div className={styles.planFoot}>
                        <span>上肢训练 / Upper body</span>
                        <ArrowRight size={20} />
                      </div>
                    </div>
                    <div className={styles.sectionTitle}>
                      <h3>训练动作</h3>
                      <span>4 个动作</span>
                    </div>
                    <div className={styles.exerciseList}>
                      {exercises.map((e, i) => (
                        <div className={styles.exerciseRow} key={e.name}>
                          <span className={styles.exerciseIcon}>
                            <Dumbbell size={21} />
                          </span>
                          <div>
                            <strong>{e.name}</strong>
                            <span>
                              {e.muscle} · {e.sets} 组 × 8–12 次
                            </span>
                          </div>
                          <span className={styles.rowNumber}>
                            {String(i + 1).padStart(2, "0")}
                          </span>
                        </div>
                      ))}
                    </div>
                    <button className={styles.primary} onClick={start}>
                      <Play size={18} fill="currentColor" />
                      开始训练
                    </button>
                    <p className={styles.helper}>专注于今天的自己。</p>
                  </>
                )}
                {active.tab === "progress" && (
                  <>
                    <p className={styles.eyebrow}>坚持，正在发生</p>
                    <h1>看见你的进步</h1>
                    <div className={styles.week}>
                      <span>本周训练</span>
                      <h2>
                        {week} <small>/ 4 次</small>
                      </h2>
                    </div>
                    <Chart last={week} />
                    <div className={styles.note}>
                      <TrendingUp size={24} />
                      <h3>每一组，都是积累</h3>
                      <p>
                        本次演示已完成 {active.completedIds.length}{" "}
                        次完整训练。历史三周为示例数据。
                      </p>
                    </div>
                  </>
                )}
                {active.tab === "profile" && (
                  <>
                    <p className={styles.eyebrow}>以自己的节奏前进</p>
                    <h1>我的训练空间</h1>
                    <div className={styles.note}>
                      <User size={32} />
                      <h2>训练者 J</h2>
                      <p>个人演示档案 · 胸肩增肌计划</p>
                      <p>
                        数据只保存在当前浏览器，没有账号，也不会上传。此模板用于界面演示，不构成训练建议。
                      </p>
                    </div>
                    <button
                      className={styles.secondary}
                      onClick={() => setDialog("reset")}
                    >
                      <RotateCcw size={18} />
                      重置演示数据
                    </button>
                  </>
                )}
              </main>
              <nav className={styles.nav} aria-label="训练导航">
                {(
                  [
                    { id: "training", name: "训练", Icon: Dumbbell },
                    { id: "progress", name: "进步", Icon: BarChart3 },
                    { id: "profile", name: "我的", Icon: User },
                  ] as const
                ).map(({ id, name, Icon }) => (
                  <button
                    key={id}
                    aria-current={active.tab === id ? "page" : undefined}
                    onClick={() => act({ type: "tab", tab: id })}
                  >
                    <Icon size={22} />
                    {name}
                  </button>
                ))}
              </nav>
            </>
          )}
          {active.screen === "workout" && (
            <main className={`${styles.main} ${styles.workoutMain}`}>
              <div className={styles.workoutHeader}>
                <button aria-label="退出训练" onClick={() => setDialog("exit")}>
                  <ArrowLeft size={21} />
                </button>
                <span>训练进行中</span>
                <button
                  onClick={() => act({ type: "finish", now: Date.now() })}
                >
                  结束
                </button>
              </div>
              <div className={styles.progressBars}>
                {exercises.map((e, i) => (
                  <span
                    key={e.name}
                    style={{
                      background:
                        i === active.exercise
                          ? "#C9F36A"
                          : records.filter((r) => r.exercise === i).length ===
                              e.sets
                            ? "#647b36"
                            : undefined,
                    }}
                  />
                ))}
              </div>
              <div className={styles.sectionTitle}>
                <span className={styles.green}>
                  动作 {active.exercise + 1} / 4
                </span>
                <label className={styles.switchLabel}>
                  切换动作
                  <select
                    aria-label="切换动作"
                    value={active.exercise}
                    onChange={(e) =>
                      act({ type: "exercise", index: Number(e.target.value) })
                    }
                  >
                    {exercises.map((e, i) => (
                      <option key={e.name} value={i}>
                        {e.name}
                      </option>
                    ))}
                  </select>
                </label>
              </div>
              <h1 className={styles.workoutTitle}>
                {exercises[active.exercise].name}
              </h1>
              <p className={styles.subtitle}>重量按单只计算</p>
              <div className={styles.setTable}>
                <div className={styles.tableHead}>
                  <span>组数</span>
                  <span>重量 × 次数</span>
                  <span>RIR</span>
                  <span>状态</span>
                </div>
                {Array.from(
                  { length: exercises[active.exercise].sets },
                  (_, i) => {
                    const r = currentRecords[i];
                    return (
                      <div
                        key={i}
                        className={`${styles.tableRow} ${!r && i === currentRecords.length ? styles.currentRow : ""}`}
                      >
                        <span>{String(i + 1).padStart(2, "0")}</span>
                        <span>
                          {r
                            ? `${r.weight} kg × ${r.reps}`
                            : i === currentRecords.length
                              ? "当前组"
                              : "—"}
                        </span>
                        <span>{r ? (r.rir === 4 ? "4+" : r.rir) : "—"}</span>
                        <span>
                          {r ? (
                            <Check size={16} />
                          ) : i === currentRecords.length ? (
                            <span className={styles.dot} />
                          ) : (
                            <span className={styles.emptyDot} />
                          )}
                        </span>
                      </div>
                    );
                  },
                )}
              </div>
              {complete ? (
                <div className={styles.note}>
                  <Check size={32} />
                  <h2>12 组，全部完成</h2>
                  <p>做得很好，收下今天的进步。</p>
                  <button
                    className={styles.primary}
                    onClick={() => act({ type: "finish", now: Date.now() })}
                  >
                    完成训练
                    <ArrowRight size={19} />
                  </button>
                </div>
              ) : (
                <>
                  <div className={styles.sectionTitle}>
                    <h3>
                      记录第{" "}
                      {Math.min(
                        currentRecords.length + 1,
                        exercises[active.exercise].sets,
                      )}{" "}
                      组
                    </h3>
                    <span>{records.length} / 12 组</span>
                  </div>
                  <div className={styles.inputs}>
                    <label>
                      重量 <span>kg</span>
                      <input
                        aria-label="重量 kg"
                        type="number"
                        inputMode="decimal"
                        min="0"
                        max="500"
                        step="0.5"
                        value={weight}
                        onChange={(e) => setWeight(e.target.value)}
                      />
                    </label>
                    <label>
                      次数 <span>次</span>
                      <input
                        aria-label="次数"
                        type="number"
                        inputMode="numeric"
                        min="1"
                        max="100"
                        value={reps}
                        onChange={(e) => setReps(e.target.value)}
                      />
                    </label>
                  </div>
                  <div className={styles.sectionTitle}>
                    <h3>这一组，还能做几次？</h3>
                  </div>
                  <div
                    className={styles.rir}
                    role="group"
                    aria-label="RIR 选择"
                  >
                    {[0, 1, 2, 3, 4].map((v) => (
                      <button
                        key={v}
                        aria-pressed={rir === v}
                        onClick={() => setRir(v)}
                      >
                        {v === 4 ? "4+" : v}
                      </button>
                    ))}
                  </div>
                  <p className={styles.helper}>RIR：还能完成的次数</p>
                  <label className={styles.restSetting}>
                    <span>
                      <Timer size={17} />
                      组间休息
                    </span>
                    <select
                      aria-label="休息时间"
                      value={rest}
                      onChange={(e) => setRest(Number(e.target.value))}
                    >
                      <option value={30}>30 秒</option>
                      <option value={60}>60 秒</option>
                      <option value={90}>90 秒</option>
                      <option value={120}>120 秒</option>
                    </select>
                  </label>
                  {!valid && (
                    <p className={styles.error} role="alert">
                      请输入 0–500 kg 的重量和 1–100 的整数次数。
                    </p>
                  )}
                  <button
                    className={styles.primary}
                    disabled={
                      !valid ||
                      seconds > 0 ||
                      currentRecords.length >= exercises[active.exercise].sets
                    }
                    onClick={() =>
                      act({
                        type: "record",
                        record: {
                          weight: Number(weight),
                          reps: Number(reps),
                          rir,
                        },
                        now: Date.now(),
                        rest,
                      })
                    }
                  >
                    <Check size={20} />
                    记录本组
                  </button>
                </>
              )}
              <button
                className={styles.textButton}
                onClick={() => setDialog("tips")}
              >
                查看动作要点
                <ChevronRight size={16} />
              </button>
              {seconds > 0 && (
                <div className={styles.restOverlay}>
                  <div className={styles.restCard} role="status">
                    <Timer size={26} />
                    <h2>休息一下，继续变强</h2>
                    <span className={styles.countdown}>
                      {Math.floor(seconds / 60)}:
                      {String(seconds % 60).padStart(2, "0")}
                    </span>
                    <p>下一组，保持专注。</p>
                    <button
                      className={styles.primary}
                      onClick={() => act({ type: "skip-rest" })}
                    >
                      跳过休息
                      <ArrowRight size={18} />
                    </button>
                  </div>
                </div>
              )}
            </main>
          )}
          {active.screen === "complete" && (
            <main className={`${styles.main} ${styles.complete}`}>
              <div className={styles.finishMark}>
                <Check size={38} strokeWidth={2.5} />
              </div>
              <p className={styles.eyebrow}>
                {complete ? "训练完成" : "本次训练已结束"}
              </p>
              <h1>
                {complete ? (
                  <>
                    今天又
                    <br />
                    前进了一步<span className={styles.green}>。</span>
                  </>
                ) : (
                  <>
                    每一组努力，
                    <br />
                    都值得记录。
                  </>
                )}
              </h1>
              <p className={styles.subtitle}>
                胸肩增肌 · {session?.demo ? "完整示例" : "本次实际记录"}
              </p>
              <div className={styles.stats}>
                <div>
                  <strong>
                    {new Set(records.map((r) => r.exercise)).size}
                  </strong>
                  <span>个动作</span>
                </div>
                <div>
                  <strong>{records.length}</strong>
                  <span>组训练</span>
                </div>
                <div>
                  <strong>{minutes}</strong>
                  <span>分钟</span>
                </div>
              </div>
              <div className={styles.completedWeek}>
                <span>
                  <Flame size={18} />
                  本周进度
                </span>
                <strong>已完成 {shownWeek} / 4 次</strong>
              </div>
              <div className={styles.highlight}>
                <span>
                  <Zap size={16} />
                  关键记录
                </span>
                <h3>
                  {records[0]
                    ? exercises[records[0].exercise].name
                    : "尚未记录训练组"}
                </h3>
                <strong>
                  {records[0]
                    ? `单只 ${records[0].weight}kg × ${records[0].reps} 次`
                    : "下次从第一组开始"}
                </strong>
              </div>
              <Chart last={shownWeek} />
              <button
                className={styles.primary}
                onClick={() => act({ type: "return" })}
              >
                完成并返回
                <ArrowRight size={19} />
              </button>
              <button
                className={styles.textButton}
                onClick={() => setDialog("details")}
              >
                查看训练详情
                <ChevronRight size={16} />
              </button>
              {!complete && (
                <p className={styles.helper}>
                  未完成全部 12 组，本周完成次数未增加。
                </p>
              )}
            </main>
          )}
        </>
      )}
      {storageError && (
        <p className={styles.error} role="status">
          浏览器存储不可用，本次记录仅在页面内保留。
        </p>
      )}
      <dialog
        ref={dialogRef}
        className={styles.dialog}
        onCancel={() => setDialog(null)}
        onClick={(e) => {
          if (e.target === e.currentTarget) setDialog(null);
        }}
      >
        <div className={styles.dialogHead}>
          <h2>
            {dialog === "tips"
              ? "动作要点"
              : dialog === "exit"
                ? "退出本次训练？"
                : dialog === "reset"
                  ? "重置演示数据？"
                  : "本次训练详情"}
          </h2>
          <button aria-label="关闭弹窗" onClick={() => setDialog(null)}>
            <X size={20} />
          </button>
        </div>
        {dialog === "tips" && <p>{exercises[active.exercise].cue}</p>}
        {dialog === "exit" && (
          <>
            <p>
              已记录的组会保留。重新开始训练会创建新的会话，本周完成次数不会增加。
            </p>
            <button
              className={styles.primary}
              onClick={() => {
                act({ type: "exit" });
                setDialog(null);
              }}
            >
              确认退出
            </button>
          </>
        )}
        {dialog === "reset" && (
          <>
            <p>
              清除本浏览器的演示会话与完成次数，回到本周 3 / 4
              次。此操作无法撤销。
            </p>
            <button
              className={styles.primary}
              onClick={() => {
                act({ type: "reset" });
                setDialog(null);
              }}
            >
              确认重置
            </button>
          </>
        )}
        {dialog === "details" && (
          <div>
            {records.length === 0 ? (
              <p>本次没有记录训练组。</p>
            ) : (
              exercises.map((e, i) => (
                <div key={e.name}>
                  <h3>{e.name}</h3>
                  {records
                    .filter((r) => r.exercise === i)
                    .map((r, j) => (
                      <p key={j}>
                        第 {j + 1} 组 · {r.weight} kg × {r.reps} 次 · RIR{" "}
                        {r.rir === 4 ? "4+" : r.rir}
                      </p>
                    ))}
                </div>
              ))
            )}
          </div>
        )}
      </dialog>
    </div>
  );
}
function Chart({ last }: { last: number }) {
  return (
    <div className={styles.chart}>
      <div className={styles.sectionTitle}>
        <h3>稳定，比完美更重要</h3>
        <span>最近四周</span>
      </div>
      <div className={styles.bars}>
        {[3, 3, 4, last].map((n, i) => (
          <div key={i}>
            <span>{n}</span>
            <i
              style={{
                height: `${n * 12}px`,
                background: i === 3 ? "#C9F36A" : undefined,
              }}
            />
            <small>{["三周前", "两周前", "上周", "本周"][i]}</small>
          </div>
        ))}
      </div>
    </div>
  );
}
