// @vitest-environment jsdom
import { act, renderHook } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

import { useMountTransition } from "./useMountTransition";

beforeEach(() => {
  vi.useFakeTimers();
  // 让 rAF 同步执行，便于断言 isVisible 翻转。
  vi.stubGlobal("requestAnimationFrame", (cb: FrameRequestCallback) => {
    cb(0);
    return 1;
  });
  vi.stubGlobal("cancelAnimationFrame", () => {});
});

afterEach(() => {
  vi.useRealTimers();
  vi.unstubAllGlobals();
});

describe("useMountTransition", () => {
  it("renders nothing while closed", () => {
    const { result } = renderHook(() => useMountTransition(false, 180));
    expect(result.current.shouldRender).toBe(false);
    expect(result.current.isVisible).toBe(false);
  });

  it("mounts and becomes visible when opened", () => {
    const { result, rerender } = renderHook(
      ({ open }) => useMountTransition(open, 180),
      { initialProps: { open: false } },
    );
    act(() => rerender({ open: true }));
    expect(result.current.shouldRender).toBe(true);
    expect(result.current.isVisible).toBe(true);
  });

  it("keeps rendering during exit, then unmounts after the duration", () => {
    const { result, rerender } = renderHook(
      ({ open }) => useMountTransition(open, 180),
      { initialProps: { open: true } },
    );
    act(() => rerender({ open: false }));
    expect(result.current.isVisible).toBe(false);
    expect(result.current.shouldRender).toBe(true);

    act(() => {
      vi.advanceTimersByTime(180);
    });
    expect(result.current.shouldRender).toBe(false);
  });
});
