'use client';

import type { WidgetConfig, ChartData, HeatmapConfig } from '@/lib/pipeline-types';
import { WidgetWrapper } from './WidgetWrapper';

interface HeatmapWidgetProps {
  config: WidgetConfig;
  data: ChartData | null;
  loading: boolean;
  error?: string;
  onRefresh?: () => void;
}

/**
 * Heatmap widget for displaying 2D data grids.
 */
export function HeatmapWidget({
  config,
  data,
  loading,
  error,
  onRefresh,
}: HeatmapWidgetProps) {
  const heatmapConfig = config.config as unknown as HeatmapConfig;
  const rawData = data?.data || [];

  // Extract unique x and y values
  const xValues = [...new Set(rawData.map((d) => d[heatmapConfig.x_key] as string))];
  const yValues = [...new Set(rawData.map((d) => d[heatmapConfig.y_key] as string))];

  // Find min/max values for color scaling
  const values = rawData.map((d) => d[heatmapConfig.value_key] as number);
  const minValue = Math.min(...values, 0);
  const maxValue = Math.max(...values, 1);

  // Create lookup map
  const valueMap = new Map<string, number>();
  rawData.forEach((d) => {
    const key = `${d[heatmapConfig.y_key]}-${d[heatmapConfig.x_key]}`;
    valueMap.set(key, d[heatmapConfig.value_key] as number);
  });

  // Get color for a value
  const getColor = (value: number): string => {
    const colors = heatmapConfig.color_scale || ['#f0fdf4', '#22c55e'];
    const ratio = maxValue === minValue ? 0.5 : (value - minValue) / (maxValue - minValue);

    // Simple interpolation between first and last color
    if (colors.length === 2) {
      return interpolateColor(colors[0], colors[1], ratio);
    }
    return colors[Math.min(Math.floor(ratio * colors.length), colors.length - 1)];
  };

  return (
    <WidgetWrapper config={config} loading={loading} error={error} onRefresh={onRefresh}>
      {rawData.length === 0 ? (
        <div className="flex items-center justify-center h-full text-gray-500">
          No data available
        </div>
      ) : (
        <div className="overflow-auto h-full">
          <table className="min-w-full">
            <thead>
              <tr>
                <th className="px-2 py-2 text-xs font-medium text-gray-500" />
                {xValues.map((x) => (
                  <th
                    key={x}
                    className="px-2 py-2 text-xs font-medium text-gray-500 text-center"
                  >
                    {x}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {yValues.map((y) => (
                <tr key={y}>
                  <td className="px-2 py-2 text-xs font-medium text-gray-700">
                    {y}
                  </td>
                  {xValues.map((x) => {
                    const key = `${y}-${x}`;
                    const value = valueMap.get(key) || 0;
                    return (
                      <td
                        key={key}
                        className="px-2 py-2 text-center"
                        style={{ backgroundColor: getColor(value) }}
                        title={`${y}, ${x}: ${value}`}
                      >
                        {heatmapConfig.show_values && (
                          <span className="text-xs font-medium text-gray-800">
                            {value.toLocaleString()}
                          </span>
                        )}
                      </td>
                    );
                  })}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </WidgetWrapper>
  );
}

/**
 * Interpolate between two hex colors.
 */
function interpolateColor(color1: string, color2: string, ratio: 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) * ratio);
  const g = Math.round(g1 + (g2 - g1) * ratio);
  const b = Math.round(b1 + (b2 - b1) * ratio);

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