import type { ClaimDetail, ClaimDetailAddress } from "@/types";

type PartiesGridProps = {
  parties: ClaimDetail["parties"];
};

type AddressLike = ClaimDetail["parties"]["billingProvider"]["address"];

/**
 * Address can come back as `ClaimDetailAddress` (line1/line2/city/...) or
 * `{}` (the backend's `Record<string, never>` shape for "missing"). The
 * latter is structurally a regular object with no keys, so a single
 * `Object.keys(addr).length === 0` check is the safe way to detect it
 * without resorting to `'line1' in addr`.
 */
function isEmptyAddress(addr: AddressLike | null | undefined): boolean {
  if (addr === null || addr === undefined) return true;
  return Object.keys(addr).length === 0;
}

function AddressBlock({ address }: { address: AddressLike }) {
  if (isEmptyAddress(address)) return null;
  // After the empty check the cast is safe — the remaining union arm is
  // `ClaimDetailAddress` which has all the fields we read.
  const a = address as ClaimDetailAddress;
  return (
    <div
      className="mt-1 border-t border-dashed border-[color:var(--m-border-heavy)]/30 pt-2 text-xs leading-relaxed text-[color:var(--m-ink-secondary)]"
      data-testid="party-address"
    >
      <div>{a.line1}</div>
      {a.line2 ? <div>{a.line2}</div> : null}
      <div>
        {a.city}, {a.state} {a.zip}
      </div>
    </div>
  );
}

/**
 * Single party card: eyebrow label, name, identity mono line(s), and
 * an optional address block. The card is just a light surface with a
 * border — no shadow, no hover; the drawer is read-only detail content.
 */
function PartyCard({
  testId,
  label,
  name,
  identity,
  address,
}: {
  testId: string;
  label: string;
  name: string;
  identity: React.ReactNode;
  address?: AddressLike;
}) {
  return (
    <div
      data-testid={testId}
      className="flex flex-col gap-2 rounded-lg border border-[color:var(--m-border-heavy)]/30 bg-[color:var(--m-surface)]/60 px-4 py-3 transition-colors hover:border-[color:var(--m-border-heavy)]/50"
    >
      <span className="eyebrow text-[color:var(--m-ink-tertiary)]">
        {label}
      </span>
      <div className="display text-lg text-[color:var(--m-ink-primary)]">
        {name}
      </div>
      <div
        className="mono text-[12.5px] text-[color:var(--m-ink-secondary)] tabular-nums"
      >
        {identity}
      </div>
      {address ? <AddressBlock address={address} /> : null}
    </div>
  );
}

/**
 * Parties section of the claim detail drawer (SP4).
 *
 * Three stacked cards on mobile (`grid-cols-1`), 3-up grid on desktop
 * (`md:grid-cols-3`). Billing provider carries the full identity + tax
 * id + address; subscriber shows the member record; payer is the slim
 * name+id card. All optional fields (subscriber DOB, line2) are
 * conditionally rendered so a missing value doesn't become "null" in
 * the rendered text.
 */
export function PartiesGrid({ parties }: PartiesGridProps) {
  const { billingProvider, subscriber, payer } = parties;

  return (
    <section
      className="flex flex-col gap-3 px-6 py-4"
      data-testid="parties-grid"
    >
      <h3
        data-testid="section-label"
        className="eyebrow text-[color:var(--m-ink-tertiary)]"
      >
        Parties
      </h3>

      <div
        data-testid="parties-grid-inner"
        className="grid grid-cols-1 md:grid-cols-3 gap-4"
      >
        <PartyCard
          testId="party-billing-provider"
          label="Billing provider"
          name={billingProvider.name}
          identity={
            <>
              <div>NPI {billingProvider.npi}</div>
              {billingProvider.taxId ? (
                <div>Tax ID {billingProvider.taxId}</div>
              ) : null}
            </>
          }
          address={billingProvider.address}
        />

        <PartyCard
          testId="party-subscriber"
          label="Subscriber"
          name={`${subscriber.firstName} ${subscriber.lastName}`}
          identity={
            <>
              <div>Member ID {subscriber.memberId}</div>
              {subscriber.gender ? <div>Gender {subscriber.gender}</div> : null}
              {subscriber.dob ? <div>DOB {subscriber.dob}</div> : null}
            </>
          }
        />

        <PartyCard
          testId="party-payer"
          label="Payer"
          name={payer.name}
          identity={
            <>
              <div>ID {payer.id}</div>
            </>
          }
        />
      </div>
    </section>
  );
}
