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

vi.mock("./api.js", () => ({
  fetchFilterOptions: vi.fn(),
  fetchSocialBiFilterOptions: vi.fn(),
  fetchSelfGameStatisticsOverview: vi.fn(),
  fetchStatisticsOverview: vi.fn(),
  getCurrentAppCode: vi.fn(() => "lalu"),
  getDefaultAppOptions: vi.fn(() => [
    { code: "", label: "全部", value: "" },
    { code: "lalu", label: "Lalu", value: "lalu" },
    { code: "aslan", label: "Aslan", value: "aslan" },
    { code: "yumi", label: "Yumi", value: "yumi" }
  ]),
  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: "", label: "全部", value: "" },
      { code: "lalu", label: "Lalu", value: "lalu" },
      { code: "aslan", label: "Aslan", value: "aslan" },
      { code: "yumi", label: "Yumi", value: "yumi" }
    ],
    countryOptions: [{ countryCode: "", id: 0, label: "全部国家", regionIds: [], searchText: "全部国家 all", value: 0 }],
    regionOptions: [{ countryCodes: [], id: "all", label: "全部区域", value: "all" }]
  });
  fetchSelfGameStatisticsOverview.mockResolvedValue({});
  fetchSocialBiFilterOptions.mockResolvedValue({
    appOptions: [
      { label: "全部 App", value: "all" },
      { label: "Lalu", value: "lalu" },
      { label: "Aslan", value: "aslan" },
      { label: "Yumi", value: "yumi" }
    ],
    operatorOptions: [{ label: "全部人员", searchText: "all 全部人员", value: "all" }]
  });
});

afterEach(() => {
  window.history.pushState(null, "", "/");
  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(screen.getByLabelText("数据报表")).toBeTruthy();
  expect(document.querySelector(".report-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(".report-metric-card.is-loading")).toBeNull();
});

test("queries China natural day statistics when display timezone is Beijing", async () => {
  fetchStatisticsOverview.mockResolvedValue({ active_users: 10, paid_users: 2, recharge_usd_minor: 100, updated_at_ms: 1 });

  render(<DatabiApp />);

  await flushEffects();

  expect(fetchStatisticsOverview).toHaveBeenCalledWith(expect.objectContaining({
    endMs: Date.UTC(2026, 5, 6, 15, 59, 59),
    seriesEndMs: Date.UTC(2026, 5, 6, 15, 59, 59),
    seriesStartMs: Date.UTC(2026, 4, 30, 16, 0, 0),
    startMs: Date.UTC(2026, 5, 5, 16, 0, 0),
    statTz: "Asia/Shanghai"
  }));
});

test("renders legacy app metric columns in report view", async () => {
  fetchStatisticsOverview.mockResolvedValue({
    coin_seller_stock_coin: 400_000,
    coin_seller_transfer_coin: 160_000,
    salary_transfer_coin: 88_000,
    country_breakdown: [
      {
        coin_seller_stock_coin: 400_000,
        coin_seller_transfer_coin: 160_000,
        country: "巴西",
        country_id: 86,
        salary_transfer_coin: 88_000
      }
    ],
    updated_at_ms: 1
  });

  render(<DatabiApp />);

  await flushEffects();

  expect(screen.getByRole("columnheader", { name: "币商充值金币" })).toBeTruthy();
  expect(screen.getByRole("columnheader", { name: "币商出货金币" })).toBeTruthy();
  expect(screen.getByRole("columnheader", { name: "工资兑换金币" })).toBeTruthy();
  expect(screen.getAllByText("400,000").length).toBeGreaterThan(0);
  expect(screen.getAllByText("160,000").length).toBeGreaterThan(0);
  expect(screen.getAllByText("88,000").length).toBeGreaterThan(0);
});

test("switches report sidebar sections and stops data report polling on empty sections", async () => {
  fetchStatisticsOverview.mockResolvedValue({ active_users: 10, paid_users: 2, recharge_usd_minor: 100, updated_at_ms: 1 });

  render(<DatabiApp />);

  await flushEffects();

  const reportTypeTabs = screen.getByRole("tablist", { name: "报表类型" });
  expect(within(reportTypeTabs).getByRole("tab", { name: "数据报表" })).toHaveAttribute("aria-selected", "true");
  expect(screen.getByRole("region", { name: "数据报表" })).toBeTruthy();

  await act(async () => {
    within(reportTypeTabs).getByRole("tab", { name: "财务报表" }).click();
  });

  expect(within(reportTypeTabs).getByRole("tab", { name: "财务报表" })).toHaveAttribute("aria-selected", "true");
  expect(screen.getByRole("region", { name: "财务报表" })).toBeTruthy();
  expect(screen.queryByRole("region", { name: "数据报表" })).toBeNull();
  const requestCountAfterFinanceSwitch = fetchStatisticsOverview.mock.calls.length;

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

  expect(fetchStatisticsOverview).toHaveBeenCalledTimes(requestCountAfterFinanceSwitch);

  await act(async () => {
    within(reportTypeTabs).getByRole("tab", { name: "运营报表" }).click();
  });

  expect(within(reportTypeTabs).getByRole("tab", { name: "运营报表" })).toHaveAttribute("aria-selected", "true");
  expect(screen.getByRole("region", { name: "运营报表" })).toBeTruthy();

  await act(async () => {
    within(reportTypeTabs).getByRole("tab", { name: "数据报表" }).click();
  });
  await flushEffects();

  expect(screen.getByRole("region", { name: "数据报表" })).toBeTruthy();
  expect(fetchStatisticsOverview.mock.calls.length).toBeGreaterThan(requestCountAfterFinanceSwitch);
});

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", statTz: "Asia/Shanghai" }));
  expect(screen.getByText("Dice / Rock H5 聚合统计")).toBeTruthy();
  expect(screen.getByText("创建局")).toBeTruthy();
});

test("renders real-room robot gift cards in a separate row", async () => {
  fetchStatisticsOverview.mockResolvedValue({
    real_room_robot_avg_room_gift_coin: 300,
    real_room_robot_gift_room_count: 2,
    real_room_robot_lucky_gift_coin: 200,
    real_room_robot_normal_gift_coin: 100,
    real_room_robot_super_gift_coin: 300,
    updated_at_ms: 1
  });

  render(<DatabiApp />);

  await flushEffects();
  await act(async () => {
    screen.getByRole("tab", { name: "大屏 BI" }).click();
  });

  const businessSection = screen.getByLabelText("业务指标");
  const robotGiftSection = screen.getByLabelText("真人房机器人送礼指标");
  expect(within(businessSection).queryByText("真人房机器人普通礼物")).toBeNull();
  expect(within(robotGiftSection).getByText("真人房机器人普通礼物")).toBeTruthy();
  expect(within(robotGiftSection).getByText("真人房机器人幸运礼物")).toBeTruthy();
  expect(within(robotGiftSection).getByText("真人房机器人超级幸运礼物")).toBeTruthy();
  expect(within(robotGiftSection).getByText("真人房机器人房均礼物")).toBeTruthy();
});

test("routes databi social page to Social BI and loads real overview rows", async () => {
  window.history.pushState(null, "", "/databi/social/");
  fetchStatisticsOverview.mockImplementation(async ({ appCode }) => ({
    active_users: appCode === "lalu" ? 20 : 10,
    app_name: appCode === "lalu" ? "Lalu" : appCode === "aslan" ? "Aslan" : "Yumi",
    arpu_usd_minor: 410,
    arppu_usd_minor: appCode === "aslan" ? null : 615,
    avg_mic_online_ms: 120_000,
    coin_seller_recharge_usd_minor: 3400,
    coin_seller_stock_coin: 400_000,
    coin_seller_transfer_coin: 160_000,
    coin_total: appCode === "aslan" ? 5000 : null,
    consumed_coin: 900_000,
    consume_output_delta: 450_000,
    consume_output_ratio: 0.5,
    country_breakdown: [],
    game_profit_rate: 0.17,
    game_turnover: 300_000,
    gift_coin_spent: 123_456,
    google_recharge_usd_minor: 700,
    lucky_gift_profit_rate: 0.25,
    lucky_gift_turnover: 200_000,
    manual_grant_coin: 222,
    mic_online_ms: 3_600_000,
    mifapay_recharge_usd_minor: 800,
    new_user_recharge_usd_minor: 1200,
    new_users: appCode === "lalu" ? 3 : 1,
    output_coin: 450_000,
    paid_conversion_rate: 0.2,
    paid_users: 4,
    platform_grant_coin: 111,
    recharge_usd_minor: appCode === "lalu" ? 12300 : 5000,
    recharge_conversion_rate: 0.2,
    recharge_users: 4,
    retention: { day1_rate: 0.25, day7_rate: 0.1, day30_rate: 0.05 },
    salary_transfer_coin: 88_000,
    salary_usd_minor: appCode === "aslan" ? 2500 : null,
    super_lucky_gift_profit_rate: 0.08,
    super_lucky_gift_turnover: 50_000
  }));

  render(<DatabiApp />);

  await flushEffects();

  expect(screen.getByLabelText("Social BI 数据中心")).toBeTruthy();
  expect(screen.queryByText("App 数据明细")).toBeNull();
  expect(fetchSocialBiFilterOptions).toHaveBeenCalledTimes(1);
  expect(fetchStatisticsOverview).toHaveBeenCalledWith(expect.objectContaining({ appCode: "lalu", statTz: "Asia/Shanghai" }));
  expect(fetchStatisticsOverview).toHaveBeenCalledWith(expect.objectContaining({ appCode: "aslan", statTz: "Asia/Shanghai" }));
  expect(fetchStatisticsOverview).toHaveBeenCalledWith(expect.objectContaining({ appCode: "yumi", statTz: "Asia/Shanghai" }));
  expect(screen.getAllByText("Lalu").length).toBeGreaterThan(0);
  expect(screen.getByText("付费用户")).toBeTruthy();
  expect(screen.getByText("游戏流水/利润率")).toBeTruthy();
  expect(screen.getByText("消耗产出比")).toBeTruthy();
  expect(screen.getByText("ARPU ($)")).toBeTruthy();
  expect(screen.getAllByText("$123").length).toBeGreaterThan(0);
  expect(screen.getAllByText("300,000").length).toBeGreaterThan(0);
  expect(screen.getAllByText("17.0%").length).toBeGreaterThan(0);
  expect(screen.getAllByText("2分").length).toBeGreaterThan(0);
  expect(screen.queryByText("$284,300")).toBeNull();
});

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