// @vitest-environment happy-dom
// SP27 Task 13: server-aggregated Dashboard KPIs.
//
// These tests pin the hook's contract independent of the Dashboard
// page: when the backend is wired, it calls ``api.getDashboardKpis``
// with the requested parameters and returns the resolved value; when
// the backend is not wired, it returns ``data: undefined`` so the
// Dashboard can render zero-shaped fallbacks.
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;

import { describe, expect, it, vi, beforeEach } from "vitest";
import { renderHook, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import React from "react";
import { api, type DashboardKpis } from "@/lib/api";

// Mock the api module so we can control isConfigured + getDashboardKpis
// without spinning up a real backend.
vi.mock("@/lib/api", async () => {
  const actual = await vi.importActual<typeof import("@/lib/api")>("@/lib/api");
  return {
    ...actual,
    api: {
      ...actual.api,
      getDashboardKpis: vi.fn(),
    },
  };
});

// Import AFTER the mock so the hook sees the mocked api.
const { useDashboardKpis } = await import("./useDashboardKpis");

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function makeWrapper() {
  const client = new QueryClient({
    defaultOptions: {
      queries: { retry: false, gcTime: 0, staleTime: 0 },
    },
  });
  return ({ children }: { children: React.ReactNode }) =>
    React.createElement(QueryClientProvider, { client }, children);
}

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------

describe("useDashboardKpis", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("calls api.getDashboardKpis and returns the resolved value when configured", async () => {
    const payload: DashboardKpis = {
      totals: {
        count: 60295,
        billed: 940143.58,
        received: 59753,
        outstandingAr: 880390.58,
        denied: 542,
        denialRate: 0.9,
        pending: 60,
      },
      monthly: [
        { month: "2026-01", label: "Jan", count: 100, billed: 15000,
          received: 12000, denied: 2, denialRate: 2.0, ar: 3000 },
      ],
      topProviders: [
        { npi: "1234567893", label: "Cedar Park", claimCount: 200,
          billed: 30000, denied: 1 },
      ],
      topDenials: [
        { id: "C-1", patientName: "Jane Doe", billedAmount: 250,
          denialReason: "Missing modifier", submissionDate: "2026-06-20T12:00:00Z" },
      ],
    };
    (api.getDashboardKpis as ReturnType<typeof vi.fn>).mockResolvedValue(payload);
    // Override the isConfigured bit too — the hook keys off this.
    (api as unknown as { isConfigured: boolean }).isConfigured = true;

    const { result } = renderHook(() => useDashboardKpis({ months: 6 }), {
      wrapper: makeWrapper(),
    });

    await waitFor(() => {
      expect(result.current.data).toEqual(payload);
    });
    expect(api.getDashboardKpis).toHaveBeenCalledWith({ months: 6 });
    expect(result.current.isError).toBe(false);
  });

  it("returns data: undefined when the backend is not configured", () => {
    (api as unknown as { isConfigured: boolean }).isConfigured = false;

    const { result } = renderHook(() => useDashboardKpis(), {
      wrapper: makeWrapper(),
    });

    expect(result.current.data).toBeUndefined();
    expect(result.current.isLoading).toBe(false);
    expect(result.current.isError).toBe(false);
    // queryFn should NOT have been called — bypassed entirely.
    expect(api.getDashboardKpis).not.toHaveBeenCalled();
  });

  it("passes top_n_providers / top_n_denials through to the API", async () => {
    (api.getDashboardKpis as ReturnType<typeof vi.fn>).mockResolvedValue({
      totals: { count: 0, billed: 0, received: 0, outstandingAr: 0,
                denied: 0, denialRate: 0, pending: 0 },
      monthly: [], topProviders: [], topDenials: [],
    });
    (api as unknown as { isConfigured: boolean }).isConfigured = true;

    renderHook(
      () => useDashboardKpis({ months: 3, top_n_providers: 2, top_n_denials: 5 }),
      { wrapper: makeWrapper() },
    );

    expect(api.getDashboardKpis).toHaveBeenCalledWith({
      months: 3, top_n_providers: 2, top_n_denials: 5,
    });
  });
});