/**
 * useExamStateMachine Hook 测试
 *
 * 测试考试状态机的状态流转：
 * NotStarted → InProgress → AutoSaving → Submitting → Submitted
 * 验证合法转移与非法转移拒绝。
 */

import { describe, it, expect } from "vitest";
import { renderHook, act } from "@testing-library/react";
import { useExamStateMachine } from "./use-exam-state-machine";

describe("useExamStateMachine", () => {
  it("初始状态应为 NotStarted", () => {
    const { result } = renderHook(() => useExamStateMachine());
    expect(result.current.state).toBe("NotStarted");
  });

  it("初始时 canSubmit 应为 false", () => {
    const { result } = renderHook(() => useExamStateMachine());
    expect(result.current.canSubmit).toBe(false);
  });

  describe("合法状态转移", () => {
    it("start: NotStarted → InProgress", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
      });
      expect(result.current.state).toBe("InProgress");
      expect(result.current.canSubmit).toBe(true);
    });

    it("beginAutoSave: InProgress → AutoSaving", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginAutoSave();
      });
      expect(result.current.state).toBe("AutoSaving");
      expect(result.current.canSubmit).toBe(true);
    });

    it("endAutoSave: AutoSaving → InProgress", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginAutoSave();
        result.current.actions.endAutoSave();
      });
      expect(result.current.state).toBe("InProgress");
    });

    it("beginSubmit: InProgress → Submitting", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginSubmit();
      });
      expect(result.current.state).toBe("Submitting");
      expect(result.current.canSubmit).toBe(false);
    });

    it("beginSubmit: AutoSaving → Submitting", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginAutoSave();
        result.current.actions.beginSubmit();
      });
      expect(result.current.state).toBe("Submitting");
    });

    it("completeSubmit: Submitting → Submitted", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginSubmit();
        result.current.actions.completeSubmit();
      });
      expect(result.current.state).toBe("Submitted");
      expect(result.current.canSubmit).toBe(false);
    });

    it("完整流程: NotStarted → InProgress → AutoSaving → InProgress → Submitting → Submitted", () => {
      const { result } = renderHook(() => useExamStateMachine());

      act(() => result.current.actions.start());
      expect(result.current.state).toBe("InProgress");

      act(() => result.current.actions.beginAutoSave());
      expect(result.current.state).toBe("AutoSaving");

      act(() => result.current.actions.endAutoSave());
      expect(result.current.state).toBe("InProgress");

      act(() => result.current.actions.beginSubmit());
      expect(result.current.state).toBe("Submitting");

      act(() => result.current.actions.completeSubmit());
      expect(result.current.state).toBe("Submitted");
    });
  });

  describe("非法状态转移（应保持原状态）", () => {
    it("NotStarted 时 beginAutoSave 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.beginAutoSave();
      });
      expect(result.current.state).toBe("NotStarted");
    });

    it("NotStarted 时 endAutoSave 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.endAutoSave();
      });
      expect(result.current.state).toBe("NotStarted");
    });

    it("NotStarted 时 beginSubmit 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.beginSubmit();
      });
      expect(result.current.state).toBe("NotStarted");
    });

    it("NotStarted 时 completeSubmit 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.completeSubmit();
      });
      expect(result.current.state).toBe("NotStarted");
    });

    it("InProgress 时 start 应无效果（不能重复 start）", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
      });
      expect(result.current.state).toBe("InProgress");
      act(() => {
        result.current.actions.start();
      });
      expect(result.current.state).toBe("InProgress");
    });

    it("InProgress 时 endAutoSave 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.endAutoSave();
      });
      expect(result.current.state).toBe("InProgress");
    });

    it("InProgress 时 completeSubmit 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.completeSubmit();
      });
      expect(result.current.state).toBe("InProgress");
    });

    it("AutoSaving 时 start 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginAutoSave();
        result.current.actions.start();
      });
      expect(result.current.state).toBe("AutoSaving");
    });

    it("AutoSaving 时 endAutoSave 后再 endAutoSave 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginAutoSave();
        result.current.actions.endAutoSave();
        result.current.actions.endAutoSave();
      });
      expect(result.current.state).toBe("InProgress");
    });

    it("Submitting 时 start 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginSubmit();
        result.current.actions.start();
      });
      expect(result.current.state).toBe("Submitting");
    });

    it("Submitting 时 beginAutoSave 应无效果", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginSubmit();
        result.current.actions.beginAutoSave();
      });
      expect(result.current.state).toBe("Submitting");
    });

    it("Submitted 时 start 应无效果（终态）", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginSubmit();
        result.current.actions.completeSubmit();
        result.current.actions.start();
      });
      expect(result.current.state).toBe("Submitted");
    });

    it("Submitted 时 beginSubmit 应无效果（终态）", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginSubmit();
        result.current.actions.completeSubmit();
        result.current.actions.beginSubmit();
      });
      expect(result.current.state).toBe("Submitted");
    });
  });

  describe("canSubmit 状态", () => {
    it("NotStarted 时 canSubmit=false", () => {
      const { result } = renderHook(() => useExamStateMachine());
      expect(result.current.canSubmit).toBe(false);
    });

    it("InProgress 时 canSubmit=true", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => result.current.actions.start());
      expect(result.current.canSubmit).toBe(true);
    });

    it("AutoSaving 时 canSubmit=true", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginAutoSave();
      });
      expect(result.current.canSubmit).toBe(true);
    });

    it("Submitting 时 canSubmit=false", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginSubmit();
      });
      expect(result.current.canSubmit).toBe(false);
    });

    it("Submitted 时 canSubmit=false", () => {
      const { result } = renderHook(() => useExamStateMachine());
      act(() => {
        result.current.actions.start();
        result.current.actions.beginSubmit();
        result.current.actions.completeSubmit();
      });
      expect(result.current.canSubmit).toBe(false);
    });
  });

  describe("actions 引用稳定性", () => {
    it("actions 对象应在多次渲染间保持引用稳定", () => {
      const { result, rerender } = renderHook(() => useExamStateMachine());
      const firstActions = result.current.actions;
      rerender();
      expect(result.current.actions).toBe(firstActions);
    });
  });
});
