import { act, render, screen } from "@testing-library/react";
import { afterEach, beforeEach, expect, test, vi } from "vitest";
import { DatabiApp } from "./DatabiApp.jsx";
import { fetchFilterOptions, fetchSelfGameStatisticsOverview, fetchStatisticsOverview } from "./api.js";

vi.mock("./api.js", () => ({
  fetchFilterOptions: vi.fn(),
  fetchSelfGameStatisticsOverview: vi.fn(),
  fetchStatisticsOverview: vi.fn(),
  getCurrentAppCode: vi.fn(() => "lalu"),
  setCurrentAppCode: vi.fn((value) => String(value || "lalu").toLowerCase())
}));

vi.mock("./charts/EChart.jsx", () => ({
  EChart: () => <div data-testid="databi-chart" />
}));

beforeEach(() => {
  vi.useFakeTimers();
  vi.setSystemTime(new Date("2026-06-06T08:00:00Z"));
  fetchFilterOptions.mockResolvedValue({
    appOptions: [{ code: "lalu", label: "Lalu", value: "lalu" }],
    countryOptions: [{ countryCode: "", id: 0, label: "全部国家", regionIds: [], searchText: "全部国家 all", value: 0 }],
    regionOptions: [{ countryCodes: [], id: "all", label: "全部区域", value: "all" }]
  });
  fetchSelfGameStatisticsOverview.mockResolvedValue({});
});

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

test("keeps current data visible during scheduled refresh", async () => {
  const overview = { active_users: 10, paid_users: 2, recharge_usd_minor: 100, updated_at_ms: 1 };
  fetchStatisticsOverview
    .mockResolvedValueOnce(overview)
    .mockResolvedValueOnce(overview)
    .mockImplementationOnce(() => new Promise(() => {}));

  render(<DatabiApp />);

  await flushEffects();
  expect(screen.getAllByText("$1").length).toBeGreaterThan(0);
  expect(document.querySelector(".metric-card.is-loading")).toBeNull();

  await act(async () => {
    vi.advanceTimersByTime(60_000);
  });

  expect(fetchStatisticsOverview).toHaveBeenCalledTimes(3);
  expect(screen.getAllByText("$1").length).toBeGreaterThan(0);
  expect(document.querySelector(".metric-card.is-loading")).toBeNull();
});

test("loads self game statistics from the big screen switch", async () => {
  fetchStatisticsOverview.mockResolvedValue({ active_users: 10, paid_users: 2, recharge_usd_minor: 100, updated_at_ms: 1 });
  fetchSelfGameStatisticsOverview.mockResolvedValue({
    events: [{ event_name: "page_open", event_count: 8, user_count: 5 }],
    match_totals: { created_matches: 3, matched_matches: 2, settled_matches: 1 },
    retention: { cohort_users: 5, day1_rate: 0.2, day7_rate: 0.1 }
  });

  render(<DatabiApp />);

  await flushEffects();
  await act(async () => {
    screen.getByRole("button", { name: "自研游戏" }).click();
  });
  await flushEffects();

  expect(fetchSelfGameStatisticsOverview).toHaveBeenCalledWith(expect.objectContaining({ appCode: "lalu", gameId: "all" }));
  expect(screen.getByText("Dice / Rock H5 聚合统计")).toBeTruthy();
  expect(screen.getByText("创建局")).toBeTruthy();
});

async function flushEffects() {
  await act(async () => {
    for (let index = 0; index < 10; index += 1) {
      await Promise.resolve();
    }
  });
}
