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

vi.mock("./api.js", () => ({
  fetchFilterOptions: 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" }]
  });
});

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();
});

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