import { StrictMode } from "react";
import { act } from "react";
import { createRoot } from "react-dom/client";
import { afterEach, describe, expect, it, vi } from "vitest";

const mocks = vi.hoisted(() => ({
  chatDispatch: vi.fn(),
  getLoginToken: vi.fn(async () => ({
    success: true as const,
    data: "email-token",
  })),
}));

vi.mock("@/data/storage/auth", () => ({
  AuthStorage: {
    getInstance: () => ({ getLoginToken: mocks.getLoginToken }),
  },
}));

vi.mock("@/stores/auth/auth-context", () => ({
  selectAuthIsLoading: () => false,
  useAuthSelector: (selector: (state: unknown) => unknown) =>
    selector({
      context: {
        hasInitialized: true,
        loginStatus: "email",
      },
    }),
}));

vi.mock("@/stores/chat/chat-context", () => ({
  useChatDispatch: () => mocks.chatDispatch,
}));

import { ChatAuthSync } from "../chat-auth-sync";

let container: HTMLDivElement | null = null;
let root: ReturnType<typeof createRoot> | null = null;

afterEach(() => {
  if (root) act(() => root?.unmount());
  container?.remove();
  container = null;
  root = null;
  mocks.chatDispatch.mockReset();
  mocks.getLoginToken.mockClear();
});

describe("ChatAuthSync", () => {
  it("dispatches the authenticated session after StrictMode restarts the effect", async () => {
    container = document.createElement("div");
    document.body.append(container);
    root = createRoot(container);

    await act(async () => {
      root?.render(
        <StrictMode>
          <ChatAuthSync />
        </StrictMode>,
      );
    });

    expect(mocks.chatDispatch).toHaveBeenCalledTimes(1);
    expect(mocks.chatDispatch).toHaveBeenCalledWith({
      type: "ChatUserLogin",
      token: "email-token",
    });
  });
});
