import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { render, screen } from "@testing-library/react";
import type React from "react";
import { MemoryRouter, Route, Routes } from "react-router-dom";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { createI18nMock } from "../../test/i18nMock";
import AuditLogsPage from "../audit/AuditLogsPage";
import AuthCallbackPage from "../auth/AuthCallbackPage";
import AuthGuard from "../auth/AuthGuard";

const authState = {
  isAuthenticated: true,
  isLoading: false,
  activeNavigator: undefined as string | undefined,
  error: null as Error | null,
  user: {
    access_token: "access-token",
    state: undefined as unknown,
  },
};

vi.mock("react-oidc-context", () => ({
  useAuth: () => authState,
}));

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

vi.mock("../../../../common/core/components/audit", () => ({
  AuditLogTable: ({
    logs,
  }: {
    logs: Array<{ user_id: string; event_type: string }>;
  }) => (
    <div>
      {logs.map((log) => (
        <div key={`${log.user_id}-${log.event_type}`}>
          <span>{log.user_id}</span>
          <span>{log.event_type}</span>
        </div>
      ))}
    </div>
  ),
}));

vi.mock("../../lib/adminApi", () => ({
  fetchAuditLogs: vi.fn(async () => ({
    items: [
      {
        event_id: "event-1",
        timestamp: "2026-05-01T00:00:00Z",
        user_id: "admin-1",
        event_type: "USER_UPDATE",
        status: "success",
        ip_address: "127.0.0.1",
        user_agent: "Vitest",
        details: JSON.stringify({ action: "USER_UPDATE", actor: "Admin" }),
      },
      {
        event_id: "event-2",
        timestamp: "2026-05-01T01:00:00Z",
        user_id: "admin-2",
        event_type: "LOGIN_FAILED",
        status: "failure",
        ip_address: "127.0.0.2",
        user_agent: "Vitest",
        details: "{}",
      },
    ],
    limit: 50,
  })),
}));

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

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

describe("admin audit and auth coverage smoke", () => {
  beforeEach(() => {
    (
      window as Window & typeof globalThis & { _IS_TEST_MODE?: boolean }
    )._IS_TEST_MODE = false;
    authState.isAuthenticated = true;
    authState.isLoading = false;
    authState.activeNavigator = undefined;
    authState.error = null;
    authState.user = {
      access_token: "access-token",
      state: undefined,
    };
    window.localStorage.clear();
  });

  it("renders audit log table with fetched events", async () => {
    renderWithProviders(<AuditLogsPage />);

    expect(await screen.findByText("감사 로그")).toBeInTheDocument();
    expect(screen.getByText("admin-1")).toBeInTheDocument();
    expect(screen.getByText("USER_UPDATE")).toBeInTheDocument();
  });

  it("renders AuthGuard loading, error, redirect, test, and outlet states", async () => {
    authState.isLoading = true;
    renderWithProviders(
      <Routes>
        <Route path="/secure" element={<AuthGuard />}>
          <Route index element={<div>Secure outlet</div>} />
        </Route>
      </Routes>,
      "/secure",
    );
    expect(screen.getByText("Loading...")).toBeInTheDocument();

    authState.isLoading = false;
    authState.error = new Error("OIDC failed");
    renderWithProviders(
      <Routes>
        <Route path="/secure" element={<AuthGuard />}>
          <Route index element={<div>Secure outlet</div>} />
        </Route>
      </Routes>,
      "/secure",
    );
    expect(screen.getByText("인증 오류")).toBeInTheDocument();

    authState.error = null;
    authState.isAuthenticated = false;
    renderWithProviders(
      <Routes>
        <Route path="/secure" element={<AuthGuard />}>
          <Route index element={<div>Secure outlet</div>} />
        </Route>
        <Route path="/login" element={<div>Login outlet</div>} />
      </Routes>,
      "/secure?x=1",
    );
    expect(screen.getByText("Login outlet")).toBeInTheDocument();

    (
      window as Window & typeof globalThis & { _IS_TEST_MODE?: boolean }
    )._IS_TEST_MODE = true;
    renderWithProviders(
      <Routes>
        <Route path="/secure" element={<AuthGuard />}>
          <Route index element={<div>Secure outlet</div>} />
        </Route>
      </Routes>,
      "/secure",
    );
    expect(screen.getByText("Secure outlet")).toBeInTheDocument();
  });

  it("stores callback token and navigates by auth result", async () => {
    authState.isAuthenticated = true;
    authState.user = {
      access_token: "callback-token",
      state: { returnTo: "/users" },
    };

    renderWithProviders(
      <Routes>
        <Route path="/auth/callback" element={<AuthCallbackPage />} />
        <Route path="/users" element={<div>Users outlet</div>} />
        <Route path="/login" element={<div>Login outlet</div>} />
      </Routes>,
      "/auth/callback",
    );
    expect(await screen.findByText("Users outlet")).toBeInTheDocument();
    expect(window.localStorage.getItem("admin_session")).toBe("callback-token");

    authState.isAuthenticated = false;
    authState.error = new Error("callback failed");
    renderWithProviders(
      <Routes>
        <Route path="/auth/callback" element={<AuthCallbackPage />} />
        <Route path="/login" element={<div>Login outlet</div>} />
      </Routes>,
      "/auth/callback",
    );
    expect(await screen.findByText("Login outlet")).toBeInTheDocument();
  });
});
