/* @vitest-environment jsdom */

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

import { ProfileScreen } from "../profile-screen";

const mocks = vi.hoisted(() => ({
  openAuth: vi.fn(),
  openSubscription: vi.fn(),
  push: vi.fn(),
  replace: vi.fn(),
  authDispatch: vi.fn(),
  userDispatch: vi.fn(),
}));

vi.mock("@/router/use-global-app-navigator", () => ({
  useGlobalAppNavigator: () => ({
    openAuth: mocks.openAuth,
    openSubscription: mocks.openSubscription,
    push: mocks.push,
    replace: mocks.replace,
  }),
}));

vi.mock("@/stores/auth/auth-context", () => ({
  useAuthDispatch: () => mocks.authDispatch,
  useAuthState: () => ({
    hasInitialized: true,
    isLoading: false,
    loginStatus: "email",
  }),
}));

vi.mock("@/stores/user/user-context", () => ({
  useUserDispatch: () => mocks.userDispatch,
  useUserState: () => ({
    avatarUrl: null,
    creditBalance: 120,
    currentUser: {
      id: "user-1",
      username: "Chase",
      countryCode: "US",
      creditBalance: 120,
      dailyFreeChatLimit: 30,
      dailyFreeChatRemaining: 20,
      dailyFreePrivateLimit: 2,
      dailyFreePrivateRemaining: 1,
      isVip: false,
    },
  }),
}));

vi.mock("next-auth/react", () => ({ signOut: vi.fn() }));
vi.mock("../use-pwa-install-entry", () => ({
  usePwaInstallEntry: () => ({
    canInstall: false,
    installApp: vi.fn(),
  }),
}));
vi.mock("../use-profile-user-bootstrap", () => ({
  useProfileUserBootstrap: vi.fn(),
}));

describe("ProfileScreen", () => {
  let container: HTMLDivElement;
  let root: Root;

  beforeEach(() => {
    (globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean })
      .IS_REACT_ACT_ENVIRONMENT = true;
    Object.values(mocks).forEach((mock) => mock.mockReset());
    container = document.createElement("div");
    document.body.append(container);
    root = createRoot(container);
  });

  afterEach(() => {
    act(() => root.unmount());
    container.remove();
  });

  it("renders without CharacterProvider and preserves the source character", () => {
    act(() => {
      root.render(<ProfileScreen returnTo="/characters/maya/chat" />);
    });

    expect(
      container.querySelector<HTMLAnchorElement>(
        '[data-analytics-key="profile.back_to_chat"]',
      )?.getAttribute("href"),
    ).toBe("/characters/maya/chat");

    clickButton("Coin Usage Rules");
    expect(mocks.push).toHaveBeenCalledWith(
      "/coins-rules?returnTo=%2Fcharacters%2Fmaya%2Fchat",
    );

    clickButton("Feedback");
    expect(mocks.push).toHaveBeenCalledWith(
      "/feedback?returnTo=%2Fcharacters%2Fmaya%2Fchat",
    );

    clickButton("Top Up");
    expect(mocks.openSubscription).toHaveBeenCalledWith(
      expect.objectContaining({
        type: "topup",
        sourceCharacterSlug: "maya",
        returnTo: "profile",
      }),
    );
  });

  function clickButton(label: string): void {
    const button = Array.from(container.querySelectorAll("button")).find(
      (item) => item.textContent?.includes(label),
    );
    if (!button) throw new Error(`Missing ${label} button`);
    act(() => button.click());
  }
});
