"use client";

/**
 * ImageCropper — canvas-based crop modal using react-easy-crop.
 *
 * Usage:
 *   <ImageCropper
 *     src={objectUrl}
 *     aspect={16/7}
 *     presetLabel="Banner Desktop (1920×700)"
 *     onApply={(blob) => { ... }}
 *     onCancel={() => { ... }}
 *   />
 *
 * Aspect ratio presets (passed from parent):
 *   Banner Desktop  → 1920/700  ≈ 2.74
 *   Banner Mobile   → 800/900   ≈ 0.89
 *   Ad Leaderboard  → 970/250   ≈ 3.88
 *   Ad Banner       → 728/90    ≈ 8.09
 *   Ad Sidebar      → 300/600   = 0.50
 */

import { useState, useCallback } from "react";
import Cropper from "react-easy-crop";
import type { Area } from "react-easy-crop";
import { ZoomIn, ZoomOut, RotateCw, Crop, X } from "lucide-react";

interface Props {
  src: string;
  aspect: number;
  presetLabel?: string;
  onApply: (blob: Blob) => void;
  onCancel: () => void;
}

/** Extract the cropped region from the source image using OffscreenCanvas / <canvas>. */
async function getCroppedBlob(
  imageSrc: string,
  pixelCrop: Area,
  rotation: number,
): Promise<Blob> {
  const image = await createImageBitmap(
    await (await fetch(imageSrc)).blob(),
  );

  const canvas  = document.createElement("canvas");
  const ctx     = canvas.getContext("2d")!;

  const { width, height } = pixelCrop;
  canvas.width  = width;
  canvas.height = height;

  ctx.save();
  ctx.translate(width / 2, height / 2);
  ctx.rotate((rotation * Math.PI) / 180);
  ctx.translate(-width / 2, -height / 2);

  ctx.drawImage(
    image,
    pixelCrop.x,
    pixelCrop.y,
    pixelCrop.width,
    pixelCrop.height,
    0,
    0,
    width,
    height,
  );
  ctx.restore();

  return new Promise((resolve, reject) => {
    canvas.toBlob(
      (blob) => (blob ? resolve(blob) : reject(new Error("Canvas is empty"))),
      "image/webp",
      0.92,
    );
  });
}

export default function ImageCropper({ src, aspect, presetLabel, onApply, onCancel }: Props) {
  const [crop,        setCrop]        = useState({ x: 0, y: 0 });
  const [zoom,        setZoom]        = useState(1);
  const [rotation,    setRotation]    = useState(0);
  const [croppedArea, setCroppedArea] = useState<Area | null>(null);
  const [applying,    setApplying]    = useState(false);

  const onCropComplete = useCallback((_: Area, croppedAreaPixels: Area) => {
    setCroppedArea(croppedAreaPixels);
  }, []);

  async function handleApply() {
    if (!croppedArea) return;
    setApplying(true);
    try {
      const blob = await getCroppedBlob(src, croppedArea, rotation);
      onApply(blob);
    } catch (err) {
      console.error("Crop failed:", err);
    } finally {
      setApplying(false);
    }
  }

  return (
    <div className="fixed inset-0 z-[60] flex items-center justify-center bg-black/80 backdrop-blur-sm p-4">
      <div className="bg-white rounded-3xl w-full max-w-2xl overflow-hidden shadow-2xl flex flex-col">
        {/* Header */}
        <div className="flex items-center justify-between px-5 py-3.5 border-b border-gray-100">
          <div>
            <h3 className="text-sm font-black text-gray-900 flex items-center gap-2">
              <Crop className="w-4 h-4 text-blue-500" />
              Crop Image
            </h3>
            {presetLabel && (
              <p className="text-[11px] text-gray-400 mt-0.5">{presetLabel}</p>
            )}
          </div>
          <button onClick={onCancel}
            className="p-1.5 rounded-lg hover:bg-gray-100 transition-colors">
            <X className="w-4 h-4 text-gray-500" />
          </button>
        </div>

        {/* Crop canvas */}
        <div className="relative bg-gray-900" style={{ height: 380 }}>
          <Cropper
            image={src}
            crop={crop}
            zoom={zoom}
            rotation={rotation}
            aspect={aspect}
            onCropChange={setCrop}
            onZoomChange={setZoom}
            onCropComplete={onCropComplete}
            showGrid
            style={{
              containerStyle: { borderRadius: 0 },
              cropAreaStyle:  { border: "2px solid #3b82f6", borderRadius: 4 },
            }}
          />
        </div>

        {/* Controls */}
        <div className="px-5 py-4 space-y-3">
          {/* Zoom */}
          <div className="flex items-center gap-3">
            <ZoomOut className="w-4 h-4 text-gray-400 shrink-0" />
            <input
              type="range"
              min={1} max={3} step={0.05}
              value={zoom}
              onChange={(e) => setZoom(Number(e.target.value))}
              className="flex-1"
            />
            <ZoomIn className="w-4 h-4 text-gray-400 shrink-0" />
            <span className="text-xs font-mono text-gray-500 w-10 text-right">
              {zoom.toFixed(2)}×
            </span>
          </div>

          {/* Rotation */}
          <div className="flex items-center gap-3">
            <RotateCw className="w-4 h-4 text-gray-400 shrink-0" />
            <input
              type="range"
              min={-180} max={180} step={1}
              value={rotation}
              onChange={(e) => setRotation(Number(e.target.value))}
              className="flex-1"
            />
            <span className="text-xs font-mono text-gray-500 w-10 text-right">
              {rotation}°
            </span>
            <button onClick={() => setRotation(0)}
              className="text-[10px] text-gray-400 hover:text-gray-700 underline">
              reset
            </button>
          </div>

          {/* Actions */}
          <div className="flex gap-3 pt-1">
            <button onClick={onCancel}
              className="flex-1 py-2.5 rounded-xl border border-gray-200 text-sm font-semibold text-gray-600 hover:bg-gray-50 transition-colors"
            >
              Cancel
            </button>
            <button onClick={handleApply} disabled={applying || !croppedArea}
              className="flex-1 py-2.5 rounded-xl bg-gradient-to-r from-blue-600 to-cyan-500 text-white text-sm font-black hover:opacity-90 disabled:opacity-50 transition-all flex items-center justify-center gap-2"
            >
              <Crop className="w-4 h-4" />
              {applying ? "Applying…" : "Apply Crop"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
