import { useState } from "react";
import { Download } from "lucide-react";
import { Badge, type BadgeProps } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { DrillDrawerHeader } from "@/components/drill/DrillDrawerHeader";
import { api } from "@/lib/api";
import { downloadTextFile } from "@/lib/download";
import { fmt } from "@/lib/format";
import type { ClaimDetail } from "@/types";

type ClaimDrawerHeaderProps = {
  claim: ClaimDetail;
  onClose: () => void;
  /**
   * Optional toast callback for surfacing download failures (network error,
   * 404 if the claim was deleted out from under us, 422 if the stored
   * payload can't be regenerated). Defaults to a no-op so consumers that
   * don't wire a toast still get the happy-path download.
   */
  onError?: (message: string) => void;
};

/**
 * State → Badge variant. The state machine value (see
 * `cyclone.db.ClaimState`) drives a color-coded chip so the user can
 * scan the drawer's status at a glance:
 *
 *   submitted  → secondary   (neutral, in-flight)
 *   accepted   → default     (brand-colored, accepted by payer)
 *   matched    → success     (paired with an ERA)
 *   paid       → success     (funds received)
 *   denied     → destructive (needs attention)
 *   pending    → warning     (waiting on something)
 *   anything else → muted
 */
const STATE_VARIANT: Record<string, BadgeProps["variant"]> = {
  submitted: "secondary",
  accepted: "default",
  matched: "success",
  paid: "success",
  denied: "destructive",
  pending: "warning",
};

function badgeVariantFor(state: string): BadgeProps["variant"] {
  return STATE_VARIANT[state] ?? "muted";
}

/**
 * Header band for the claim detail drawer (SP4 → refactored SP21
 * Phase 5 Task 5.10).
 *
 * The shell is now the shared `DrillDrawerHeader` (same as
 * `ProviderDrawer` / `AckDrawer`) — eyebrow + title on the left,
 * close button on the right. The right-side `action` slot carries
 * the state badge, total billed amount, and the "Download 837"
 * button, all of which used to live in a custom <header> block.
 *
 * Top-left: instrument-style "Claim" eyebrow + the claim ID.
 * Top-right: state badge + total billed amount + download button.
 * The badge color encodes state so the user can read the drawer's
 * status at a glance without scrolling.
 */
export function ClaimDrawerHeader({
  claim,
  onClose,
  onError,
}: ClaimDrawerHeaderProps) {
  // Local "is downloading" flag so the button can show feedback while the
  // fetch is in flight. The header is rendered above the fold, so a stuck
  // spinner is the difference between "the click did something" and "did
  // my click even register?"
  const [downloading, setDownloading] = useState(false);

  async function handleDownload() {
    if (downloading) return;
    setDownloading(true);
    try {
      const { text, filename } = await api.serializeClaim837(claim.id);
      downloadTextFile(filename, "text/x12", text);
    } catch (err) {
      const message =
        err instanceof Error ? err.message : "Failed to download 837 file.";
      onError?.(message);
    } finally {
      setDownloading(false);
    }
  }

  // The action slot is rendered by DrillDrawerHeader to the left of
  // the close button. Group the three action pieces (badge, amount,
  // download) in a single flex row so they read as a unit.
  const action = (
    <div className="flex items-center gap-2" data-testid="claim-header-actions">
      <div className="flex items-center gap-2">
        <Badge
          variant={badgeVariantFor(claim.state)}
          data-testid="header-state"
          className="uppercase tracking-[0.14em]"
        >
          {claim.stateLabel}
        </Badge>
        <span
          data-testid="header-amount"
          className="mono text-sm tabular-nums text-muted-foreground"
        >
          {fmt.usdPrecise(claim.billedAmount)}
        </span>
      </div>
      <Button
        variant="ghost"
        size="icon"
        onClick={handleDownload}
        disabled={downloading}
        aria-label={downloading ? "Downloading 837 file" : "Download 837 file"}
        title="Download 837 file"
        data-testid="header-download-837"
      >
        <Download className="h-4 w-4" strokeWidth={1.75} />
      </Button>
    </div>
  );

  return (
    <header data-testid="claim-drawer-header">
      <DrillDrawerHeader
        eyebrow="Claim"
        title={claim.id}
        onClose={onClose}
        action={action}
      />
    </header>
  );
}
