import { useMemo } from 'react';

export interface TreemapItem {
  id: string;
  label: string;
  value: number;
  /** 0-100, drives green→yellow→red color */
  slaCompliance: number;
}

interface TreemapProps {
  items: TreemapItem[];
  width: number;
  height: number;
  onItemClick?: (id: string) => void;
}

interface LayoutRect {
  item: TreemapItem;
  x: number;
  y: number;
  w: number;
  h: number;
}

function slaColor(pct: number): string {
  if (pct >= 99) return 'hsl(120, 45%, 85%)';
  if (pct >= 97) return 'hsl(90, 45%, 85%)';
  if (pct >= 95) return 'hsl(60, 50%, 85%)';
  if (pct >= 90) return 'hsl(30, 55%, 85%)';
  return 'hsl(0, 55%, 85%)';
}

function slaBorderColor(pct: number): string {
  if (pct >= 99) return 'hsl(120, 40%, 45%)';
  if (pct >= 97) return 'hsl(90, 40%, 50%)';
  if (pct >= 95) return 'hsl(60, 45%, 45%)';
  if (pct >= 90) return 'hsl(30, 50%, 45%)';
  return 'hsl(0, 50%, 45%)';
}

function slaTextColor(pct: number): string {
  if (pct >= 95) return 'hsl(120, 20%, 25%)';
  return 'hsl(0, 40%, 30%)';
}

/** Squarified treemap layout */
function layoutTreemap(items: TreemapItem[], x: number, y: number, w: number, h: number): LayoutRect[] {
  if (items.length === 0) return [];
  const total = items.reduce((s, i) => s + i.value, 0);
  if (total === 0) return items.map((item, i) => ({ item, x: x + i, y, w: 1, h: 1 }));

  const sorted = [...items].sort((a, b) => b.value - a.value);
  const rects: LayoutRect[] = [];
  layoutSlice(sorted, total, x, y, w, h, rects);
  return rects;
}

function layoutSlice(
  items: TreemapItem[], total: number,
  x: number, y: number, w: number, h: number,
  out: LayoutRect[],
) {
  if (items.length === 0) return;
  if (items.length === 1) {
    out.push({ item: items[0], x, y, w, h });
    return;
  }

  const isWide = w >= h;
  let partialSum = 0;
  let splitIndex = 0;

  // Find split point closest to half the total area
  const halfTotal = total / 2;
  for (let i = 0; i < items.length - 1; i++) {
    partialSum += items[i].value;
    if (partialSum >= halfTotal) {
      splitIndex = i + 1;
      break;
    }
    splitIndex = i + 1;
  }

  const leftTotal = items.slice(0, splitIndex).reduce((s, i) => s + i.value, 0);
  const ratio = total > 0 ? leftTotal / total : 0.5;

  if (isWide) {
    const splitX = x + w * ratio;
    layoutSlice(items.slice(0, splitIndex), leftTotal, x, y, w * ratio, h, out);
    layoutSlice(items.slice(splitIndex), total - leftTotal, splitX, y, w * (1 - ratio), h, out);
  } else {
    const splitY = y + h * ratio;
    layoutSlice(items.slice(0, splitIndex), leftTotal, x, y, w, h * ratio, out);
    layoutSlice(items.slice(splitIndex), total - leftTotal, x, splitY, w, h * (1 - ratio), out);
  }
}

export function Treemap({ items, width, height, onItemClick }: TreemapProps) {
  const rects = useMemo(() => layoutTreemap(items, 1, 1, width - 2, height - 2), [items, width, height]);

  if (items.length === 0) {
    return (
      <svg viewBox={`0 0 ${width} ${height}`} style={{ width: '100%', height: 'auto', display: 'block' }}>
        <text x={width / 2} y={height / 2} textAnchor="middle" fill="#9CA3AF" fontSize={12}>No data</text>
      </svg>
    );
  }

  return (
    <svg viewBox={`0 0 ${width} ${height}`} style={{ width: '100%', height: 'auto', display: 'block' }}>
      {rects.map(({ item, x, y, w, h }) => {
        const pad = 1;
        const rx = x + pad;
        const ry = y + pad;
        const rw = Math.max(w - pad * 2, 0);
        const rh = Math.max(h - pad * 2, 0);
        const showLabel = rw > 40 && rh > 20;
        const showSla = rw > 60 && rh > 34;

        return (
          <g
            key={item.id}
            onClick={() => onItemClick?.(item.id)}
            style={{ cursor: onItemClick ? 'pointer' : 'default' }}
          >
            <rect
              x={rx} y={ry} width={rw} height={rh}
              rx={3}
              fill={slaColor(item.slaCompliance)}
              stroke={slaBorderColor(item.slaCompliance)}
              strokeWidth={1}
            />
            {showLabel && (
              <text
                x={rx + 4} y={ry + 13}
                fill={slaTextColor(item.slaCompliance)}
                fontSize={11} fontWeight={600}
                style={{ pointerEvents: 'none' }}
              >
                {item.label.length > rw / 6.5 ? item.label.slice(0, Math.floor(rw / 6.5)) + '\u2026' : item.label}
              </text>
            )}
            {showSla && (
              <text
                x={rx + 4} y={ry + 26}
                fill={slaTextColor(item.slaCompliance)}
                fontSize={10} fontWeight={400}
                style={{ pointerEvents: 'none' }}
              >
                {item.slaCompliance.toFixed(1)}% SLA
              </text>
            )}
          </g>
        );
      })}
    </svg>
  );
}
