import React, { useEffect, useMemo, useRef, useState } from "react";
import AddToPersonalizedButton from "../personalized/AddToPersonalizedButton.jsx";
import { chartScaleMax } from "../../../utils/documentCreationTrend.js";

const DEFAULT_WIDTH = 520;
const MIN_WIDTH = 280;
const HEIGHT = 260;
const PAD = { top: 16, right: 16, bottom: 48, left: 44 };

const TONE_COLORS = {
  opened: "#2563eb",
  assigned: "#d97706",
  "in-progress": "#7c3aed",
  completed: "#059669",
};

function toneColor(tone) {
  return TONE_COLORS[tone] || "var(--swi-accent)";
}

function handleChartKeyDown(event, onClick) {
  if (!onClick) return;
  if (event.key === "Enter" || event.key === " ") {
    event.preventDefault();
    onClick();
  }
}

function formatAxisLabel(label, slotWidth) {
  if (slotWidth >= 88 || label.length <= 12) return label;
  if (slotWidth >= 64) {
    return label.length > 14 ? `${label.slice(0, 13)}…` : label;
  }
  return label.length > 10 ? `${label.slice(0, 9)}…` : label;
}

/**
 * @param {{
 *   data: Array<{ label: string, value: number, tone?: string }>,
 *   title: string,
 *   description?: string,
 *   emptyMessage?: string,
 *   personalizedWidgetId?: string,
 *   onClick?: () => void,
 *   onBarClick?: (item: { label: string, value: number, tone?: string }, index: number) => void,
 * }} props
 */
export default function UserVerticalBarChart({
  data = [],
  title,
  description,
  emptyMessage = "No data for this chart.",
  personalizedWidgetId,
  onClick,
  onBarClick,
}) {
  const clickable = Boolean(onClick || onBarClick);
  const canvasRef = useRef(null);
  const [chartWidth, setChartWidth] = useState(DEFAULT_WIDTH);

  useEffect(() => {
    const node = canvasRef.current;
    if (!node) return undefined;

    const updateWidth = () => {
      const nextWidth = Math.round(node.getBoundingClientRect().width);
      if (nextWidth > 0) {
        setChartWidth(Math.max(MIN_WIDTH, nextWidth));
      }
    };

    updateWidth();
    const observer = new ResizeObserver(updateWidth);
    observer.observe(node);
    return () => observer.disconnect();
  }, []);

  const maxValue = useMemo(() => {
    const peak = Math.max(0, ...data.map((item) => Number(item.value) || 0));
    return chartScaleMax(peak);
  }, [data]);

  const plotW = chartWidth - PAD.left - PAD.right;
  const plotH = HEIGHT - PAD.top - PAD.bottom;
  const barGap = 12;
  const barCount = Math.max(data.length, 1);
  const slotWidth = plotW / barCount;
  const barWidth = Math.min(96, Math.max(24, slotWidth - barGap));
  const getBarX = (index) =>
    PAD.left + index * slotWidth + (slotWidth - barWidth) / 2;

  const total = useMemo(
    () => data.reduce((sum, item) => sum + (Number(item.value) || 0), 0),
    [data]
  );

  const descText =
    description && clickable
      ? `${description} Click a bar or chart to open details.`
      : description;

  return (
    <section
      className={`swi-user-chart swi-user-chart--wide swi-panel${clickable ? " swi-user-chart--clickable" : ""}`}
    >
      <header
        className="swi-user-chart__head"
        onClick={onClick}
        onKeyDown={(event) => handleChartKeyDown(event, onClick)}
        role={onClick ? "button" : undefined}
        tabIndex={onClick ? 0 : undefined}
      >
        <div>
          <h2 className="swi-user-chart__title">{title}</h2>
          {descText ? <p className="swi-user-chart__desc">{descText}</p> : null}
        </div>
        <div
          className="swi-user-chart__head-actions"
          onClick={(event) => event.stopPropagation()}
          onKeyDown={(event) => event.stopPropagation()}
        >
          <div className="swi-user-chart__metric">
            <strong>{total}</strong>
            <span>Total</span>
          </div>
          {personalizedWidgetId ? (
            <AddToPersonalizedButton
              widgetId={personalizedWidgetId}
              label="Add"
              className="swi-add-to-pd--compact"
            />
          ) : null}
        </div>
      </header>

      {!data.length || total === 0 ? (
        onClick ? (
          <button
            type="button"
            className="swi-user-chart__empty-action swi-muted"
            onClick={onClick}
          >
            {emptyMessage}
          </button>
        ) : (
          <p className="swi-muted">{emptyMessage}</p>
        )
      ) : (
        <div
          ref={canvasRef}
          className="swi-user-chart__canvas-wrap"
          onClick={onClick}
          onKeyDown={(event) => handleChartKeyDown(event, onClick)}
          role={onClick ? "button" : undefined}
          tabIndex={onClick ? 0 : undefined}
        >
          <svg
            className="swi-user-chart__svg"
            viewBox={`0 0 ${chartWidth} ${HEIGHT}`}
            preserveAspectRatio="xMidYMid meet"
            role="img"
            aria-label={title}
          >
            {[0, 0.25, 0.5, 0.75, 1].map((ratio) => {
              const y = PAD.top + plotH - ratio * plotH;
              const tick = Math.round(maxValue * ratio);
              return (
                <g key={ratio}>
                  <line
                    x1={PAD.left}
                    y1={y}
                    x2={chartWidth - PAD.right}
                    y2={y}
                    className="swi-user-chart__grid-line"
                  />
                  <text
                    x={PAD.left - 8}
                    y={y}
                    className="swi-user-chart__y-label"
                    textAnchor="end"
                    dominantBaseline="middle"
                  >
                    {tick}
                  </text>
                </g>
              );
            })}

            {data.map((item, index) => {
              const value = Number(item.value) || 0;
              const barH = maxValue > 0 ? (value / maxValue) * plotH : 0;
              const x = getBarX(index);
              const y = PAD.top + plotH - barH;
              const color = toneColor(item.tone);

              const handleBarActivate = () => {
                if (onBarClick) {
                  onBarClick(item, index);
                  return;
                }
                onClick?.();
              };

              return (
                <g key={`${item.label}-${index}`}>
                  <rect
                    x={x}
                    y={y}
                    width={barWidth}
                    height={barH}
                    rx="6"
                    fill={color}
                    opacity="0.88"
                    pointerEvents="none"
                  >
                    <title>{`${item.label}: ${value}`}</title>
                  </rect>
                  <text
                    x={x + barWidth / 2}
                    y={y - 6}
                    className="swi-user-chart__value-label"
                    textAnchor="middle"
                    pointerEvents="none"
                  >
                    {value > 0 ? value : ""}
                  </text>
                  <text
                    x={x + barWidth / 2}
                    y={HEIGHT - 12}
                    className="swi-user-chart__x-label"
                    textAnchor="middle"
                    pointerEvents="none"
                  >
                    {formatAxisLabel(item.label, slotWidth)}
                  </text>
                  {clickable ? (
                    <rect
                      x={x}
                      y={PAD.top}
                      width={barWidth}
                      height={plotH}
                      fill="transparent"
                      className="swi-user-chart__bar-hit"
                      tabIndex={0}
                      role="button"
                      aria-label={`${item.label}: ${value}. Open details.`}
                      onClick={(event) => {
                        event.stopPropagation();
                        handleBarActivate();
                      }}
                      onKeyDown={(event) => {
                        if (event.key === "Enter" || event.key === " ") {
                          event.preventDefault();
                          event.stopPropagation();
                          handleBarActivate();
                        }
                      }}
                    />
                  ) : null}
                </g>
              );
            })}
          </svg>
        </div>
      )}
    </section>
  );
}
