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

import React, { act } from "react";
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
import { MemoryRouter } from "react-router-dom";
import { createRoot, type Root } from "react-dom/client";
import { useAppStore } from "@/store";
import { ClaimCard837 } from "./ClaimCard837";
import type { ClaimOutput } from "@/types";

// Tiny fixture — just enough to exercise the card's UI surface.
const CLAIM: ClaimOutput = {
  claim_id: "CLM-TEST",
  subscriber: { first_name: "Jane", last_name: "Doe", member_id: "MEM-1" },
  payer: { name: "Test Payer", id: "P1" },
  billing_provider: { npi: "1234567890" },
  claim: {
    total_charge: 100,
    place_of_service: "11",
    frequency_code: "1",
    prior_auth: null,
  },
  service_lines: [
    {
      line_number: 1,
      procedure: { qualifier: "HC", code: "99213", modifiers: [] },
      charge: "100",
      units: "1",
      unit_type: "UN",
      service_date: "2026-06-01",
    },
  ],
  diagnoses: [{ qualifier: "ABK", code: "J20.9" }],
  validation: { passed: true, errors: [], warnings: [] },
};

function renderCard(
  props: Partial<React.ComponentProps<typeof ClaimCard837>> = {},
): {
  container: HTMLDivElement;
  unmount: () => void;
} {
  const container = document.createElement("div");
  document.body.appendChild(container);
  const root: Root = createRoot(container);
  const onToggleSelect = props.onToggleSelect ?? (() => {});
  act(() => {
    root.render(
      React.createElement(
        MemoryRouter,
        null,
        React.createElement(ClaimCard837, {
          claim: CLAIM,
          selected: false,
          onToggleSelect,
          ...props,
        }),
      ),
    );
  });
  return {
    container,
    unmount: () => {
      act(() => root.unmount());
      container.remove();
    },
  };
}

describe("ClaimCard837 — checkbox + select interaction", () => {
  beforeEach(() => {
    useAppStore.setState({ parsedBatches: [] });
  });
  afterEach(() => {
    vi.restoreAllMocks();
  });

  it("renders a checkbox with checked={selected}", () => {
    const { container, unmount } = renderCard({ selected: true });
    const cb = container.querySelector<HTMLInputElement>(
      'input[type="checkbox"]',
    );
    expect(cb).not.toBeNull();
    expect(cb!.checked).toBe(true);
    unmount();
  });

  it("renders an unchecked checkbox when selected={false}", () => {
    const { container, unmount } = renderCard({ selected: false });
    const cb = container.querySelector<HTMLInputElement>(
      'input[type="checkbox"]',
    );
    expect(cb!.checked).toBe(false);
    unmount();
  });

  it("clicking the checkbox fires onToggleSelect with the claim_id", () => {
    const onToggleSelect = vi.fn();
    const { container, unmount } = renderCard({ onToggleSelect });
    const cb = container.querySelector<HTMLInputElement>(
      'input[type="checkbox"]',
    )!;
    act(() => {
      cb.click();
    });
    expect(onToggleSelect).toHaveBeenCalledWith("CLM-TEST");
    unmount();
  });

  it("clicking the checkbox does NOT toggle the card's expand state", () => {
    // Regression guard: the card body is a <button> that toggles expand
    // on click. The new checkbox must not bubble its click into that
    // button (which would also fire onToggleSelect, double-counting).
    // We assert this by checking the expanded content (the service lines
    // table) is NOT in the DOM after a checkbox click.
    const { container, unmount } = renderCard();
    const cb = container.querySelector<HTMLInputElement>(
      'input[type="checkbox"]',
    )!;
    act(() => {
      cb.click();
    });
    // The service lines table only renders when the card is expanded.
    const table = container.querySelector("table");
    expect(table).toBeNull();
    unmount();
  });

  it("clicking the card body still toggles expand (existing behavior preserved)", () => {
    const { container, unmount } = renderCard();
    // The card body is a <button aria-expanded="false">. Clicking it
    // should reveal the expanded details (service lines table).
    const expandButton = container.querySelector<HTMLButtonElement>(
      'button[aria-expanded]',
    );
    expect(expandButton).not.toBeNull();
    act(() => {
      expandButton!.click();
    });
    // After expand, the service lines table is in the DOM.
    const table = container.querySelector("table");
    expect(table).not.toBeNull();
    unmount();
  });

  it("checkbox has an accessible label that names the claim", () => {
    const { container, unmount } = renderCard();
    const cb = container.querySelector<HTMLInputElement>(
      'input[type="checkbox"]',
    );
    // aria-label or wrapping <label> — at minimum the input must be
    // findable by an accessible name. The simplest assertion is that an
    // aria-label exists on the input itself.
    expect(
      cb!.getAttribute("aria-label") ||
        cb!.closest("label")?.textContent,
    ).toContain("CLM-TEST");
    unmount();
  });
});
