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

import React, { act } from "react";
import { createRoot, type Root } from "react-dom/client";
import { describe, expect, it } from "vitest";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { CasAdjustmentsPanel } from "./CasAdjustmentsPanel";
import type { CasAdjustment } from "@/types";

function renderIntoContainer(element: React.ReactElement): {
  container: HTMLDivElement;
  unmount: () => void;
} {
  const container = document.createElement("div");
  document.body.appendChild(container);
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  const root: Root = createRoot(container);
  act(() => {
    root.render(
      React.createElement(QueryClientProvider, { client: qc }, element)
    );
  });
  return {
    container,
    unmount: () => {
      act(() => root.unmount());
      container.remove();
    },
  };
}

describe("CasAdjustmentsPanel", () => {
  it("groups_repeated_codes_and_shows_count_and_amount", () => {
    const adjs: CasAdjustment[] = [
      { group: "CO", reason: "45", label: "Charge exceeds fee schedule", amount: 50, quantity: null },
      { group: "PR", reason: "1", label: "Deductible", amount: 10, quantity: 1 },
      { group: "CO", reason: "45", label: "Charge exceeds fee schedule", amount: -35, quantity: null },
    ];

    const { container, unmount } = renderIntoContainer(
      <CasAdjustmentsPanel adjustments={adjs} />
    );

    const rows = container.querySelectorAll('[data-testid="cas-row"]');
    expect(rows.length).toBe(2);

    const co45 = Array.from(rows).find(
      (row) => row.getAttribute("data-carc") === "CO-45"
    );
    expect(co45).toBeDefined();
    expect(co45?.textContent).toContain("×2");
    // Cumulative amount 50 + -35 = 15, formatted as $15.00.
    expect(co45?.textContent).toContain("15");

    unmount();
  });

  it("renders_nothing_when_adjustments_empty", () => {
    const { container, unmount } = renderIntoContainer(
      <CasAdjustmentsPanel adjustments={[]} />
    );

    // An empty list produces no panel — the parent decides what to
    // show in its place (the parent omits the section entirely, but
    // we still defend against the empty-array case here).
    expect(
      container.querySelector('[data-testid="cas-adjustments-panel"]')
    ).toBeNull();

    unmount();
  });

  it("renders_per_line_section_with_procedure_and_line_number", () => {
    const { container, unmount } = renderIntoContainer(
      <CasAdjustmentsPanel
        adjustments={[]}
        perLine={[
          {
            slp: {
              id: 1,
              lineNumber: 1,
              procedureQualifier: "HC",
              procedureCode: "99213",
              modifiers: [],
              charge: "100.00",
              payment: "80.00",
              units: "1",
              unitType: "UN",
              serviceDate: "2026-06-01",
            },
            adjustments: [
              { groupCode: "CO", reasonCode: "45", amount: "20.00" },
            ],
          },
        ]}
      />
    );

    const section = container.querySelector(
      '[data-testid="per-line-cas-section"]'
    );
    expect(section).not.toBeNull();
    const row = container.querySelector('[data-testid="per-line-cas-row"]');
    expect(row).not.toBeNull();
    expect(row?.getAttribute("data-line-number")).toBe("1");
    expect(row?.textContent).toContain("99213");
    expect(row?.textContent).toContain("#1");
    expect(row?.textContent).toContain("CO-45");

    unmount();
  });

  it("renders_claim_level_section_with_subheader", () => {
    const { container, unmount } = renderIntoContainer(
      <CasAdjustmentsPanel
        adjustments={[]}
        claimLevelAdjustments={[
          { id: 1, groupCode: "PR", reasonCode: "1", amount: "10.00", quantity: null },
        ]}
      />
    );

    const section = container.querySelector(
      '[data-testid="claim-level-cas-section"]'
    );
    expect(section).not.toBeNull();
    expect(section?.textContent ?? "").toMatch(/Claim-level adjustments/i);
    const entry = container.querySelector('[data-testid="claim-level-cas-entry"]');
    expect(entry).not.toBeNull();
    expect(entry?.textContent).toContain("PR-1");

    unmount();
  });

  it("toggle_collapses_and_expands_the_list", () => {
    // A long list (> 3 groups) starts collapsed so the drawer doesn't
    // get buried under a wall of CARC rows. The user can re-expand by
    // clicking the section header.
    const adjs: CasAdjustment[] = [
      { group: "CO", reason: "45", label: "A", amount: 10, quantity: null },
      { group: "PR", reason: "1", label: "B", amount: 10, quantity: 1 },
      { group: "OA", reason: "23", label: "C", amount: 10, quantity: null },
      { group: "PI", reason: "10", label: "D", amount: 10, quantity: null },
    ];

    const { container, unmount } = renderIntoContainer(
      <CasAdjustmentsPanel adjustments={adjs} />
    );

    // 4 unique CARC codes → starts collapsed.
    expect(
      container.querySelector('[data-testid="cas-adjustments-list"]')
    ).toBeNull();

    // Click the toggle → list expands.
    const toggle = container.querySelector(
      '[data-testid="cas-toggle"]'
    ) as HTMLButtonElement | null;
    expect(toggle).not.toBeNull();
    act(() => {
      toggle?.click();
    });
    expect(
      container.querySelector('[data-testid="cas-adjustments-list"]')
    ).not.toBeNull();

    unmount();
  });
});
