"use client";

import { useRef, useState, useEffect, useCallback } from "react";
import { X } from "lucide-react";

interface SelectionBounds {
  x: number;
  y: number;
  width: number;
  height: number;
}

interface SelectionData {
  bounds: SelectionBounds;
  maskBase64: string;
}

interface TextSelectionCanvasProps {
  imageUrl: string;
  onSelectionComplete: (data: SelectionData) => void;
  onCancel: () => void;
}

// Target dimensions for the mask (matching zine page size)
const MASK_WIDTH = 768;
const MASK_HEIGHT = 1024;

export default function TextSelectionCanvas({
  imageUrl,
  onSelectionComplete,
  onCancel,
}: TextSelectionCanvasProps) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [isDrawing, setIsDrawing] = useState(false);
  const [startPoint, setStartPoint] = useState<{ x: number; y: number } | null>(null);
  const [currentRect, setCurrentRect] = useState<SelectionBounds | null>(null);
  const [imageLoaded, setImageLoaded] = useState(false);
  const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 });

  // Load and draw the background image
  useEffect(() => {
    const canvas = canvasRef.current;
    const container = containerRef.current;
    if (!canvas || !container) return;

    const img = new Image();
    img.crossOrigin = "anonymous";

    img.onload = () => {
      // Calculate canvas size to fit container while maintaining aspect ratio
      const containerWidth = container.clientWidth;
      const containerHeight = container.clientHeight;
      const imgAspect = img.width / img.height;
      const containerAspect = containerWidth / containerHeight;

      let canvasWidth: number;
      let canvasHeight: number;

      if (imgAspect > containerAspect) {
        canvasWidth = containerWidth;
        canvasHeight = containerWidth / imgAspect;
      } else {
        canvasHeight = containerHeight;
        canvasWidth = containerHeight * imgAspect;
      }

      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
      setCanvasSize({ width: canvasWidth, height: canvasHeight });

      const ctx = canvas.getContext("2d");
      if (ctx) {
        ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);
        setImageLoaded(true);
      }
    };

    img.src = imageUrl;
  }, [imageUrl]);

  // Redraw canvas with selection rectangle
  const redrawCanvas = useCallback((rect: SelectionBounds | null) => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    // Reload and draw the image
    const img = new Image();
    img.crossOrigin = "anonymous";
    img.onload = () => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

      // Draw semi-transparent overlay
      ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      if (rect && rect.width > 0 && rect.height > 0) {
        // Clear the selected area (show original image)
        ctx.clearRect(rect.x, rect.y, rect.width, rect.height);
        ctx.drawImage(
          img,
          (rect.x / canvas.width) * img.width,
          (rect.y / canvas.height) * img.height,
          (rect.width / canvas.width) * img.width,
          (rect.height / canvas.height) * img.height,
          rect.x,
          rect.y,
          rect.width,
          rect.height
        );

        // Draw selection border
        ctx.strokeStyle = "#22c55e";
        ctx.lineWidth = 2;
        ctx.setLineDash([5, 5]);
        ctx.strokeRect(rect.x, rect.y, rect.width, rect.height);

        // Draw corner handles
        ctx.setLineDash([]);
        ctx.fillStyle = "#22c55e";
        const handleSize = 8;
        const corners = [
          { x: rect.x, y: rect.y },
          { x: rect.x + rect.width, y: rect.y },
          { x: rect.x, y: rect.y + rect.height },
          { x: rect.x + rect.width, y: rect.y + rect.height },
        ];
        corners.forEach(({ x, y }) => {
          ctx.fillRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize);
        });
      }
    };
    img.src = imageUrl;
  }, [imageUrl]);

  // Get canvas coordinates from mouse/touch event
  const getCanvasCoords = (e: React.MouseEvent | React.TouchEvent) => {
    const canvas = canvasRef.current;
    if (!canvas) return { x: 0, y: 0 };

    const rect = canvas.getBoundingClientRect();
    const clientX = "touches" in e ? e.touches[0].clientX : e.clientX;
    const clientY = "touches" in e ? e.touches[0].clientY : e.clientY;

    return {
      x: clientX - rect.left,
      y: clientY - rect.top,
    };
  };

  const handleStart = (e: React.MouseEvent | React.TouchEvent) => {
    e.preventDefault();
    const coords = getCanvasCoords(e);
    setIsDrawing(true);
    setStartPoint(coords);
    setCurrentRect(null);
  };

  const handleMove = (e: React.MouseEvent | React.TouchEvent) => {
    if (!isDrawing || !startPoint) return;
    e.preventDefault();

    const coords = getCanvasCoords(e);
    const rect: SelectionBounds = {
      x: Math.min(startPoint.x, coords.x),
      y: Math.min(startPoint.y, coords.y),
      width: Math.abs(coords.x - startPoint.x),
      height: Math.abs(coords.y - startPoint.y),
    };

    setCurrentRect(rect);
    redrawCanvas(rect);
  };

  const handleEnd = () => {
    setIsDrawing(false);
    setStartPoint(null);
  };

  // Generate mask and complete selection
  const handleConfirm = useCallback(() => {
    if (!currentRect || currentRect.width < 20 || currentRect.height < 20) {
      return;
    }

    // Create mask canvas at target dimensions
    const maskCanvas = document.createElement("canvas");
    maskCanvas.width = MASK_WIDTH;
    maskCanvas.height = MASK_HEIGHT;
    const maskCtx = maskCanvas.getContext("2d");

    if (!maskCtx) return;

    // Fill with black (preserve area)
    maskCtx.fillStyle = "black";
    maskCtx.fillRect(0, 0, MASK_WIDTH, MASK_HEIGHT);

    // Scale selection coordinates to mask dimensions
    const scaleX = MASK_WIDTH / canvasSize.width;
    const scaleY = MASK_HEIGHT / canvasSize.height;

    const scaledRect = {
      x: currentRect.x * scaleX,
      y: currentRect.y * scaleY,
      width: currentRect.width * scaleX,
      height: currentRect.height * scaleY,
    };

    // Draw white rectangle (inpaint area)
    maskCtx.fillStyle = "white";
    maskCtx.fillRect(scaledRect.x, scaledRect.y, scaledRect.width, scaledRect.height);

    // Convert to base64 (without data: prefix)
    const maskDataUrl = maskCanvas.toDataURL("image/png");
    const maskBase64 = maskDataUrl.replace(/^data:image\/png;base64,/, "");

    onSelectionComplete({
      bounds: scaledRect,
      maskBase64,
    });
  }, [currentRect, canvasSize, onSelectionComplete]);

  const hasValidSelection = currentRect && currentRect.width >= 20 && currentRect.height >= 20;

  // Handle keyboard events (Enter to confirm, Escape to cancel)
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Enter" && hasValidSelection) {
        e.preventDefault();
        handleConfirm();
      } else if (e.key === "Escape") {
        e.preventDefault();
        onCancel();
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [hasValidSelection, handleConfirm, onCancel]);

  return (
    <div className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-4">
      <div className="relative w-full max-w-2xl">
        {/* Header */}
        <div className="flex items-center justify-between mb-4">
          <h3 className="text-white punk-text text-lg">Draw a rectangle around the text to edit</h3>
          <button
            onClick={onCancel}
            className="p-2 bg-white/10 hover:bg-white/20 rounded-full text-white"
          >
            <X className="w-5 h-5" />
          </button>
        </div>

        {/* Canvas container */}
        <div
          ref={containerRef}
          className="relative w-full bg-gray-900 punk-border"
          style={{ aspectRatio: "3/4" }}
        >
          <canvas
            ref={canvasRef}
            className={`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 ${
              imageLoaded ? "cursor-crosshair" : "cursor-wait"
            }`}
            onMouseDown={handleStart}
            onMouseMove={handleMove}
            onMouseUp={handleEnd}
            onMouseLeave={handleEnd}
            onTouchStart={handleStart}
            onTouchMove={handleMove}
            onTouchEnd={handleEnd}
          />

          {!imageLoaded && (
            <div className="absolute inset-0 flex items-center justify-center">
              <div className="text-white punk-text">Loading image...</div>
            </div>
          )}
        </div>

        {/* Action buttons */}
        <div className="flex gap-3 mt-4">
          <button
            onClick={onCancel}
            className="flex-1 py-3 px-4 bg-white/10 text-white punk-text border-2 border-white/30 hover:bg-white/20"
          >
            Cancel
          </button>
          <button
            onClick={handleConfirm}
            disabled={!hasValidSelection}
            className={`flex-1 py-3 px-4 punk-text border-2 ${
              hasValidSelection
                ? "bg-green-600 text-white border-green-600 hover:bg-green-700"
                : "bg-gray-600 text-gray-400 border-gray-600 cursor-not-allowed"
            }`}
          >
            {hasValidSelection ? "Edit This Area ↵" : "Draw a selection"}
          </button>
        </div>

        {/* Help text */}
        <p className="text-white/60 text-sm text-center mt-3 punk-text">
          Click and drag to select the text region • Press <kbd className="px-1.5 py-0.5 bg-white/20 rounded">Enter</kbd> to confirm or <kbd className="px-1.5 py-0.5 bg-white/20 rounded">Esc</kbd> to cancel
        </p>
      </div>
    </div>
  );
}
