// ---------------------------------------------------------------------------
// HBarChart — horizontal bar chart for ranked lists (e.g. Top Providers).
//
// Each row gets a label slot on the left, a bar that grows from 0 to
// its value on mount, and a trailing value. Bars share a common scale
// derived from the max value. Designed for 4–8 rows; collapses to a
// list if rows are empty. Paper-friendly: cream background, dark ink.
// ---------------------------------------------------------------------------

import { useEffect, useRef, useState } from "react";
import { cn } from "@/lib/utils";

export interface HBarRow {
  /** Stable id used as React key. */
  id: string;
  /** Left label (e.g. provider name). */
  label: string;
  /** Sub-label under the row (e.g. NPI). Optional. */
  sublabel?: string;
  /** Bar value. */
  value: number;
  /** Optional pre-formatted trailing value. Defaults to fmt.num(value). */
  formatted?: string;
  /** Optional color override. Defaults to --accent. */
  color?: string;
  /** Optional leading slot (icon, initials avatar, etc). */
  leading?: React.ReactNode;
}

export interface HBarChartProps {
  rows: HBarRow[];
  /** Bar fill colour when a row doesn't override. Defaults to accent. */
  defaultColor?: string;
  /** Pixel height of each row. Default 44. */
  rowHeight?: number;
  /** Compact mode: smaller text, tighter padding. */
  compact?: boolean;
  /** Optional click handler. */
  onRowClick?: (id: string) => void;
}

export function HBarChart({
  rows,
  defaultColor = "hsl(var(--accent))",
  rowHeight = 44,
  compact = false,
  onRowClick,
}: HBarChartProps) {
  const wrapRef = useRef<HTMLDivElement | null>(null);
  const [labelW, setLabelW] = useState(180);

  useEffect(() => {
    const el = wrapRef.current;
    if (!el) return;
    const ro = new ResizeObserver((entries) => {
      const w = entries[0]?.contentRect.width ?? 800;
      // Reserve ~38% of width for label + leading slot, capped between
      // 140 and 260 so bars stay readable on wide and narrow layouts.
      setLabelW(Math.max(140, Math.min(260, Math.floor(w * 0.38))));
    });
    ro.observe(el);
    setLabelW(Math.max(140, Math.min(260, Math.floor(el.clientWidth * 0.38))));
    return () => ro.disconnect();
  }, []);

  if (rows.length === 0) {
    return (
      <div
        className="mono text-[11px] py-6 text-center"
        style={{ color: "hsl(var(--surface-ink-3))" }}
      >
        No data yet.
      </div>
    );
  }

  const max = Math.max(...rows.map((r) => r.value), 1);

  return (
    <div ref={wrapRef} className="w-full">
      {rows.map((r, i) => {
        const pct = (r.value / max) * 100;
        const color = r.color ?? defaultColor;
        return (
          <div
            key={r.id}
            role={onRowClick ? "button" : undefined}
            tabIndex={onRowClick ? 0 : undefined}
            onClick={onRowClick ? () => onRowClick(r.id) : undefined}
            onKeyDown={
              onRowClick
                ? (e) => {
                    if (e.key === "Enter" || e.key === " ") {
                      e.preventDefault();
                      onRowClick(r.id);
                    }
                  }
                : undefined
            }
            className={cn(
              "group flex items-center gap-3",
              compact ? "py-1.5" : "py-2.5",
              onRowClick ? "cursor-pointer" : ""
            )}
            style={{ minHeight: rowHeight }}
          >
            {/* Leading slot (e.g. initials avatar) */}
            {r.leading ? (
              <div className="shrink-0">{r.leading}</div>
            ) : null}

            {/* Label column */}
            <div
              className="shrink-0 min-w-0"
              style={{ width: labelW - (r.leading ? 36 : 0) }}
            >
              <div
                className={cn(
                  "truncate font-medium",
                  compact ? "text-[12.5px]" : "text-[13.5px]"
                )}
                style={{ color: "hsl(var(--surface-ink))" }}
              >
                {r.label}
              </div>
              {r.sublabel ? (
                <div
                  className="mono truncate"
                  style={{
                    color: "hsl(var(--surface-ink-3))",
                    fontSize: 10.5,
                    marginTop: 1,
                  }}
                >
                  {r.sublabel}
                </div>
              ) : null}
            </div>

            {/* Bar */}
            <div className="flex-1 min-w-0 relative">
              {/* Track (hairline) */}
              <div
                className="absolute inset-x-0 top-1/2 -translate-y-1/2 h-px"
                style={{ backgroundColor: "hsl(30 14% 14% / 0.08)" }}
                aria-hidden
              />
              <div
                className="relative h-[10px] rounded-[2px]"
                style={{
                  width: `${pct}%`,
                  backgroundColor: color,
                  opacity: 0.85,
                  animation: `bar-grow-h 700ms cubic-bezier(0.2,0.8,0.2,1) ${
                    i * 50
                  }ms both`,
                  transformOrigin: "left center",
                  boxShadow: `inset 0 1px 0 hsl(0 0% 100% / 0.15)`,
                }}
                aria-hidden
              />
              {/* Rank tick on the bar */}
              <span
                className="mono absolute top-1/2 -translate-y-1/2 text-[9px] font-semibold tabular-nums"
                style={{
                  left: 6,
                  color: "hsl(0 0% 100% / 0.92)",
                  mixBlendMode: "screen",
                  opacity: pct > 12 ? 1 : 0,
                }}
              >
                {String(i + 1).padStart(2, "0")}
              </span>
            </div>

            {/* Trailing value */}
            <div
              className={cn(
                "shrink-0 text-right mono tabular-nums",
                compact ? "text-[12.5px]" : "text-[14px]"
              )}
              style={{
                color: "hsl(var(--surface-ink))",
                minWidth: 56,
              }}
            >
              {r.formatted ?? r.value.toLocaleString("en-US")}
            </div>
          </div>
        );
      })}
    </div>
  );
}