import { useState, useEffect, useRef, useCallback } from "react";
import type { ToolUiProps } from "../../core/plugins/plugin-types";
import type { ImageRedactorOptions, RedactRect } from "./index";
import { Button } from "../../components/ui/Button";
import { Card } from "../../components/ui/Card";
import { Dropzone } from "../../components/ui/Dropzone";
import { useToolExecution } from "../../components/tool/useToolExecution";

export default function ImageRedactorUi({
  plugin,
}: ToolUiProps<ImageRedactorOptions>) {
  const [files, setFiles] = useState<File[]>([]);
  const [previewUrl, setPreviewUrl] = useState<string>("");
  const [rects, setRects] = useState<RedactRect[]>([]);

  // Drawing state
  const [isDrawing, setIsDrawing] = useState(false);
  const [startPos, setStartPos] = useState({ x: 0, y: 0 });
  const [currentPos, setCurrentPos] = useState({ x: 0, y: 0 });

  const [imageSize, setImageSize] = useState({ width: 0, height: 0 });
  const { run, result, isExecuting, error, reset } = useToolExecution(plugin);

  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!previewUrl) return;

    return () => {
      URL.revokeObjectURL(previewUrl);
    };
  }, [previewUrl]);

  const handleFilesDrop = useCallback((nextFiles: File[]) => {
    setFiles(nextFiles);
    setPreviewUrl(nextFiles.length > 0 ? URL.createObjectURL(nextFiles[0]) : "");
    setRects([]);
    reset();
  }, [reset]);

  const handleClearFiles = useCallback(() => {
    setFiles([]);
    setPreviewUrl("");
    setRects([]);
    reset();
  }, [reset]);

  const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {
    const img = e.currentTarget;
    setImageSize({ width: img.naturalWidth, height: img.naturalHeight });
  };

  const getPercentageCoords = (e: React.PointerEvent<HTMLDivElement>) => {
    if (!containerRef.current) return { x: 0, y: 0 };
    const rect = containerRef.current.getBoundingClientRect();
    const x = ((e.clientX - rect.left) / rect.width) * 100;
    const y = ((e.clientY - rect.top) / rect.height) * 100;
    // Clamp to 0-100 range
    return {
      x: Math.max(0, Math.min(100, x)),
      y: Math.max(0, Math.min(100, y)),
    };
  };

  const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
    if (result) return; // Disable drawing if result is shown
    e.preventDefault();
    (e.target as HTMLElement).setPointerCapture(e.pointerId);
    const coords = getPercentageCoords(e);
    setStartPos(coords);
    setCurrentPos(coords);
    setIsDrawing(true);
  };

  const handlePointerMove = (e: React.PointerEvent<HTMLDivElement>) => {
    if (!isDrawing) return;
    const coords = getPercentageCoords(e);
    setCurrentPos(coords);
  };

  const handlePointerUp = (e: React.PointerEvent<HTMLDivElement>) => {
    if (!isDrawing) return;
    (e.target as HTMLElement).releasePointerCapture(e.pointerId);
    setIsDrawing(false);

    const coords = getPercentageCoords(e);
    const x = Math.min(startPos.x, coords.x);
    const y = Math.min(startPos.y, coords.y);
    const w = Math.abs(coords.x - startPos.x);
    const h = Math.abs(coords.y - startPos.y);

    // Save rectangle if it has some minimum size to avoid tiny single click boxes
    if (w > 0.4 && h > 0.4) {
      setRects((prev) => [...prev, { x, y, w, h }]);
    }
  };

  const handleUndo = () => {
    setRects((prev) => prev.slice(0, -1));
  };

  const handleClear = () => {
    setRects([]);
  };

  const handleRun = useCallback(async () => {
    if (files.length === 0) return;

    await run({ files }, { rects, color: "#000000" });
  }, [files, rects, run]);

  const downloadBlob = useCallback((blob: Blob, filename: string) => {
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }, []);

  // Hotkeys: Ctrl+Enter to redact
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key === "Enter") {
        e.preventDefault();
        if (!isExecuting && files.length > 0 && !result) {
          handleRun();
        }
      }
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [files.length, handleRun, isExecuting, result]);

  // Temporary rectangle styles (while drawing)
  const tempRectStyle = isDrawing
    ? {
        left: `${Math.min(startPos.x, currentPos.x)}%`,
        top: `${Math.min(startPos.y, currentPos.y)}%`,
        width: `${Math.abs(currentPos.x - startPos.x)}%`,
        height: `${Math.abs(currentPos.y - startPos.y)}%`,
      }
    : null;

  return (
    <div className="p-[18px] md:p-[28px] max-w-5xl mx-auto">

      {files.length === 0 ? (
        <Card title="Upload Image to Redact">
          <Dropzone
            accept="image/jpeg,image/png,image/webp"
            multiple={false}
            onFilesDrop={handleFilesDrop}
          />
        </Card>
      ) : (
        <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
          <div className="lg:col-span-2 space-y-6">
            <Card title="Redaction Canvas">
              <div className="text-xs text-gray-400 mb-3">
                Pointer drawing active. Click and drag to place black redaction blocks.
              </div>

              {/* Bounding box wrapper */}
              <div
                ref={containerRef}
                onPointerDown={handlePointerDown}
                onPointerMove={handlePointerMove}
                onPointerUp={handlePointerUp}
                className="relative select-none overflow-hidden cursor-crosshair border border-[var(--p-border)] rounded-lg bg-[var(--p-bg)] max-w-full flex items-center justify-center"
                style={{ touchAction: "none" }}
              >
                <img
                  src={previewUrl}
                  alt="Redaction source"
                  onLoad={handleImageLoad}
                  onDragStart={(e) => e.preventDefault()}
                  className="max-w-full max-h-[60vh] object-contain pointer-events-none"
                />

                {/* Draw saved rectangles */}
                {rects.map((r, i) => (
                  <div
                    key={i}
                    className="absolute bg-black pointer-events-none"
                    style={{
                      left: `${r.x}%`,
                      top: `${r.y}%`,
                      width: `${r.w}%`,
                      height: `${r.h}%`,
                      boxShadow: "0 0 0 1px rgba(255, 255, 255, 0.15)",
                    }}
                  />
                ))}

                {/* Draw active temporary rectangle */}
                {tempRectStyle && (
                  <div
                    className="absolute bg-black/60 border-2 border-red-500 border-dashed pointer-events-none"
                    style={tempRectStyle}
                  />
                )}
              </div>
            </Card>

            {error && (
              <Card className="border-red-200">
                <div className="text-sm text-red-700">{error}</div>
              </Card>
            )}

            {result && result.type === "files" && (
              <Card
                title="Redacted Result"
                className="border-green-200 shadow-md"
              >
                <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 p-4 border border-green-200 bg-green-50/50 rounded-xl">
                  <div className="flex flex-col min-w-0 flex-1">
                    <span className="font-medium text-green-950 truncate" title={result.files[0].name}>
                      {result.files[0].name}
                    </span>
                    <span className="text-xs text-green-700 mt-1">
                      Metadata flattened & redacted successfully.
                    </span>
                  </div>
                  <Button
                    variant="primary"
                    onClick={() => downloadBlob(result.files[0].blob, result.files[0].name)}
                    className="w-full sm:w-auto shrink-0"
                  >
                    Download Redacted Image
                  </Button>
                </div>
              </Card>
            )}
          </div>

          <div className="space-y-6">
            <Card title="Controls">
              <div className="space-y-6">
                <div>
                  <div className="text-sm font-semibold text-gray-800">
                    File details
                  </div>
                  <div className="text-xs text-gray-500 mt-1 truncate">
                    Name: {files[0].name}
                  </div>
                  {imageSize.width > 0 && (
                    <div className="text-xs text-gray-500">
                      Dimensions: {imageSize.width} &times; {imageSize.height} px
                    </div>
                  )}
                  <div className="text-xs text-gray-500">
                    Active redactions: {rects.length}
                  </div>
                </div>

                <div className="flex flex-col gap-2">
                  <Button
                    variant="secondary"
                    onClick={handleUndo}
                    disabled={rects.length === 0 || isExecuting}
                    className="w-full justify-center"
                  >
                    Undo Last Block
                  </Button>
                  <Button
                    variant="secondary"
                    onClick={handleClear}
                    disabled={rects.length === 0 || isExecuting}
                    className="w-full justify-center text-red-600 hover:text-red-700 hover:bg-red-50"
                  >
                    Clear All Blocks
                  </Button>
                </div>

                <div className="pt-4 border-t border-gray-100 flex flex-col gap-2">
                  <Button
                    variant="primary"
                    onClick={handleRun}
                    disabled={isExecuting || rects.length === 0 || result !== null}
                    className="w-full justify-center"
                  >
                    {isExecuting ? "Processing..." : "Apply Redactions"}
                  </Button>
                  <Button
                    variant="secondary"
                    onClick={handleClearFiles}
                    disabled={isExecuting}
                    className="w-full justify-center"
                  >
                    Upload Another Image
                  </Button>
                </div>
              </div>
            </Card>
          </div>
        </div>
      )}
    </div>
  );
}
