import { useMemo, useRef, useState } from "react";
import {
  AlertTriangle,
  ArrowRight,
  CheckCircle2,
  ChevronRight,
  CloudUpload,
  FileText,
  Inbox,
  Loader2,
  Upload as UploadIcon,
  XCircle,
} from "lucide-react";
import { toast } from "sonner";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { api, type ParseProgress } from "@/lib/api";
import { fmt, toNum } from "@/lib/format";
import { useAppStore } from "@/store";
import { useParse } from "@/hooks/useParse";
import type {
  ClaimOutput,
  ClaimPayment,
  ParsedBatch,
  ParsedBatchKind,
  ServiceLine,
  ServicePayment,
} from "@/types";
import { cn } from "@/lib/utils";

// ---------------------------------------------------------------------------
// Streaming state — every claim that arrives from the backend accumulates
// in this list. The 837P and 835 cases are kept as separate slots so the UI
// can render the right "card" type for each.
// ---------------------------------------------------------------------------

type StreamedClaim837 = { kind: "837p"; data: ClaimOutput };
type StreamedClaim835 = { kind: "835"; data: ClaimPayment };
type StreamedClaim = StreamedClaim837 | StreamedClaim835;

interface StreamState {
  items: StreamedClaim[];
  expectedTotal: number | null;
  passed: number;
  failed: number;
}

const PAYERS_837 = [
  { value: "co_medicaid", label: "CO Medicaid" },
  { value: "generic_837p", label: "Generic 837P" },
];

const PAYERS_835 = [
  { value: "co_medicaid_835", label: "CO Medicaid" },
  { value: "generic_835", label: "Generic 835" },
];

function formatBytes(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
}

function ValidationDot({
  passed,
  hasWarnings,
}: {
  passed: boolean;
  hasWarnings?: boolean;
}) {
  if (passed) {
    return (
      <span
        className="inline-flex items-center gap-1.5 mono text-[10.5px] uppercase tracking-[0.12em] text-[hsl(var(--success))] font-medium"
        title="Validation passed"
      >
        <CheckCircle2 className="h-3.5 w-3.5" strokeWidth={1.75} />
        Passed
      </span>
    );
  }
  if (hasWarnings) {
    return (
      <span
        className="inline-flex items-center gap-1.5 mono text-[10.5px] uppercase tracking-[0.12em] text-[hsl(var(--warning))] font-medium"
        title="Validation passed with warnings"
      >
        <AlertTriangle className="h-3.5 w-3.5" strokeWidth={1.75} />
        Warnings
      </span>
    );
  }
  return (
    <span
      className="inline-flex items-center gap-1.5 mono text-[10.5px] uppercase tracking-[0.12em] text-destructive font-medium"
      title="Validation failed"
    >
      <XCircle className="h-3.5 w-3.5" strokeWidth={1.75} />
      Failed
    </span>
  );
}

function StatPill({
  label,
  value,
  mono = true,
}: {
  label: string;
  value: React.ReactNode;
  mono?: boolean;
}) {
  return (
    <div className="flex flex-col gap-1">
      <div
        className="mono text-[10px] uppercase tracking-[0.18em] font-semibold"
        style={{ color: "hsl(var(--surface-ink-3))" }}
      >
        {label}
      </div>
      <div
        className={cn(
          "text-[13px]",
          mono && "display mono"
        )}
        style={{ color: "hsl(var(--surface-ink))" }}
      >
        {value}
      </div>
    </div>
  );
}

function ClaimCard837({ claim }: { claim: ClaimOutput }) {
  const [open, setOpen] = useState(false);
  const passed = claim.validation.passed;
  const hasWarnings = claim.validation.warnings.length > 0;
  return (
    <div
      className="rounded-lg overflow-hidden border"
      style={{
        backgroundColor: "hsl(36 22% 96%)",
        borderColor: "hsl(30 14% 14% / 0.10)",
        boxShadow: "inset 0 1px 0 0 hsl(0 0% 100% / 0.5)",
      }}
    >
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        className="w-full text-left px-4 py-3 hover:bg-[hsl(36_22%_92%)] transition-colors"
        aria-expanded={open}
      >
        <div className="flex items-center gap-3">
          <ChevronRight
            className={cn(
              "h-3.5 w-3.5 transition-transform shrink-0",
              open && "rotate-90"
            )}
            strokeWidth={1.75}
            style={{ color: "hsl(var(--surface-ink-3))" }}
          />
          <div className="flex-1 min-w-0">
            <div className="flex items-center gap-2.5 flex-wrap">
              <span
                className="display mono text-[12.5px]"
                style={{ color: "hsl(var(--surface-ink))" }}
              >
                {claim.claim_id}
              </span>
              <span
                className="text-[12px] truncate"
                style={{ color: "hsl(var(--surface-ink-2))" }}
              >
                {claim.subscriber.first_name} {claim.subscriber.last_name}
              </span>
              <span
                className="text-[12px]"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                · {claim.payer.name}
              </span>
            </div>
            <div
              className="mono text-[10.5px] flex items-center gap-2 mt-1"
              style={{ color: "hsl(var(--surface-ink-3))" }}
            >
              <span>NPI {claim.billing_provider.npi}</span>
              <span className="opacity-40">·</span>
              <span>
                {claim.service_lines.length} line
                {claim.service_lines.length === 1 ? "" : "s"}
              </span>
              <span className="opacity-40">·</span>
              <span>{claim.diagnoses.length} dx</span>
            </div>
          </div>
          <div className="text-right shrink-0">
            <div
              className="display mono text-[14px]"
              style={{ color: "hsl(var(--surface-ink))" }}
            >
              {fmt.usdDecimal(claim.claim.total_charge)}
            </div>
            <div className="mt-0.5">
              <ValidationDot passed={passed} hasWarnings={hasWarnings} />
            </div>
          </div>
        </div>
      </button>
      {open ? (
        <div
          className="border-t px-4 py-3 grid gap-4 animate-fade-in"
          style={{
            borderColor: "hsl(30 14% 14% / 0.08)",
            backgroundColor: "hsl(36 22% 92%)",
          }}
        >
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            <StatPill label="Member" value={claim.subscriber.member_id} />
            <StatPill
              label="Place of service"
              value={claim.claim.place_of_service ?? "—"}
            />
            <StatPill label="Frequency" value={claim.claim.frequency_code ?? "—"} />
            <StatPill
              label="Prior auth"
              value={claim.claim.prior_auth ?? "—"}
            />
          </div>

          {claim.diagnoses.length > 0 ? (
            <div>
              <div
                className="mono text-[10px] uppercase tracking-[0.18em] font-semibold mb-1.5"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                Diagnoses
              </div>
              <div className="flex flex-wrap gap-1.5">
                {claim.diagnoses.map((d, i) => (
                  <Badge key={`${d.code}-${i}`} variant="muted">
                    {d.qualifier ? `${d.qualifier}·` : ""}
                    {d.code}
                  </Badge>
                ))}
              </div>
            </div>
          ) : null}

          {claim.service_lines.length > 0 ? (
            <div>
              <div
                className="mono text-[10px] uppercase tracking-[0.18em] font-semibold mb-1.5"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                Service lines
              </div>
              <div
                className="rounded-md border overflow-x-auto"
                style={{
                  borderColor: "hsl(30 14% 14% / 0.10)",
                  backgroundColor: "hsl(36 22% 98%)",
                }}
              >
                <table className="w-full text-[12px]">
                  <thead style={{ backgroundColor: "hsl(36 22% 90%)" }}>
                    <tr className="text-left" style={{ color: "hsl(var(--surface-ink-2))" }}>
                      <th className="px-2.5 py-1.5 font-medium">#</th>
                      <th className="px-2.5 py-1.5 font-medium">Code</th>
                      <th className="px-2.5 py-1.5 font-medium">Mods</th>
                      <th className="px-2.5 py-1.5 font-medium">Date</th>
                      <th className="px-2.5 py-1.5 font-medium">Units</th>
                      <th className="px-2.5 py-1.5 font-medium text-right">Charge</th>
                    </tr>
                  </thead>
                  <tbody>
                    {claim.service_lines.map((line) => (
                      <ServiceLine837Row key={line.line_number} line={line} />
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          ) : null}

          {(claim.validation.errors.length > 0 ||
            claim.validation.warnings.length > 0) ? (
            <div>
              <div
                className="mono text-[10px] uppercase tracking-[0.18em] font-semibold mb-1.5"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                Validation
              </div>
              <ul className="space-y-1 text-[12px]">
                {claim.validation.errors.map((issue, i) => (
                  <li
                    key={`e-${i}`}
                    className="flex items-start gap-2 text-destructive"
                  >
                    <XCircle
                      className="h-3.5 w-3.5 mt-0.5 shrink-0"
                      strokeWidth={1.75}
                    />
                    <span>
                      <span className="mono">{issue.rule}</span> — {issue.message}
                    </span>
                  </li>
                ))}
                {claim.validation.warnings.map((issue, i) => (
                  <li
                    key={`w-${i}`}
                    className="flex items-start gap-2 text-[hsl(var(--warning))]"
                  >
                    <AlertTriangle
                      className="h-3.5 w-3.5 mt-0.5 shrink-0"
                      strokeWidth={1.75}
                    />
                    <span>
                      <span className="mono">{issue.rule}</span> — {issue.message}
                    </span>
                  </li>
                ))}
              </ul>
            </div>
          ) : null}
        </div>
      ) : null}
    </div>
  );
}

function ServiceLine837Row({ line }: { line: ServiceLine }) {
  return (
    <tr
      className="border-t"
      style={{ borderColor: "hsl(30 14% 14% / 0.08)" }}
    >
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink))" }}
      >
        {line.line_number}
      </td>
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink))" }}
      >
        {line.procedure.qualifier}·{line.procedure.code}
      </td>
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink-3))" }}
      >
        {line.procedure.modifiers.length > 0
          ? line.procedure.modifiers.join(", ")
          : "—"}
      </td>
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink-3))" }}
      >
        {line.service_date ?? "—"}
      </td>
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink-3))" }}
      >
        {line.units ? `${toNum(line.units)} ${line.unit_type ?? ""}`.trim() : "—"}
      </td>
      <td
        className="px-2.5 py-1.5 mono text-right display"
        style={{ color: "hsl(var(--surface-ink))" }}
      >
        {fmt.usdDecimal(line.charge)}
      </td>
    </tr>
  );
}

function ClaimCard835({ claim }: { claim: ClaimPayment }) {
  const [open, setOpen] = useState(false);
  const passed = claim.service_payments.length > 0;
  return (
    <div
      className="rounded-lg overflow-hidden border"
      style={{
        backgroundColor: "hsl(36 22% 96%)",
        borderColor: "hsl(30 14% 14% / 0.10)",
        boxShadow: "inset 0 1px 0 0 hsl(0 0% 100% / 0.5)",
      }}
    >
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        className="w-full text-left px-4 py-3 hover:bg-[hsl(36_22%_92%)] transition-colors"
        aria-expanded={open}
      >
        <div className="flex items-center gap-3">
          <ChevronRight
            className={cn(
              "h-3.5 w-3.5 transition-transform shrink-0",
              open && "rotate-90"
            )}
            strokeWidth={1.75}
            style={{ color: "hsl(var(--surface-ink-3))" }}
          />
          <div className="flex-1 min-w-0">
            <div className="flex items-center gap-2.5 flex-wrap">
              <span
                className="display mono text-[12.5px]"
                style={{ color: "hsl(var(--surface-ink))" }}
              >
                {claim.payer_claim_control_number}
              </span>
              <span
                className="text-[12px]"
                style={{ color: "hsl(var(--surface-ink-2))" }}
              >
                {claim.status_label ?? `Status ${claim.status_code}`}
              </span>
            </div>
            <div
              className="mono text-[10.5px] flex items-center gap-2 mt-1"
              style={{ color: "hsl(var(--surface-ink-3))" }}
            >
              <span>CLP {claim.status_code}</span>
              {claim.original_claim_id ? (
                <>
                  <span className="opacity-40">·</span>
                  <span>Orig {claim.original_claim_id}</span>
                </>
              ) : null}
              <span className="opacity-40">·</span>
              <span>{claim.service_payments.length} svc</span>
            </div>
          </div>
          <div className="text-right shrink-0">
            <div
              className="display mono text-[14px] text-[hsl(var(--success))]"
            >
              {fmt.usdDecimal(claim.total_paid)}
            </div>
            <div
              className="mono text-[10.5px]"
              style={{ color: "hsl(var(--surface-ink-3))" }}
            >
              of {fmt.usdDecimal(claim.total_charge)}
            </div>
            <div className="mt-0.5">
              <ValidationDot passed={passed} />
            </div>
          </div>
        </div>
      </button>
      {open ? (
        <div
          className="border-t px-4 py-3 grid gap-4 animate-fade-in"
          style={{
            borderColor: "hsl(30 14% 14% / 0.08)",
            backgroundColor: "hsl(36 22% 92%)",
          }}
        >
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            <StatPill label="Filing" value={claim.claim_filing_indicator ?? "—"} />
            <StatPill label="Facility" value={claim.facility_type ?? "—"} />
            <StatPill label="Frequency" value={claim.frequency_code ?? "—"} />
            <StatPill
              label="Patient resp"
              value={
                claim.patient_responsibility
                  ? fmt.usdDecimal(claim.patient_responsibility)
                  : "—"
              }
            />
          </div>

          {claim.service_payments.length > 0 ? (
            <div>
              <div
                className="mono text-[10px] uppercase tracking-[0.18em] font-semibold mb-1.5"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                Service payments
              </div>
              <div
                className="rounded-md border overflow-x-auto"
                style={{
                  borderColor: "hsl(30 14% 14% / 0.10)",
                  backgroundColor: "hsl(36 22% 98%)",
                }}
              >
                <table className="w-full text-[12px]">
                  <thead style={{ backgroundColor: "hsl(36 22% 90%)" }}>
                    <tr className="text-left" style={{ color: "hsl(var(--surface-ink-2))" }}>
                      <th className="px-2.5 py-1.5 font-medium">#</th>
                      <th className="px-2.5 py-1.5 font-medium">Code</th>
                      <th className="px-2.5 py-1.5 font-medium">Mods</th>
                      <th className="px-2.5 py-1.5 font-medium">Date</th>
                      <th className="px-2.5 py-1.5 font-medium">Units</th>
                      <th className="px-2.5 py-1.5 font-medium text-right">Charge</th>
                      <th className="px-2.5 py-1.5 font-medium text-right">Paid</th>
                    </tr>
                  </thead>
                  <tbody>
                    {claim.service_payments.map((svc) => (
                      <ServicePaymentRow key={svc.line_number} svc={svc} />
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          ) : null}
        </div>
      ) : null}
    </div>
  );
}

function ServicePaymentRow({ svc }: { svc: ServicePayment }) {
  return (
    <tr
      className="border-t"
      style={{ borderColor: "hsl(30 14% 14% / 0.08)" }}
    >
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink))" }}
      >
        {svc.line_number}
      </td>
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink))" }}
      >
        {svc.procedure_qualifier}·{svc.procedure_code}
      </td>
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink-3))" }}
      >
        {svc.modifiers.length > 0 ? svc.modifiers.join(", ") : "—"}
      </td>
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink-3))" }}
      >
        {svc.service_date ?? "—"}
      </td>
      <td
        className="px-2.5 py-1.5 mono"
        style={{ color: "hsl(var(--surface-ink-3))" }}
      >
        {svc.units ? `${toNum(svc.units)} ${svc.unit_type ?? ""}`.trim() : "—"}
      </td>
      <td
        className="px-2.5 py-1.5 mono text-right display"
        style={{ color: "hsl(var(--surface-ink))" }}
      >
        {fmt.usdDecimal(svc.charge)}
      </td>
      <td
        className="px-2.5 py-1.5 mono text-right display text-[hsl(var(--success))]"
      >
        {fmt.usdDecimal(svc.payment)}
      </td>
    </tr>
  );
}

// ---------------------------------------------------------------------------
// Page
// ---------------------------------------------------------------------------

export function Upload() {
  const inputRef = useRef<HTMLInputElement>(null);
  const [file, setFile] = useState<File | null>(null);
  const [kind, setKind] = useState<ParsedBatchKind>("837p");
  const [payer, setPayer] = useState<string>(PAYERS_837[0]!.value);
  const [stream, setStream] = useState<StreamState>({
    items: [],
    expectedTotal: null,
    passed: 0,
    failed: 0,
  });
  const [dragging, setDragging] = useState(false);
  const addParsedBatch = useAppStore((s) => s.addParsedBatch);
  const parsedBatches = useAppStore((s) => s.parsedBatches);
  const parseMutation = useParse(kind);

  const payerOptions = kind === "837p" ? PAYERS_837 : PAYERS_835;

  const expectedTotal = stream.expectedTotal;
  const totalSoFar = stream.items.length;
  const running = parseMutation.isPending;
  const progressPct = useMemo(() => {
    if (!expectedTotal || expectedTotal <= 0) return 0;
    return Math.min(100, Math.round((totalSoFar / expectedTotal) * 100));
  }, [expectedTotal, totalSoFar]);

  function pickFile(f: File | null) {
    setFile(f);
    setStream({ items: [], expectedTotal: null, passed: 0, failed: 0 });
  }

  async function onParse() {
    if (!file) return;
    if (!api.isConfigured) {
      toast.error(
        "Backend not configured. Set VITE_API_BASE_URL in .env.local to use the Upload page."
      );
      return;
    }
    setStream({ items: [], expectedTotal: null, passed: 0, failed: 0 });
    const items: StreamedClaim[] = [];
    const onProgress: ParseProgress = (event) => {
      if (event.type === "claim") {
        items.push({ kind: "837p", data: event.data });
        setStream((s) => ({
          ...s,
          items: [...items],
        }));
      } else if (event.type === "claim_payment") {
        items.push({ kind: "835", data: event.data });
        setStream((s) => ({
          ...s,
          items: [...items],
        }));
      } else if (event.type === "summary") {
        setStream((s) => ({
          ...s,
          expectedTotal: event.data.total_claims,
          passed: event.data.passed,
          failed: event.data.failed,
        }));
      }
    };

    try {
      const summary = await parseMutation.mutateAsync({
        file,
        options: { payer, onProgress },
      });

      const finalSummary =
        summary && typeof summary === "object" && "total_claims" in summary
          ? summary
          : null;

      if (finalSummary) {
        const id = `BATCH-${Date.now()}`;
        const claimIds = items
          .map((c) =>
            c.kind === "837p" ? c.data.claim_id : c.data.payer_claim_control_number
          )
          .filter(Boolean);
        const batch: ParsedBatch = {
          id,
          kind,
          inputFilename: file.name,
          parsedAt: new Date().toISOString(),
          claimCount: finalSummary.total_claims,
          passed: finalSummary.passed,
          failed: finalSummary.failed,
          claimIds,
          summary: finalSummary,
        };
        addParsedBatch(batch);
        toast.success(
          `Parsed ${finalSummary.total_claims} ${kind === "837p" ? "claims" : "payments"} · ${
            finalSummary.passed
          } passed · ${finalSummary.failed} failed`,
          { description: file.name }
        );
      }
    } catch (err) {
      toast.error(
        err instanceof Error ? err.message : "Failed to parse file"
      );
    }
  }

  function onDrop(e: React.DragEvent<HTMLDivElement>) {
    e.preventDefault();
    setDragging(false);
    const f = e.dataTransfer.files?.[0];
    if (f) pickFile(f);
  }

  // -----------------------------------------------------------------
  // Stagger choreography
  // -----------------------------------------------------------------
  const heroDelay = 0;
  const foldDelay = 220;
  const titleDelay = 320;
  const dropDelay = 460;
  const streamDelay = 620;
  const batchesDelay = 760;

  return (
    <div className="space-y-0">
      {/* =================================================================
          HERO — DARK EDITORIAL HEADER
          Larger and bolder than the default PageHeader. The "X12"
          wordmark sits italic as the page's anchor, and a ghost
          "DROP" watermark fills the right side as a print-shop stamp.
          ================================================================= */}
      <section
        className="relative animate-fade-in pt-6 pb-8 lg:pt-9 lg:pb-10"
        style={{ animationDelay: `${heroDelay}ms` }}
      >
        {/* Ghost wordmark — a large faded "DROP" stamp behind the title */}
        <div
          aria-hidden="true"
          className="pointer-events-none select-none absolute inset-x-0 top-[58%] -translate-y-1/2 whitespace-nowrap display text-center"
          style={{
            fontSize: "clamp(160px, 22vw, 320px)",
            letterSpacing: "-0.05em",
            opacity: 0.045,
            lineHeight: 1,
            color: "hsl(var(--surface-ink))",
          }}
        >
          DROP
        </div>

        <div className="relative z-10 max-w-3xl">
          <div className="flex items-center gap-3 mb-5">
            <div className="h-px w-14 bg-foreground/25" />
            <span className="mono text-[12px] uppercase tracking-[0.22em] text-muted-foreground">
              Upload · EDI parser
            </span>
            <span
              className="mono text-[12px] uppercase tracking-[0.22em] text-muted-foreground/60 hidden sm:inline"
              aria-hidden
            >
              · {api.isConfigured ? "ready" : "no backend"}
            </span>
          </div>

          <h1 className="display text-[48px] sm:text-[64px] lg:text-[80px] leading-[0.92] text-foreground tracking-[-0.04em]">
            Parse an{" "}
            <span className="italic text-muted-foreground/85">X12</span>
            <br />
            file.
          </h1>

          <p className="text-[14px] text-muted-foreground mt-5 max-w-xl leading-relaxed">
            Drop an 837P professional claim or 835 ERA remittance file. The
            parser streams claims back as they're produced so the UI updates
            in real time.
          </p>
        </div>
      </section>

      {/* =================================================================
          FOLD — TORN PAGE
          ================================================================= */}
      <div
        aria-hidden
        className="relative h-14 animate-fade-in"
        style={{ animationDelay: `${foldDelay}ms` }}
      >
        <div
          className="absolute inset-x-0 top-0 h-1/2"
          style={{
            background:
              "linear-gradient(to bottom, hsl(0 0% 0% / 0.55), transparent)",
          }}
        />
        <div
          className="absolute inset-x-0 bottom-0 h-1/2"
          style={{
            background:
              "linear-gradient(to top, hsl(30 14% 14% / 0.18), transparent)",
          }}
        />
        <div
          className="absolute inset-x-0 top-1/2 -translate-y-1/2 h-px"
          style={{
            background:
              "linear-gradient(to right, transparent, hsl(30 14% 14% / 0.5) 12%, hsl(30 14% 14% / 0.7) 50%, hsl(30 14% 14% / 0.5) 88%, transparent)",
          }}
        />
        <div
          className="absolute inset-x-0 top-1/2 -translate-y-1/2 flex justify-between px-2"
          style={{ pointerEvents: "none" }}
        >
          {Array.from({ length: 48 }, (_, i) => (
            <span
              key={i}
              className="block h-[3px] w-[3px] rounded-full"
              style={{ backgroundColor: "hsl(30 14% 14% / 0.22)" }}
            />
          ))}
        </div>
        <div className="relative z-10 mx-auto h-full flex items-center justify-center gap-3 bg-background px-4 w-fit">
          <span
            className="display italic"
            style={{ color: "hsl(var(--muted-foreground))", fontSize: 15 }}
          >
            ↘
          </span>
          <span
            className="mono uppercase tracking-[0.24em]"
            style={{
              color: "hsl(var(--muted-foreground))",
              fontSize: 11,
              fontWeight: 500,
            }}
          >
            Drop &amp; parse
          </span>
          <span
            className="display italic"
            style={{ color: "hsl(var(--muted-foreground))", fontSize: 15 }}
          >
            ↙
          </span>
        </div>
      </div>

      {/* =================================================================
          PAPER PLANE — DROP ZONE
          Title block → dropzone → stream results → recent batches
          ================================================================= */}
      <div
        className="relative max-w-[1280px] mx-auto animate-fade-in-up"
        style={{
          animationDelay: `${titleDelay}ms`,
          backgroundColor: "hsl(var(--surface))",
          boxShadow:
            "inset 0 1px 0 0 hsl(0 0% 100% / 0.5), 0 1px 0 0 hsl(30 14% 22% / 0.06), 0 30px 80px -24px hsl(0 0% 0% / 0.45)",
        }}
      >
        {/* Paper grain */}
        <div
          aria-hidden
          className="pointer-events-none absolute inset-0 opacity-[0.04]"
          style={{
            backgroundImage:
              "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.1  0 0 0 0 0.08  0 0 0 0 0.05  0 0 0 0.9 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>\")",
            backgroundSize: "160px 160px",
            mixBlendMode: "multiply",
          }}
        />

        {/* Title block */}
        <div className="relative px-8 lg:px-14 pt-12 pb-9 border-b border-[hsl(30_14%_14%/_0.12)]">
          <div
            aria-hidden
            className="absolute left-7 lg:left-12 top-0 bottom-0 w-px"
            style={{ backgroundColor: "hsl(30 14% 14% / 0.14)" }}
          />
          <div className="flex items-end justify-between gap-8 flex-wrap">
            <div>
              <div
                className="mono text-[12px] uppercase tracking-[0.24em] mb-4 font-medium"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                Ingestion · Sheet 01
              </div>
              <h2
                className="display leading-[0.92] tracking-[-0.04em]"
                style={{
                  color: "hsl(var(--surface-ink))",
                  fontSize: "clamp(48px, 7vw, 96px)",
                  fontWeight: 400,
                }}
              >
                Drop a file.
              </h2>
              <div
                className="mt-4 display italic"
                style={{
                  color: "hsl(var(--surface-ink-2))",
                  fontSize: "clamp(15px, 1.3vw, 18px)",
                  lineHeight: 1.4,
                  maxWidth: "32ch",
                }}
              >
                The X12 837/835 file as exported from your clearinghouse.
                The parser handles validation, line items, and service
                payments on the way in.
              </div>
            </div>
            <div className="text-right shrink-0">
              <div
                className="mono text-[11px] uppercase tracking-[0.24em] mb-1.5 font-medium"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                Accepts
              </div>
              <div
                className="display tabular-nums"
                style={{
                  color: "hsl(var(--surface-ink))",
                  fontSize: 26,
                  lineHeight: 1.1,
                }}
              >
                .txt
              </div>
              <div
                className="mono text-[11px] mt-1"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                837P · 835
              </div>
              <div
                className={cn(
                  "mt-4 inline-flex items-center gap-1.5 rounded-sm border px-2 py-1"
                )}
                style={{
                  borderColor: api.isConfigured
                    ? "hsl(30 14% 14% / 0.18)"
                    : "hsl(36 92% 50% / 0.45)",
                  color: api.isConfigured
                    ? "hsl(var(--surface-ink-2))"
                    : "hsl(36 92% 28%)",
                }}
              >
                <span
                  className="block h-1.5 w-1.5 rounded-full"
                  style={{
                    backgroundColor: api.isConfigured
                      ? "hsl(152 64% 38%)"
                      : "hsl(36 92% 50%)",
                  }}
                />
                <span className="mono text-[10px] uppercase tracking-[0.18em]">
                  {api.isConfigured ? "Backend ready" : "No backend"}
                </span>
              </div>
            </div>
          </div>
        </div>

        {/* DROP ZONE — section § 01 */}
        <section
          aria-label="File upload"
          className="relative px-8 lg:px-14 py-8 lg:py-10 animate-fade-in-up"
          style={{ animationDelay: `${dropDelay}ms` }}
        >
          {/* Folio */}
          <div
            aria-hidden
            className="absolute left-7 lg:left-12 top-9 flex flex-col items-center gap-1"
          >
            <span
              className="mono text-[10px] uppercase tracking-[0.18em] font-semibold"
              style={{ color: "hsl(var(--surface-ink-3))" }}
            >
              § 01
            </span>
            <div
              className="w-px h-12"
              style={{ backgroundColor: "hsl(30 14% 14% / 0.18)" }}
            />
            <span
              className="display italic"
              style={{
                color: "hsl(var(--surface-ink-2))",
                fontSize: 11,
                writingMode: "vertical-rl",
                transform: "rotate(180deg)",
                letterSpacing: "0.16em",
              }}
            >
              The drop
            </span>
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-5">
            <div className="grid gap-1.5">
              <div
                className="mono text-[10px] uppercase tracking-[0.18em] font-semibold"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                Kind
              </div>
              <Select
                value={kind}
                onValueChange={(v) => {
                  const next = v as ParsedBatchKind;
                  setKind(next);
                  setPayer(
                    next === "837p" ? PAYERS_837[0]!.value : PAYERS_835[0]!.value
                  );
                }}
              >
                <SelectTrigger
                  className="border-[hsl(30_14%_14%/_0.16)] bg-[hsl(36_22%_98%)] text-foreground"
                >
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="837p">837P (Professional claim)</SelectItem>
                  <SelectItem value="835">835 (ERA remittance)</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="grid gap-1.5">
              <div
                className="mono text-[10px] uppercase tracking-[0.18em] font-semibold"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                Payer config
              </div>
              <Select value={payer} onValueChange={setPayer}>
                <SelectTrigger
                  className="border-[hsl(30_14%_14%/_0.16)] bg-[hsl(36_22%_98%)] text-foreground"
                >
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {payerOptions.map((p) => (
                    <SelectItem key={p.value} value={p.value}>
                      {p.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          <div
            onDragOver={(e) => {
              e.preventDefault();
              setDragging(true);
            }}
            onDragLeave={() => setDragging(false)}
            onDrop={onDrop}
            onClick={() => inputRef.current?.click()}
            role="button"
            tabIndex={0}
            onKeyDown={(e) => {
              if (e.key === "Enter" || e.key === " ") inputRef.current?.click();
            }}
            className={cn(
              "relative flex flex-col items-center justify-center gap-2 rounded-lg border border-dashed transition-colors",
              "px-6 py-14 min-h-[180px] cursor-pointer",
              dragging
                ? "border-[hsl(212_100%_45%)] bg-[hsl(212_85%_95%)] ring-2 ring-[hsl(212_100%_45%_/_0.25)]"
                : "border-[hsl(30_14%_14%/_0.22)] bg-[hsl(36_22%_98%)] hover:bg-[hsl(36_22%_94%)] hover:border-[hsl(30_14%_14%/_0.35)]",
              "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(212_100%_45%_/_0.4)]"
            )}
          >
            <div
              className={cn(
                "h-12 w-12 rounded-md ring-1 ring-inset flex items-center justify-center transition-colors",
                dragging
                  ? "bg-[hsl(212_85%_88%)] text-[hsl(212_100%_35%)] ring-[hsl(212_100%_45%_/_0.4)]"
                  : "bg-[hsl(36_22%_92%)] ring-[hsl(30_14%_14%/_0.10)]"
              )}
              style={!dragging ? { color: "hsl(var(--surface-ink-2))" } : undefined}
            >
              {dragging ? (
                <CloudUpload className="h-5 w-5" strokeWidth={1.5} />
              ) : (
                <UploadIcon className="h-5 w-5" strokeWidth={1.5} />
              )}
            </div>
            {file ? (
              <div className="flex items-center gap-2 text-[14px] mt-1">
                <FileText
                  className="h-4 w-4"
                  strokeWidth={1.75}
                  style={{ color: "hsl(var(--surface-ink-2))" }}
                />
                <span
                  className="font-medium"
                  style={{ color: "hsl(var(--surface-ink))" }}
                >
                  {file.name}
                </span>
                <span
                  className="mono"
                  style={{ color: "hsl(var(--surface-ink-3))" }}
                >
                  · {formatBytes(file.size)}
                </span>
              </div>
            ) : (
              <>
                <div
                  className="text-[15px] font-medium mt-1"
                  style={{ color: "hsl(var(--surface-ink))" }}
                >
                  {dragging
                    ? "Release to upload"
                    : "Drop a file here, or click to choose"}
                </div>
                <div
                  className="mono text-[11px] uppercase tracking-[0.16em]"
                  style={{ color: "hsl(var(--surface-ink-3))" }}
                >
                  .txt — the X12 837/835 file as exported from your
                  clearinghouse
                </div>
              </>
            )}
            <input
              ref={inputRef}
              type="file"
              accept=".txt"
              className="sr-only"
              onChange={(e) => pickFile(e.target.files?.[0] ?? null)}
            />
          </div>

          <div
            className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between mt-5 pt-5 border-t"
            style={{ borderColor: "hsl(30 14% 14% / 0.10)" }}
          >
            <div
              className="mono text-[11px]"
              style={{ color: "hsl(var(--surface-ink-3))" }}
            >
              {api.isConfigured ? (
                <span className="inline-flex items-center gap-1.5">
                  <span className="h-1.5 w-1.5 rounded-full bg-[hsl(152_64%_38%)]" />
                  Backend ready · {api.baseUrl}
                </span>
              ) : (
                <span
                  className="inline-flex items-center gap-1.5"
                  style={{ color: "hsl(36 92% 28%)" }}
                >
                  <AlertTriangle className="h-3 w-3" strokeWidth={1.75} />
                  No backend configured — set VITE_API_BASE_URL to enable
                  parsing
                </span>
              )}
            </div>
            <div className="flex items-center gap-2 flex-wrap">
              {file ? (
                <Button
                  variant="ghost"
                  onClick={() => pickFile(null)}
                  disabled={running}
                  className="min-h-[44px] sm:min-h-0"
                >
                  Clear
                </Button>
              ) : null}
              <Button
                onClick={onParse}
                disabled={!file || running}
                className="min-h-[44px] sm:min-h-0"
              >
                {running ? (
                  <>
                    <Loader2 className="h-3.5 w-3.5 animate-spin" />
                    Parsing…
                  </>
                ) : (
                  <>
                    <UploadIcon className="h-3.5 w-3.5" />
                    Parse
                  </>
                )}
              </Button>
            </div>
          </div>
        </section>

        {/* STREAM RESULTS — section § 02 */}
        {(running || stream.items.length > 0) ? (
          <section
            aria-label="Parse stream"
            className="relative px-8 lg:px-14 pb-8 lg:pb-10 animate-fade-in-up"
            style={{ animationDelay: `${streamDelay}ms` }}
          >
            <div
              aria-hidden
              className="absolute left-7 lg:left-12 top-9 flex flex-col items-center gap-1"
            >
              <span
                className="mono text-[10px] uppercase tracking-[0.18em] font-semibold"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                § 02
              </span>
              <div
                className="w-px h-12"
                style={{ backgroundColor: "hsl(30 14% 14% / 0.18)" }}
              />
              <span
                className="display italic"
                style={{
                  color: "hsl(var(--surface-ink-2))",
                  fontSize: 11,
                  writingMode: "vertical-rl",
                  transform: "rotate(180deg)",
                  letterSpacing: "0.16em",
                }}
              >
                The stream
              </span>
            </div>

            <div
              className="pt-6 border-t"
              style={{
                borderTopStyle: "double",
                borderTopWidth: 3,
                borderColor: "hsl(30 14% 14% / 0.12)",
              }}
            >
              <div className="flex items-end justify-between gap-6 flex-wrap mb-4">
                <div>
                  <div
                    className="mono text-[11.5px] uppercase tracking-[0.24em] font-semibold mb-2"
                    style={{ color: "hsl(var(--surface-ink-3))" }}
                  >
                    The stream
                  </div>
                  <h3
                    className="display leading-[0.98] tracking-[-0.03em]"
                    style={{
                      color: "hsl(var(--surface-ink))",
                      fontSize: "clamp(24px, 2.6vw, 32px)",
                      fontWeight: 400,
                    }}
                  >
                    {running ? (
                      <>
                        Parsing{" "}
                        <span className="italic">live.</span>
                      </>
                    ) : (
                      <>
                        Stream{" "}
                        <span className="italic">complete.</span>
                      </>
                    )}
                  </h3>
                </div>
                <div className="flex items-center gap-6">
                  <div>
                    <div
                      className="mono text-[10px] uppercase tracking-[0.18em] font-semibold"
                      style={{ color: "hsl(var(--surface-ink-3))" }}
                    >
                      Parsed
                    </div>
                    <div
                      className="display mono tabular-nums"
                      style={{
                        color: "hsl(var(--surface-ink))",
                        fontSize: 22,
                      }}
                    >
                      {totalSoFar}
                      <span
                        className="text-[14px]"
                        style={{ color: "hsl(var(--surface-ink-3))" }}
                      >
                        {" "}
                        / {expectedTotal ?? "?"}
                      </span>
                    </div>
                  </div>
                  <div className="text-right">
                    <div
                      className="mono text-[10px] uppercase tracking-[0.18em] font-semibold"
                      style={{ color: "hsl(var(--surface-ink-3))" }}
                    >
                      Progress
                    </div>
                    <div
                      className="display mono tabular-nums"
                      style={{
                        color: "hsl(var(--surface-ink))",
                        fontSize: 22,
                      }}
                    >
                      {expectedTotal ? `${progressPct}%` : "…"}
                    </div>
                  </div>
                </div>
              </div>

              <div
                className="mt-3 h-1.5 w-full rounded-full overflow-hidden"
                style={{ backgroundColor: "hsl(30 14% 14% / 0.08)" }}
              >
                <div
                  className="h-full transition-[width] duration-200"
                  style={{
                    width: `${progressPct}%`,
                    background:
                      "linear-gradient(to right, hsl(212 100% 60%), hsl(152 64% 38%))",
                  }}
                />
              </div>

              <div className="mt-5 max-h-[640px] overflow-y-auto -mx-2 px-2 space-y-2">
                {stream.items.length === 0 && running ? (
                  <div
                    className="text-center py-10 text-[12.5px] display italic"
                    style={{ color: "hsl(var(--surface-ink-3))" }}
                  >
                    Waiting for first claim…
                  </div>
                ) : null}
                {stream.items.map((item, i) =>
                  item.kind === "837p" ? (
                    <ClaimCard837
                      key={`837-${item.data.claim_id}-${i}`}
                      claim={item.data}
                    />
                  ) : (
                    <ClaimCard835
                      key={`835-${item.data.payer_claim_control_number}-${i}`}
                      claim={item.data}
                    />
                  )
                )}
              </div>
            </div>
          </section>
        ) : null}

        {/* RECENT BATCHES — section § 03 */}
        {parsedBatches.length > 0 ? (
          <section
            aria-label="Recent batches"
            className="relative px-8 lg:px-14 pb-8 animate-fade-in-up"
            style={{ animationDelay: `${batchesDelay}ms` }}
          >
            <div
              aria-hidden
              className="absolute left-7 lg:left-12 top-9 flex flex-col items-center gap-1"
            >
              <span
                className="mono text-[10px] uppercase tracking-[0.18em] font-semibold"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                § 03
              </span>
              <div
                className="w-px h-12"
                style={{ backgroundColor: "hsl(30 14% 14% / 0.18)" }}
              />
              <span
                className="display italic"
                style={{
                  color: "hsl(var(--surface-ink-2))",
                  fontSize: 11,
                  writingMode: "vertical-rl",
                  transform: "rotate(180deg)",
                  letterSpacing: "0.16em",
                }}
              >
                The archive
              </span>
            </div>

            <div
              className="pt-6 border-t"
              style={{ borderColor: "hsl(30 14% 14% / 0.10)" }}
            >
              <div className="flex items-end justify-between gap-6 flex-wrap mb-4">
                <div>
                  <div
                    className="mono text-[11.5px] uppercase tracking-[0.24em] font-semibold mb-2"
                    style={{ color: "hsl(var(--surface-ink-3))" }}
                  >
                    The archive
                  </div>
                  <h3
                    className="display leading-[0.98] tracking-[-0.03em]"
                    style={{
                      color: "hsl(var(--surface-ink))",
                      fontSize: "clamp(24px, 2.6vw, 32px)",
                      fontWeight: 400,
                    }}
                  >
                    Recent <span className="italic">batches.</span>
                  </h3>
                </div>
                <div className="text-right">
                  <div
                    className="mono text-[10px] uppercase tracking-[0.18em] font-semibold"
                    style={{ color: "hsl(var(--surface-ink-3))" }}
                  >
                    Total
                  </div>
                  <div
                    className="display mono tabular-nums"
                    style={{
                      color: "hsl(var(--surface-ink))",
                      fontSize: 22,
                    }}
                  >
                    {parsedBatches.length}
                  </div>
                </div>
              </div>
              <ul
                className="divide-y"
                style={{ borderColor: "hsl(30 14% 14% / 0.08)" }}
              >
                {parsedBatches.map((b) => (
                  <li
                    key={b.id}
                    className="flex items-center gap-3 py-3.5 first:pt-0 last:pb-0"
                  >
                    <Badge variant={b.kind === "837p" ? "default" : "muted"}>
                      {b.kind === "837p" ? "837P" : "835"}
                    </Badge>
                    <div className="flex-1 min-w-0">
                      <div
                        className="text-[13.5px] font-medium truncate"
                        style={{ color: "hsl(var(--surface-ink))" }}
                      >
                        {b.inputFilename}
                      </div>
                      <div
                        className="mono text-[10.5px]"
                        style={{ color: "hsl(var(--surface-ink-3))" }}
                      >
                        {fmt.dateShort(b.parsedAt)} · {b.claimCount}{" "}
                        {b.kind === "837p" ? "claims" : "payments"}
                      </div>
                    </div>
                    <div className="text-right shrink-0">
                      <div
                        className="display mono text-[13px]"
                        style={{ color: "hsl(var(--surface-ink))" }}
                      >
                        {b.passed} / {b.claimCount}
                      </div>
                      <div
                        className="mono text-[10.5px]"
                        style={{ color: "hsl(var(--surface-ink-3))" }}
                      >
                        passed
                      </div>
                    </div>
                  </li>
                ))}
              </ul>
            </div>
          </section>
        ) : null}

        {/* Inbox prompt when nothing parsed yet */}
        {parsedBatches.length === 0 && stream.items.length === 0 && !running ? (
          <div className="relative px-8 lg:px-14 pb-10 animate-fade-in-up">
            <div
              className="border border-dashed rounded-md py-10 px-6 text-center"
              style={{ borderColor: "hsl(30 14% 14% / 0.16)" }}
            >
              <Inbox
                className="h-6 w-6 mx-auto mb-2"
                strokeWidth={1.5}
                style={{ color: "hsl(var(--surface-ink-3))" }}
              />
              <div
                className="display italic mb-1.5"
                style={{ color: "hsl(var(--surface-ink-2))", fontSize: 17 }}
              >
                No batches yet.
              </div>
              <div
                className="mono text-[11px] uppercase tracking-[0.16em]"
                style={{ color: "hsl(var(--surface-ink-3))" }}
              >
                Drop a file above to start a parse.
              </div>
            </div>
          </div>
        ) : null}

        {/* Footer */}
        <div
          className="relative px-8 lg:px-14 py-5 border-t flex items-center justify-between mono text-[10.5px] uppercase tracking-[0.18em]"
          style={{
            borderColor: "hsl(30 14% 14% / 0.12)",
            color: "hsl(var(--surface-ink-3))",
          }}
        >
          <span>End of sheet 01</span>
          <span>Cyclone · Ingestion</span>
          <span>
            {parsedBatches.length}{" "}
            {parsedBatches.length === 1 ? "batch" : "batches"}
          </span>
        </div>
      </div>
    </div>
  );
}
