/* @vitest-environment jsdom */

import { act } from "react";
import { hydrateRoot, type Root } from "react-dom/client";
import { renderToString } from "react-dom/server";
import { afterEach, describe, expect, it, vi } from "vitest";

const mocks = vi.hoisted(() => ({
  loadLatestMessage: vi.fn(() => new Promise<never>(() => undefined)),
  cache: {
    clear: vi.fn(),
    get: vi.fn(),
    set: vi.fn(),
  },
}));

vi.mock("@/lib/chat/splash_latest_message", () => ({
  loadSplashLatestMessagePreview: mocks.loadLatestMessage,
}));

vi.mock("@/providers/splash-latest-message-provider", () => ({
  useSplashLatestMessageCache: () => mocks.cache,
}));

import { useSplashLatestMessage } from "../use-splash-latest-message";

function LatestMessageHarness() {
  const state = useSplashLatestMessage({
    hasInitialized: true,
    isAuthLoading: false,
    loginStatus: "facebook",
  });

  return state.isLoading ? <button>Loading</button> : <span>Empty</span>;
}

describe("useSplashLatestMessage hydration", () => {
  let root: Root | null = null;

  afterEach(async () => {
    if (root) {
      await act(async () => root?.unmount());
      root = null;
    }
    document.body.innerHTML = "";
    vi.clearAllMocks();
  });

  it("keeps the server and hydration snapshots stable before loading", async () => {
    const serverHtml = renderToString(<LatestMessageHarness />);
    const container = document.createElement("div");
    const hydrationErrors: unknown[] = [];
    container.innerHTML = serverHtml;
    document.body.append(container);

    expect(container.textContent).toBe("Empty");

    await act(async () => {
      root = hydrateRoot(container, <LatestMessageHarness />, {
        onRecoverableError: (error) => hydrationErrors.push(error),
      });
    });

    expect(hydrationErrors).toEqual([]);
    expect(container.textContent).toBe("Loading");
    expect(mocks.loadLatestMessage).toHaveBeenCalledOnce();
  });
});
