/**
 * Heatmap Component
 * Displays data intensity across a grid
 */

interface HeatmapCell {
  x: string;
  y: string;
  value: number;
}

interface HeatmapProps {
  data: HeatmapCell[];
  title?: string;
  xLabels: string[];
  yLabels: string[];
  colorRange?: { min: string; max: string };
  height?: number;
  showValues?: boolean;
}

function interpolateColor(color1: string, color2: string, factor: number): string {
  const hex = (c: string) => parseInt(c, 16);
  const r1 = hex(color1.slice(1, 3));
  const g1 = hex(color1.slice(3, 5));
  const b1 = hex(color1.slice(5, 7));
  const r2 = hex(color2.slice(1, 3));
  const g2 = hex(color2.slice(3, 5));
  const b2 = hex(color2.slice(5, 7));

  const r = Math.round(r1 + (r2 - r1) * factor);
  const g = Math.round(g1 + (g2 - g1) * factor);
  const b = Math.round(b1 + (b2 - b1) * factor);

  return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
}

export default function Heatmap({
  data,
  title,
  xLabels,
  yLabels,
  colorRange = { min: '#fee2e2', max: '#10b981' },
  height = 300,
  showValues = true,
}: HeatmapProps) {
  const maxValue = Math.max(...data.map((d) => d.value));
  const minValue = Math.min(...data.map((d) => d.value));
  const range = maxValue - minValue || 1;

  const getColor = (value: number): string => {
    const factor = (value - minValue) / range;
    return interpolateColor(colorRange.min, colorRange.max, factor);
  };

  const getValue = (x: string, y: string): number | undefined => {
    const cell = data.find((d) => d.x === x && d.y === y);
    return cell?.value;
  };

  const cellWidth = `${100 / xLabels.length}%`;
  const cellHeight = (height - 40) / yLabels.length;

  return (
    <div className="bg-white rounded-lg shadow-lg p-6">
      {title && <h3 className="text-lg font-bold text-gray-900 mb-4">{title}</h3>}
      <div style={{ height }}>
        {/* X Labels */}
        <div className="flex mb-1" style={{ paddingLeft: '80px' }}>
          {xLabels.map((label) => (
            <div
              key={label}
              className="text-xs text-gray-500 text-center truncate"
              style={{ width: cellWidth }}
            >
              {label}
            </div>
          ))}
        </div>

        {/* Grid */}
        {yLabels.map((yLabel) => (
          <div key={yLabel} className="flex">
            <div
              className="flex items-center justify-end pr-2 text-xs text-gray-500"
              style={{ width: '80px' }}
            >
              {yLabel}
            </div>
            {xLabels.map((xLabel) => {
              const value = getValue(xLabel, yLabel);
              const bgColor = value !== undefined ? getColor(value) : '#f3f4f6';
              const textColor =
                value !== undefined && (value - minValue) / range > 0.5
                  ? '#fff'
                  : '#374151';

              return (
                <div
                  key={`${xLabel}-${yLabel}`}
                  className="flex items-center justify-center border border-white rounded-sm transition-all hover:ring-2 hover:ring-gray-400"
                  style={{
                    width: cellWidth,
                    height: cellHeight,
                    backgroundColor: bgColor,
                  }}
                  title={`${xLabel}, ${yLabel}: ${value ?? 'N/A'}`}
                >
                  {showValues && value !== undefined && (
                    <span className="text-xs font-medium" style={{ color: textColor }}>
                      {value.toFixed(0)}
                    </span>
                  )}
                </div>
              );
            })}
          </div>
        ))}

        {/* Legend */}
        <div className="flex items-center justify-center mt-4 space-x-4">
          <span className="text-xs text-gray-500">Low</span>
          <div
            className="w-24 h-3 rounded"
            style={{
              background: `linear-gradient(to right, ${colorRange.min}, ${colorRange.max})`,
            }}
          />
          <span className="text-xs text-gray-500">High</span>
        </div>
      </div>
    </div>
  );
}
