"use client";

import * as React from "react";
import { Bar, BarChart, CartesianGrid, Cell, XAxis, YAxis } from "recharts";

import { type ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart";
import { cn } from "@/lib/utils";

import type { DashboardBarItem } from "./types";

const chartConfig = {
  value: { label: "Value", color: "var(--chart-1)" },
} satisfies ChartConfig;

function truncateLabel(value: string, max = 22) {
  const trimmed = value.trim();
  if (trimmed.length <= max) return trimmed;
  return `${trimmed.slice(0, max - 1)}…`;
}

function labelWidthForItems(items: DashboardBarItem[]) {
  const longest = items.reduce((max, item) => Math.max(max, item.name.length), 0);
  return Math.min(148, Math.max(84, Math.ceil(longest * 5.8)));
}

type ResponsiveHorizontalBarChartProps = {
  items: DashboardBarItem[];
  className?: string;
  height?: number;
  valueFormatter?: (item: DashboardBarItem) => string;
  barSize?: number;
};

export function ResponsiveHorizontalBarChart({
  items,
  className,
  height,
  valueFormatter,
  barSize = 16,
}: ResponsiveHorizontalBarChartProps) {
  const hostRef = React.useRef<HTMLDivElement>(null);
  const [measuredHeight, setMeasuredHeight] = React.useState(height ?? 180);

  React.useEffect(() => {
    if (height != null) {
      setMeasuredHeight(height);
      return;
    }

    const el = hostRef.current;
    if (!el) return;

    let frame = 0;
    const update = () => {
      cancelAnimationFrame(frame);
      frame = requestAnimationFrame(() => {
        const next = Math.max(120, Math.floor(el.getBoundingClientRect().height));
        setMeasuredHeight((prev) => (prev === next ? prev : next));
      });
    };

    update();
    const ro = new ResizeObserver(update);
    ro.observe(el);
    return () => {
      cancelAnimationFrame(frame);
      ro.disconnect();
    };
  }, [height]);

  const yAxisWidth = React.useMemo(() => labelWidthForItems(items), [items]);

  if (items.length === 0) {
    return (
      <div className={cn("flex h-full min-h-[120px] items-center justify-center text-xs text-muted-foreground", className)}>
        No chart data
      </div>
    );
  }

  const chartHeight = Math.max(120, Math.min(measuredHeight, items.length * (barSize + 14) + 28));

  return (
    <div ref={hostRef} className={cn("min-h-[120px] w-full", className)} style={{ height: chartHeight }}>
      <ChartContainer config={chartConfig} className="h-full w-full">
        <BarChart
          data={items}
          layout="vertical"
          margin={{ top: 4, right: 12, bottom: 4, left: 0 }}
          barCategoryGap="18%"
        >
          <CartesianGrid horizontal={false} strokeDasharray="3 3" className="stroke-border/40" />
          <XAxis type="number" hide domain={[0, 100]} />
          <YAxis
            type="category"
            // Use unique id — truncated display names often collide (e.g. many
            // "KAISA GRP HLDGS LTD…") and Recharts then maps every hover to the first bar.
            dataKey="id"
            width={yAxisWidth}
            tick={{ fontSize: 10, fill: "var(--foreground)" }}
            tickLine={false}
            axisLine={false}
            tickFormatter={(value) => {
              const item = items.find((entry) => entry.id === value);
              return truncateLabel(item?.name ?? String(value), 20);
            }}
          />
          <ChartTooltip
            isAnimationActive={false}
            content={
              <ChartTooltipContent
                labelFormatter={(_label, payload) => {
                  const item = payload?.[0]?.payload as DashboardBarItem | undefined;
                  return item?.name ?? _label;
                }}
                formatter={(_value, _name, item) => {
                  const payload = item.payload as DashboardBarItem;
                  // Prefer formatted real % / amount — `value` is only a 0–100 bar-width scale.
                  return valueFormatter?.(payload) ?? payload.formatted ?? String(payload.value);
                }}
              />
            }
          />
          <Bar dataKey="value" radius={[0, 4, 4, 0]} isAnimationActive={false} barSize={barSize}>
            {items.map((item) => (
              <Cell key={item.id} fill={item.fill ?? "var(--chart-1)"} />
            ))}
          </Bar>
        </BarChart>
      </ChartContainer>
    </div>
  );
}
