import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import type React from "react";
import { MemoryRouter } from "react-router-dom";
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
  fetchAdminRPUsageDaily,
  fetchDataIntegrityReport,
} from "../../lib/adminApi";
import { createI18nMock } from "../../test/i18nMock";
import AuthPage from "../auth/AuthPage";
import GlobalOverviewPage from "./GlobalOverviewPage";

vi.mock("../../lib/i18n", () => createI18nMock());

let currentRole = "super_admin";

vi.mock("../../lib/adminApi", () => ({
  fetchMe: vi.fn(async () => ({ role: currentRole })),
  fetchAdminOverviewStats: vi.fn(async () => ({
    totalTenants: 10,
    totalUsers: 152,
    oidcClients: 3,
    auditEvents24h: 18,
  })),
  fetchAllTenants: vi.fn(async () => ({
    items: [
      {
        id: "group-1",
        type: "COMPANY_GROUP",
        name: "한맥그룹",
        slug: "hanmac-group",
        description: "",
        status: "active",
        memberCount: 0,
        createdAt: "2026-05-06T00:00:00Z",
        updatedAt: "2026-05-06T00:00:00Z",
      },
      {
        id: "company-1",
        type: "COMPANY",
        name: "한맥",
        slug: "hanmac",
        description: "",
        status: "active",
        memberCount: 0,
        createdAt: "2026-05-06T00:00:00Z",
        updatedAt: "2026-05-06T00:00:00Z",
      },
      {
        id: "org-1",
        type: "ORGANIZATION",
        name: "개발팀",
        slug: "dev-team",
        description: "",
        status: "active",
        memberCount: 0,
        createdAt: "2026-05-06T00:00:00Z",
        updatedAt: "2026-05-06T00:00:00Z",
      },
      {
        id: "personal-1",
        type: "PERSONAL",
        name: "개인",
        slug: "personal",
        description: "",
        status: "active",
        memberCount: 0,
        createdAt: "2026-05-06T00:00:00Z",
        updatedAt: "2026-05-06T00:00:00Z",
      },
    ],
    limit: 1000,
    offset: 0,
    total: 4,
  })),
  fetchAdminRPUsageDaily: vi.fn(async () => ({
    days: 14,
    period: "day",
    items: [
      {
        date: "2026-05-05",
        tenantId: "company-1",
        tenantType: "COMPANY",
        tenantName: "한맥",
        clientId: "orgfront",
        clientName: "OrgFront",
        loginRequests: 12,
        otherRequests: 4,
        uniqueSubjects: 8,
      },
      {
        date: "2026-05-06",
        tenantId: "company-1",
        tenantType: "COMPANY",
        tenantName: "한맥",
        clientId: "adminfront",
        clientName: "AdminFront",
        loginRequests: 7,
        otherRequests: 3,
        uniqueSubjects: 5,
      },
      {
        date: "2026-09-28",
        tenantId: "company-1",
        tenantType: "COMPANY",
        tenantName: "한맥",
        clientId: "devfront",
        clientName: "DevFront",
        loginRequests: 2,
        otherRequests: 1,
        uniqueSubjects: 2,
      },
    ],
  })),
  fetchDataIntegrityReport: vi.fn(async () => ({
    status: "fail",
    checkedAt: "2026-05-14T00:00:00Z",
    summary: {
      totalChecks: 5,
      passed: 4,
      warnings: 0,
      failures: 1,
    },
    sections: [
      {
        key: "tenant_integrity",
        label: "테넌트 정합성",
        status: "pass",
        checks: [],
      },
      {
        key: "user_integrity",
        label: "사용자 정합성",
        status: "fail",
        checks: [],
      },
    ],
  })),
}));

function renderWithProviders(ui: React.ReactElement) {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: { retry: false },
      mutations: { retry: false },
    },
  });

  return render(
    <QueryClientProvider client={queryClient}>
      <MemoryRouter>{ui}</MemoryRouter>
    </QueryClientProvider>,
  );
}

describe("admin overview and auth guard pages", () => {
  beforeEach(() => {
    currentRole = "super_admin";
    vi.clearAllMocks();
  });

  it("renders usage trend chart without quick navigation or permission checker", async () => {
    renderWithProviders(<GlobalOverviewPage />);

    expect(
      await screen.findByText("회사별 앱별 로그인 요청 현황"),
    ).toBeInTheDocument();
    expect(
      await screen.findByLabelText("일 단위 RP 요청 현황"),
    ).toBeInTheDocument();
    expect(await screen.findByText("05.05")).toBeInTheDocument();
    expect(await screen.findByText("05.06")).toBeInTheDocument();
    expect(screen.queryByText("빠른 작업")).not.toBeInTheDocument();
    expect(screen.queryByText("빠른 이동")).not.toBeInTheDocument();
    expect(screen.queryByText("테넌트 추가")).not.toBeInTheDocument();
    expect(screen.queryByText("ReBAC 권한 검증 도구")).not.toBeInTheDocument();
  });

  it("renders overview tenant count from the fully fetched tenant list", async () => {
    renderWithProviders(<GlobalOverviewPage />);

    expect(
      (await screen.findByText("전체 테넌트 수")).parentElement,
    ).toHaveTextContent("4");
    expect(screen.getByText("OIDC 클라이언트").parentElement).toHaveTextContent(
      "3",
    );
    expect(screen.getByText("전체 사용자 수").parentElement).toHaveTextContent(
      "152",
    );
    expect(screen.getByText("24시간 이벤트").parentElement).toHaveTextContent(
      "18",
    );
  });

  it("limits the overview graph choices to company tenants", async () => {
    renderWithProviders(<GlobalOverviewPage />);

    await screen.findByText("회사별 앱별 로그인 요청 현황");

    expect(
      await screen.findByRole("checkbox", { name: "한맥 (hanmac)" }),
    ).toBeInTheDocument();
    expect(
      screen.queryByText("한맥그룹 (hanmac-group)"),
    ).not.toBeInTheDocument();
    expect(screen.queryByText("개발팀 (dev-team)")).not.toBeInTheDocument();
    expect(screen.queryByText("개인 (personal)")).not.toBeInTheDocument();
  });

  it("changes the RP usage perspective and targets a permitted company", async () => {
    renderWithProviders(<GlobalOverviewPage />);

    await screen.findByText("회사별 앱별 로그인 요청 현황");
    fireEvent.click(screen.getByRole("button", { name: "주" }));
    expect(await screen.findAllByText("19(05월1주)")).not.toHaveLength(0);
    expect(await screen.findAllByText("40(10월1주)")).not.toHaveLength(0);
    fireEvent.click(screen.getByRole("button", { name: "월" }));
    fireEvent.click(screen.getByRole("checkbox", { name: "한맥 (hanmac)" }));

    await waitFor(() => {
      expect(fetchAdminRPUsageDaily).toHaveBeenLastCalledWith({
        days: 90,
        period: "month",
      });
    });
    expect(
      screen.queryByText("한맥그룹 (hanmac-group)"),
    ).not.toBeInTheDocument();
    expect(screen.queryByText("개발팀 (dev-team)")).not.toBeInTheDocument();
    expect(screen.queryByText("개인 (personal)")).not.toBeInTheDocument();
  });

  it("shows the latest integrity summary at the bottom for super admins only", async () => {
    renderWithProviders(<GlobalOverviewPage />);

    expect(await screen.findByText("정합성 최종 검증")).toBeInTheDocument();
    expect(screen.getByText("실패 1건")).toBeInTheDocument();
    expect(screen.getByText("테넌트 정합성")).toBeInTheDocument();
    expect(screen.getByText("사용자 정합성")).toBeInTheDocument();
    expect(fetchDataIntegrityReport).toHaveBeenCalledTimes(1);
  });

  it("does not fetch or show the integrity summary for non-super admins", async () => {
    currentRole = "tenant_admin";

    renderWithProviders(<GlobalOverviewPage />);

    await screen.findByText("회사별 앱별 로그인 요청 현황");
    expect(screen.queryByText("정합성 최종 검증")).not.toBeInTheDocument();
    expect(fetchDataIntegrityReport).not.toHaveBeenCalled();
  });

  it("moves the permission checker to the auth guard page and removes mock guardrails", () => {
    renderWithProviders(<AuthPage />);

    expect(screen.getByText("인증 가드")).toBeInTheDocument();
    expect(screen.getByText("ReBAC 권한 검증 도구")).toBeInTheDocument();
    expect(screen.queryByText("Admin auth guardrails")).not.toBeInTheDocument();
    expect(
      screen.queryByText("IDP session placeholder"),
    ).not.toBeInTheDocument();
    expect(screen.queryByText("Admin login")).not.toBeInTheDocument();
  });
});
