// ─────────────────────────────────────────────────────────────────────────────
// Ultra Image Cropper 2.0 — Text Layer Overlay
// Drag-and-resize SVG overlay for the selected text layer
// ─────────────────────────────────────────────────────────────────────────────

import React, { useRef, useCallback, useEffect } from 'react';
import { useCanvasStore } from '@/store';
import { historyManager } from '@/engine/HistoryManager';

type HandlePos = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'move';

interface TextLayerOverlayProps {
  canvasDisplayWidth: number;
  canvasDisplayHeight: number;
  zoom: number;
}

const HANDLE_SIZE = 8;
const MIN_LAYER_PX = 20; // minimum size in image pixel space

const CURSOR_MAP: Record<HandlePos, string> = {
  nw: 'nw-resize', n: 'n-resize', ne: 'ne-resize',
  e: 'e-resize',   se: 'se-resize', s: 's-resize',
  sw: 'sw-resize', w: 'w-resize',   move: 'move',
};

export const TextLayerOverlay: React.FC<TextLayerOverlayProps> = ({
  canvasDisplayWidth,
  canvasDisplayHeight,
  zoom,
}) => {
  const { layers, updateLayer, selectedLayerId, setSelectedLayerId } = useCanvasStore();
  const svgRef = useRef<SVGSVGElement>(null);

  const layer = layers.find((l) => l.id === selectedLayerId) ?? null;

  const dragState = useRef<{
    handle: HandlePos;
    startX: number;
    startY: number;
    startLayer: { x: number; y: number; width: number; height: number };
  } | null>(null);

  const clamp = (v: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, v));

  const handleMouseDown = useCallback((e: React.MouseEvent, handle: HandlePos) => {
    if (!layer) return;
    e.preventDefault();
    e.stopPropagation();
    const rect = svgRef.current!.getBoundingClientRect();
    dragState.current = {
      handle,
      startX: e.clientX - rect.left,
      startY: e.clientY - rect.top,
      startLayer: { x: layer.x, y: layer.y, width: layer.width, height: layer.height },
    };
  }, [layer]);

  const handleMouseMove = useCallback((e: MouseEvent) => {
    if (!dragState.current || !svgRef.current || !layer) return;

    const rect = svgRef.current.getBoundingClientRect();
    const mx = e.clientX - rect.left;
    const my = e.clientY - rect.top;
    const { handle, startX, startY, startLayer } = dragState.current;

    // Delta in display pixels → image pixel space
    const dxI = (mx - startX) / zoom;
    const dyI = (my - startY) / zoom;

    const imgW = canvasDisplayWidth / zoom;
    const imgH = canvasDisplayHeight / zoom;

    let { x, y, width, height } = startLayer;

    if (handle === 'move') {
      x = clamp(startLayer.x + dxI, 0, imgW - width);
      y = clamp(startLayer.y + dyI, 0, imgH - height);
    } else {
      if (handle.includes('e')) width  = clamp(startLayer.width  + dxI, MIN_LAYER_PX, imgW - x);
      if (handle.includes('s')) height = clamp(startLayer.height + dyI, MIN_LAYER_PX, imgH - y);
      if (handle.includes('w')) {
        const maxDx   = startLayer.width - MIN_LAYER_PX;
        const actualDx = clamp(dxI, -startLayer.x, maxDx);
        x     = startLayer.x + actualDx;
        width = startLayer.width - actualDx;
      }
      if (handle.includes('n')) {
        const maxDy    = startLayer.height - MIN_LAYER_PX;
        const actualDy = clamp(dyI, -startLayer.y, maxDy);
        y      = startLayer.y + actualDy;
        height = startLayer.height - actualDy;
      }
    }

    updateLayer(layer.id, {
      x: Math.round(x),
      y: Math.round(y),
      width: Math.round(width),
      height: Math.round(height),
    });
  }, [layer, zoom, canvasDisplayWidth, canvasDisplayHeight, updateLayer]);

  const handleMouseUp = useCallback(() => {
    if (dragState.current && layer) {
      historyManager.snapshot('Move / Resize Text');
    }
    dragState.current = null;
  }, [layer]);

  useEffect(() => {
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [handleMouseMove, handleMouseUp]);

  if (!layer) return null;

  // Convert layer coords (image pixel space) → SVG display space
  const sx = layer.x * zoom;
  const sy = layer.y * zoom;
  const sw = layer.width  * zoom;
  const sh = layer.height * zoom;

  const handles: { pos: HandlePos; cx: number; cy: number }[] = [
    { pos: 'nw', cx: sx,        cy: sy        },
    { pos: 'n',  cx: sx + sw/2, cy: sy        },
    { pos: 'ne', cx: sx + sw,   cy: sy        },
    { pos: 'e',  cx: sx + sw,   cy: sy + sh/2 },
    { pos: 'se', cx: sx + sw,   cy: sy + sh   },
    { pos: 's',  cx: sx + sw/2, cy: sy + sh   },
    { pos: 'sw', cx: sx,        cy: sy + sh   },
    { pos: 'w',  cx: sx,        cy: sy + sh/2 },
  ];

  return (
    <svg
      ref={svgRef}
      className="ultra-text-overlay"
      width={canvasDisplayWidth}
      height={canvasDisplayHeight}
      style={{ position: 'absolute', top: 0, left: 0, pointerEvents: 'none', overflow: 'visible' }}
    >
      {/* Transparent backdrop — click outside the box to deselect */}
      <rect
        x={0} y={0}
        width={canvasDisplayWidth}
        height={canvasDisplayHeight}
        fill="transparent"
        style={{ pointerEvents: 'all', cursor: 'default' }}
        onMouseDown={(e) => {
          const rect = svgRef.current!.getBoundingClientRect();
          const mx = e.clientX - rect.left;
          const my = e.clientY - rect.top;
          if (mx < sx || mx > sx + sw || my < sy || my > sy + sh) {
            setSelectedLayerId(null);
          }
        }}
      />

      {/* Dashed selection border + drag zone */}
      <rect
        x={sx} y={sy} width={sw} height={sh}
        fill="rgba(99,102,241,0.05)"
        stroke="rgba(99,102,241,0.85)"
        strokeWidth={1.5}
        strokeDasharray="6 3"
        style={{ cursor: 'move', pointerEvents: 'all' }}
        onMouseDown={(e) => handleMouseDown(e, 'move')}
      />

      {/* 8 resize handles */}
      {handles.map(({ pos, cx, cy }) => (
        <rect
          key={pos}
          x={cx - HANDLE_SIZE / 2}
          y={cy - HANDLE_SIZE / 2}
          width={HANDLE_SIZE}
          height={HANDLE_SIZE}
          fill="white"
          stroke="rgba(99,102,241,0.9)"
          strokeWidth={1.5}
          rx={2}
          style={{ cursor: CURSOR_MAP[pos], pointerEvents: 'all' }}
          onMouseDown={(e) => handleMouseDown(e, pos)}
        />
      ))}
    </svg>
  );
};
