'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import Cropper, { type Area } from 'react-easy-crop';
import { Camera, ImagePlus, Upload, X, ZoomIn } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { UserAvatar } from '@/components/ui/UserAvatar';
import { getCroppedImageBlob } from '@/lib/cropImage';
import { cn } from '@/lib/utils';
import 'react-easy-crop/react-easy-crop.css';

interface ProfilePhotoPickerProps {
  value?: File | null;
  previewUrl?: string | null;
  onChange: (file: File | null, previewUrl: string | null) => void;
  firstName?: string;
  lastName?: string;
  helperText?: string;
  pendingLabel?: string;
  disabled?: boolean;
  className?: string;
}

export function ProfilePhotoPicker({
  value,
  previewUrl,
  onChange,
  firstName,
  lastName,
  helperText = 'Optional — helps customers recognize you. Upload, take a photo, or drag an image here.',
  pendingLabel,
  disabled = false,
  className,
}: ProfilePhotoPickerProps) {
  const uploadRef = useRef<HTMLInputElement>(null);
  const cameraRef = useRef<HTMLInputElement>(null);
  const cropPixelsRef = useRef<Area | null>(null);

  const [dragOver, setDragOver] = useState(false);
  const [cropOpen, setCropOpen] = useState(false);
  const [imageSrc, setImageSrc] = useState<string | null>(null);
  const [crop, setCrop] = useState({ x: 0, y: 0 });
  const [zoom, setZoom] = useState(1);
  const [cropping, setCropping] = useState(false);
  const [error, setError] = useState('');

  const displayUrl = previewUrl ?? null;

  useEffect(() => {
    return () => {
      if (imageSrc?.startsWith('blob:')) {
        URL.revokeObjectURL(imageSrc);
      }
    };
  }, [imageSrc]);

  const resetCropState = useCallback(() => {
    if (imageSrc?.startsWith('blob:')) {
      URL.revokeObjectURL(imageSrc);
    }
    setImageSrc(null);
    setCrop({ x: 0, y: 0 });
    setZoom(1);
    cropPixelsRef.current = null;
    setCropOpen(false);
    setCropping(false);
  }, [imageSrc]);

  const openImageForCrop = useCallback((file: File) => {
    if (disabled) return;
    if (!file.type.startsWith('image/')) {
      setError('Please choose an image file');
      return;
    }
    if (file.size > 10 * 1024 * 1024) {
      setError('Image must be 10 MB or smaller');
      return;
    }

    setError('');
    const url = URL.createObjectURL(file);
    setImageSrc(url);
    setCrop({ x: 0, y: 0 });
    setZoom(1);
    cropPixelsRef.current = null;
    setCropOpen(true);
  }, [disabled]);

  const handleFileInput = (fileList: FileList | null) => {
    const file = fileList?.[0];
    if (file) openImageForCrop(file);
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setDragOver(false);
    handleFileInput(e.dataTransfer.files);
  };

  const handleApplyCrop = async () => {
    if (!imageSrc || !cropPixelsRef.current) return;
    setCropping(true);
    setError('');
    try {
      const blob = await getCroppedImageBlob(imageSrc, cropPixelsRef.current);
      const file = new File([blob], 'profile-photo.jpg', { type: 'image/jpeg' });
      const nextPreview = URL.createObjectURL(blob);

      if (previewUrl?.startsWith('blob:')) {
        URL.revokeObjectURL(previewUrl);
      }

      onChange(file, nextPreview);
      resetCropState();
    } catch {
      setError('Could not crop image. Please try another photo.');
      setCropping(false);
    }
  };

  const handleRemove = () => {
    if (previewUrl?.startsWith('blob:')) {
      URL.revokeObjectURL(previewUrl);
    }
    onChange(null, null);
    setError('');
  };

  return (
    <div className={cn('space-y-3', className)}>
      <div
        onDragOver={(e) => {
          e.preventDefault();
          setDragOver(true);
        }}
        onDragLeave={(e) => {
          e.preventDefault();
          setDragOver(false);
        }}
        onDrop={handleDrop}
        className={cn(
          'rounded-xl border-2 border-dashed p-4 md:p-5 transition-colors',
          dragOver ? 'border-primary bg-primary/5' : 'border-border bg-slate-50'
        )}
      >
        <div className="flex flex-col sm:flex-row items-center gap-4 md:gap-6">
          <div className="relative shrink-0">
            <UserAvatar
              firstName={firstName}
              lastName={lastName}
              imageSrc={displayUrl}
              size="picker"
              ringClassName="ring-2 ring-white shadow-md"
              alt="Profile preview"
            />
            {displayUrl ? (
              <button
                type="button"
                onClick={handleRemove}
                disabled={disabled}
                className="absolute -top-1 -right-1 flex h-7 w-7 items-center justify-center rounded-full bg-white border border-border text-muted shadow hover:text-red-500 disabled:opacity-50"
                aria-label="Remove profile photo"
              >
                <X className="h-4 w-4" />
              </button>
            ) : null}
          </div>

          <div className="flex-1 text-center sm:text-left space-y-3 min-w-0">
            <div>
              <p className="text-sm md:text-base font-medium text-slate-800">Profile photo</p>
              <p className="text-xs md:text-sm text-muted mt-0.5 leading-relaxed whitespace-pre-line">{helperText}</p>
            </div>

            <div className="flex flex-wrap items-center justify-center sm:justify-start gap-2">
              <Button
                type="button"
                variant="outline"
                size="sm"
                className="gap-2"
                disabled={disabled}
                onClick={() => uploadRef.current?.click()}
              >
                <Upload className="h-4 w-4" />
                Upload
              </Button>
              <Button
                type="button"
                variant="outline"
                size="sm"
                className="gap-2"
                disabled={disabled}
                onClick={() => cameraRef.current?.click()}
              >
                <Camera className="h-4 w-4" />
                Take photo
              </Button>
              {!displayUrl && (
                <span className="text-xs text-muted hidden md:inline-flex items-center gap-1">
                  <ImagePlus className="h-3.5 w-3.5" />
                  or drag image here
                </span>
              )}
            </div>

            {(pendingLabel || value) ? (
              <p className="text-xs text-emerald-600">
                {pendingLabel ?? 'Photo ready'}
              </p>
            ) : null}
          </div>
        </div>
      </div>

      <input
        ref={uploadRef}
        type="file"
        accept="image/*"
        className="hidden"
        onChange={(e) => {
          handleFileInput(e.target.files);
          e.target.value = '';
        }}
      />
      <input
        ref={cameraRef}
        type="file"
        accept="image/*"
        capture="user"
        className="hidden"
        onChange={(e) => {
          handleFileInput(e.target.files);
          e.target.value = '';
        }}
      />

      {error ? <p className="text-sm text-red-500">{error}</p> : null}

      {cropOpen && imageSrc ? (
        <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
          <button
            type="button"
            className="absolute inset-0 bg-black/70"
            aria-label="Close crop dialog"
            onClick={resetCropState}
          />
          <div className="relative z-10 w-full max-w-lg rounded-xl bg-white shadow-xl overflow-hidden">
            <div className="flex items-center justify-between border-b border-border px-4 py-3">
              <h3 className="text-sm font-semibold text-slate-900">Crop profile photo</h3>
              <button
                type="button"
                onClick={resetCropState}
                className="text-muted hover:text-slate-700"
                aria-label="Close"
              >
                <X className="h-5 w-5" />
              </button>
            </div>

            <p className="px-4 pt-3 text-xs text-muted">
              Drag to reposition. Pinch or use the slider to zoom.
            </p>

            <div className="relative h-72 md:h-80 bg-slate-900 mx-4 mt-3 rounded-lg overflow-hidden">
              <Cropper
                image={imageSrc}
                crop={crop}
                zoom={zoom}
                aspect={1}
                cropShape="round"
                showGrid={false}
                onCropChange={setCrop}
                onZoomChange={setZoom}
                onCropComplete={(_area, pixels) => {
                  cropPixelsRef.current = pixels;
                }}
              />
            </div>

            <div className="flex items-center gap-3 px-4 py-4">
              <ZoomIn className="h-4 w-4 text-muted shrink-0" />
              <input
                type="range"
                min={1}
                max={3}
                step={0.05}
                value={zoom}
                onChange={(e) => setZoom(Number(e.target.value))}
                className="flex-1 accent-primary"
                aria-label="Zoom"
              />
            </div>

            <div className="flex flex-col-reverse sm:flex-row sm:justify-end gap-2 border-t border-border px-4 py-4">
              <Button type="button" variant="outline" onClick={resetCropState} disabled={cropping}>
                Cancel
              </Button>
              <Button type="button" onClick={handleApplyCrop} disabled={cropping}>
                {cropping ? 'Saving…' : 'Use photo'}
              </Button>
            </div>
          </div>
        </div>
      ) : null}
    </div>
  );
}
