// @vitest-environment happy-dom
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;

import { describe, expect, it, vi, beforeEach } from "vitest";
import { render, waitFor, cleanup } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

// Stub the auth hook so Sidebar doesn't try to read a token.
vi.mock("@/auth/useAuth", () => ({
  useAuth: () => ({ user: { id: 1, username: "admin", role: "admin" }, logout: vi.fn() }),
}));

// Mutable state so each test can flip the rejected-acks count without
// re-importing the module. `vi.hoisted` ensures the mock factory closes
// over the same `state` object across calls.
const state = vi.hoisted(() => ({
  unmatchedClaims: 0,
  unmatchedRemits: 0,
  rejectedAcks: 0,
}));

vi.mock("@/hooks/useReconciliation", () => ({
  useReconciliation: () => ({
    unmatched: {
      data: {
        claims: Array.from({ length: state.unmatchedClaims }),
        remittances: Array.from({ length: state.unmatchedRemits }),
      },
    },
  }),
}));

vi.mock("@/hooks/useAckStats", () => ({
  useAckStats: () => ({
    data: state.rejectedAcks > 0
      ? { aggregates: { accepted: 1000, rejected: state.rejectedAcks, received: 1005 } }
      : undefined,
  }),
}));

import { Sidebar } from "./Sidebar";

function renderSidebar() {
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  return render(
    <QueryClientProvider client={qc}>
      <MemoryRouter>
        <Sidebar />
      </MemoryRouter>
    </QueryClientProvider>,
  );
}

describe("Sidebar — 999 ACKs rejected badge", () => {
  beforeEach(() => {
    cleanup();
    state.unmatchedClaims = 0;
    state.unmatchedRemits = 0;
    state.rejectedAcks = 0;
  });

  it("shows a '5' badge when 5 segments are rejected", async () => {
    state.rejectedAcks = 5;
    const { container } = renderSidebar();
    await waitFor(() => {
      const badge = container.querySelector(
        '[data-testid="sidebar-acks-rejected-badge"]',
      );
      expect(badge).not.toBeNull();
      expect(badge?.textContent).toBe("5");
    });
  });

  it("shows '99+' when rejected segments exceed 99", async () => {
    state.rejectedAcks = 250;
    const { container } = renderSidebar();
    await waitFor(() => {
      const badge = container.querySelector(
        '[data-testid="sidebar-acks-rejected-badge"]',
      );
      expect(badge?.textContent).toBe("99+");
    });
  });

  it("hides the badge when there are no rejected acks", async () => {
    state.rejectedAcks = 0;
    const { container } = renderSidebar();
    // Allow the synchronous mock to settle.
    await waitFor(() => {
      expect(
        container.querySelector('[data-testid="sidebar-acks-rejected-badge"]'),
      ).toBeNull();
    });
  });
});