import { fmt } from "@/lib/format";
import type {
LineReconciliationResponse,
LineReconciliationRow,
} from "@/types";
/**
* Per-line reconciliation tab for the ClaimDrawer (SP7 §6.2).
*
* Two-column layout: left = "Billed (837 SV1)", right = "Adjudicated
* (835 SVC)". Each row is a service line, matched when both sides
* are present; unmatched 835 lines appear at the bottom with an
* oxblood accent rail. Per-line CAS adjustments are listed under each
* row.
*/
export function LineReconciliationTab({
data,
}: {
data: LineReconciliationResponse;
}) {
const { summary, lines } = data;
const allMatched = summary.matchedLines === summary.totalLines;
const leftRows = lines.filter((l) => l.status !== "unmatched_835_only");
const rightRows = lines;
return (
Billed (837 SV1)
{leftRows.map((row) => (
))}
Adjudicated (835 SVC)
{rightRows.map((row) => (
))}
);
}
function rowKey(row: LineReconciliationRow, side: "left" | "right"): string {
const ln =
row.claimServiceLine?.lineNumber ??
row.serviceLinePayment?.lineNumber ??
-1;
return `${side}-${row.status}-${ln}`;
}
function LineCard({
row,
side,
}: {
row: LineReconciliationRow;
side: "left" | "right";
}) {
const cl = row.claimServiceLine;
const svc = row.serviceLinePayment;
const isUnmatched835 = row.status === "unmatched_835_only";
const accentColor = isUnmatched835 ? "var(--tt-oxblood)" : "var(--tt-ink-blue)";
const procCode = cl?.procedureCode ?? svc?.procedureCode ?? "—";
const lineNumber = cl?.lineNumber ?? svc?.lineNumber ?? null;
return (
{procCode}
{lineNumber !== null ? (
#{lineNumber}
) : null}
{isUnmatched835 ? (
no 837 line matched
) : null}
{row.status === "unmatched_837_only" ? (
no 835 line adjudicated this line
) : null}
{side === "left" && cl ? {fmt.usdPrecise(Number(cl.charge))} : null}
{side === "right" && svc ? {fmt.usdPrecise(Number(svc.payment))} : null}
{row.adjustments.length > 0 ? (
{row.adjustments.map((a, i) => (
-
{a.groupCode}-{a.reasonCode}
{fmt.usdPrecise(Number(a.amount))}
))}
) : null}
);
}