"use client";

import { useState, useRef, useCallback } from "react";
import ReactCrop, {
  type Crop,
  type PixelCrop,
  centerCrop,
  makeAspectCrop,
} from "react-image-crop";
import "react-image-crop/dist/ReactCrop.css";
import { X } from "lucide-react";

interface CropPreset {
  label: string;
  aspect: number | undefined;
}

const PRESETS: CropPreset[] = [
  { label: "Twitter 16:9", aspect: 16 / 9 },
  { label: "Twitter 1:1", aspect: 1 },
  { label: "LinkedIn 1.91:1", aspect: 1.91 },
  { label: "Free crop", aspect: undefined },
];

interface CropModalProps {
  file: File;
  defaultPresetIndex?: number;
  onApply: (croppedFile: File) => void;
  onCancel: () => void;
}

function getCenteredCrop(
  mediaWidth: number,
  mediaHeight: number,
  aspect: number
): Crop {
  return centerCrop(
    makeAspectCrop(
      { unit: "%", width: 90 },
      aspect,
      mediaWidth,
      mediaHeight
    ),
    mediaWidth,
    mediaHeight
  );
}

export function CropModal({
  file,
  defaultPresetIndex = 0,
  onApply,
  onCancel,
}: CropModalProps) {
  const [crop, setCrop] = useState<Crop>();
  const [completedCrop, setCompletedCrop] = useState<PixelCrop>();
  const [activePreset, setActivePreset] = useState(defaultPresetIndex);
  const [aspect, setAspect] = useState<number | undefined>(
    PRESETS[defaultPresetIndex]?.aspect
  );
  const imgRef = useRef<HTMLImageElement>(null);
  const [imgSrc] = useState(() => URL.createObjectURL(file));
  const [applying, setApplying] = useState(false);

  const onImageLoad = useCallback(
    (e: React.SyntheticEvent<HTMLImageElement>) => {
      const { naturalWidth, naturalHeight } = e.currentTarget;
      const presetAspect = PRESETS[activePreset]?.aspect;
      if (presetAspect) {
        setCrop(getCenteredCrop(naturalWidth, naturalHeight, presetAspect));
      } else {
        setCrop({
          unit: "%",
          x: 5,
          y: 5,
          width: 90,
          height: 90,
        });
      }
    },
    [activePreset]
  );

  const selectPreset = (index: number) => {
    setActivePreset(index);
    const preset = PRESETS[index];
    setAspect(preset.aspect);

    const img = imgRef.current;
    if (!img) return;

    if (preset.aspect) {
      setCrop(
        getCenteredCrop(img.naturalWidth, img.naturalHeight, preset.aspect)
      );
    } else {
      setCrop({ unit: "%", x: 5, y: 5, width: 90, height: 90 });
    }
  };

  const handleApply = async () => {
    const img = imgRef.current;
    if (!img || !completedCrop) return;

    setApplying(true);
    try {
      const canvas = document.createElement("canvas");
      const scaleX = img.naturalWidth / img.width;
      const scaleY = img.naturalHeight / img.height;

      canvas.width = completedCrop.width * scaleX;
      canvas.height = completedCrop.height * scaleY;

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

      ctx.drawImage(
        img,
        completedCrop.x * scaleX,
        completedCrop.y * scaleY,
        completedCrop.width * scaleX,
        completedCrop.height * scaleY,
        0,
        0,
        canvas.width,
        canvas.height
      );

      const blob = await new Promise<Blob | null>((resolve) =>
        canvas.toBlob(resolve, file.type || "image/jpeg", 0.92)
      );

      if (!blob) return;

      const baseName = file.name.replace(/\.[^.]+$/, "");
      const ext = file.name.split(".").pop() ?? "jpg";
      const croppedFile = new File([blob], `cropped-${baseName}.${ext}`, {
        type: file.type || "image/jpeg",
      });

      onApply(croppedFile);
    } finally {
      setApplying(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
      <div className="relative mx-2 sm:mx-4 flex h-[90vh] sm:h-auto sm:max-h-[90vh] w-full max-w-lg flex-col rounded-xl bg-white shadow-xl">
        {/* Header */}
        <div className="flex items-center justify-between border-b px-4 py-3">
          <h3 className="text-sm font-semibold text-gray-900">Crop Image</h3>
          <button
            type="button"
            onClick={onCancel}
            className="rounded-full p-1 text-gray-400 hover:bg-gray-100 hover:text-gray-600"
          >
            <X className="h-4 w-4" />
          </button>
        </div>

        {/* Presets */}
        <div className="flex flex-wrap gap-1.5 border-b px-3 sm:px-4 py-2">
          {PRESETS.map((p, i) => (
            <button
              key={p.label}
              type="button"
              onClick={() => selectPreset(i)}
              className={`rounded-full px-3 sm:px-2.5 py-2 sm:py-1 min-h-[44px] sm:min-h-0 text-xs font-medium transition-colors ${
                activePreset === i
                  ? "bg-gray-900 text-white"
                  : "bg-gray-100 text-gray-600 hover:bg-gray-200"
              }`}
            >
              {p.label}
            </button>
          ))}
        </div>

        {/* Crop area */}
        <div className="flex-1 overflow-auto p-4">
          <ReactCrop
            crop={crop}
            onChange={(c) => setCrop(c)}
            onComplete={(c) => setCompletedCrop(c)}
            aspect={aspect}
            keepSelection
          >
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img
              ref={imgRef}
              src={imgSrc}
              alt="Crop preview"
              onLoad={onImageLoad}
              className="max-h-[50vh] w-full object-contain"
            />
          </ReactCrop>
        </div>

        {/* Actions */}
        <div className="flex flex-col-reverse sm:flex-row sm:justify-end gap-2 border-t px-3 sm:px-4 py-3">
          <button
            type="button"
            onClick={onCancel}
            className="rounded-lg border border-gray-200 px-4 py-2.5 sm:py-1.5 min-h-[44px] sm:min-h-0 text-sm text-gray-700 hover:bg-gray-50 w-full sm:w-auto"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={handleApply}
            disabled={!completedCrop || applying}
            className="rounded-lg bg-gray-900 px-4 py-2.5 sm:py-1.5 min-h-[44px] sm:min-h-0 text-sm font-medium text-white hover:bg-gray-800 disabled:opacity-50 w-full sm:w-auto"
          >
            {applying ? "Applying..." : "Apply Crop"}
          </button>
        </div>
      </div>
    </div>
  );
}
