import { act, cleanup, render, renderHook, screen } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { I18nProvider } from "@/translations/provider";
import {
  MatchProfileOverlay,
  useMatchProfileOverlay,
} from "./match-profile-overlay";

vi.mock("next/navigation", () => ({
  useRouter: () => ({
    push: vi.fn(),
    replace: vi.fn(),
    back: vi.fn(),
  }),
}));

vi.mock("@/hooks/marriage/use-profile-main", () => ({
  useMarriageProfileQuery: () => ({
    data: {
      status: "matched",
      gender: "female",
      active_case: { case_id: "test-case-1", status: "introduced" },
      match_summary: {
        gender: "male",
        public_info: [{ key: "full_name", label: "نام", value: "علی احمدی" }],
      },
    },
    isLoading: false,
    refetch: vi.fn(),
  }),
}));

vi.mock("@/hooks/marriage/use-case-respond", () => ({
  useRespondToMarriageCaseMutation: () => ({
    mutateAsync: vi.fn(),
    isPending: false,
  }),
}));

function createWrapper() {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: { retry: false },
    },
  });

  return function Wrapper({ children }: { children: React.ReactNode }) {
    return (
      <QueryClientProvider client={queryClient}>
        <I18nProvider locale="fa">{children}</I18nProvider>
      </QueryClientProvider>
    );
  };
}

describe("MatchProfileOverlay & useMatchProfileOverlay", () => {
  beforeEach(() => {
    vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout"] });
    vi.stubGlobal("requestAnimationFrame", (cb: FrameRequestCallback) => {
      return setTimeout(() => cb(Date.now()), 0);
    });
    vi.stubGlobal("cancelAnimationFrame", (id: number) => {
      clearTimeout(id);
    });
    document.body.className = "";
  });

  afterEach(() => {
    cleanup();
    vi.restoreAllMocks();
    vi.useRealTimers();
    document.body.className = "";
  });

  it("hook manages open and close state with history sync", () => {
    const { result } = renderHook(() => useMatchProfileOverlay());

    expect(result.current.isProfileOpen).toBe(false);

    act(() => {
      result.current.openProfile();
    });

    expect(result.current.isProfileOpen).toBe(true);

    act(() => {
      result.current.closeProfile();
    });

    expect(result.current.isProfileOpen).toBe(false);
  });

  it("renders overlay dialog and profile page when open is true", () => {
    const handleClose = vi.fn();
    const wrapper = createWrapper();

    render(
      <MatchProfileOverlay open={true} onClose={handleClose} />,
      { wrapper },
    );

    act(() => {
      vi.advanceTimersByTime(16);
    });

    const overlay = screen.getByRole("dialog");
    expect(overlay).toBeInTheDocument();
    expect(overlay).toHaveClass("section-overlay");
    expect(document.body.classList.contains("section-overlay-open")).toBe(true);
  });

  it("handles closing animation and removes body class when open becomes false", () => {
    const handleClose = vi.fn();
    const wrapper = createWrapper();

    const { rerender } = render(
      <MatchProfileOverlay open={true} onClose={handleClose} />,
      { wrapper },
    );

    act(() => {
      vi.advanceTimersByTime(16);
    });

    expect(screen.getByRole("dialog")).toHaveAttribute("data-state", "open");
    expect(document.body.classList.contains("section-overlay-open")).toBe(true);

    rerender(<MatchProfileOverlay open={false} onClose={handleClose} />);

    expect(screen.getByRole("dialog")).toHaveAttribute("data-state", "closing");
    expect(document.body.classList.contains("section-overlay-open")).toBe(false);

    act(() => {
      vi.advanceTimersByTime(210);
    });

    expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
  });
});
