import { useCallback, useEffect, useState } from 'react'
import Cropper, { type Area } from 'react-easy-crop'
import { ImagePlus, X } from 'lucide-react'
import { getCroppedImage } from '../utils/cropImage'
import styles from './ImageCropper.module.css'

type ImageCropperProps = {
  value: string | null
  onChange: (value: string | null) => void
  aspect?: number
  uploadLabel?: string
  hint?: string
  changeLabel?: string
}

export function ImageCropper({
  value,
  onChange,
  aspect = 1,
  uploadLabel = 'آپلود تصویر اصلی',
  hint = 'برای برش مربعی ۱:۱ کلیک کنید',
  changeLabel = 'تغییر تصویر',
}: ImageCropperProps) {
  const [imageSrc, setImageSrc] = useState<string | null>(null)
  const [crop, setCrop] = useState({ x: 0, y: 0 })
  const [zoom, setZoom] = useState(1)
  const [croppedArea, setCroppedArea] = useState<Area | null>(null)

  useEffect(() => {
    setCrop({ x: 0, y: 0 })
    setZoom(1)
    setCroppedArea(null)
  }, [aspect])

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

  function handleFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0]
    if (!file) return
    const reader = new FileReader()
    reader.onload = () => {
      setImageSrc(reader.result as string)
      setCrop({ x: 0, y: 0 })
      setZoom(1)
      setCroppedArea(null)
    }
    reader.readAsDataURL(file)
    e.target.value = ''
  }

  async function applyCrop() {
    if (!imageSrc || !croppedArea) return
    const cropped = await getCroppedImage(imageSrc, croppedArea, 'jpeg')
    onChange(cropped)
    setImageSrc(null)
    setZoom(1)
    setCrop({ x: 0, y: 0 })
  }

  function cancelCrop() {
    setImageSrc(null)
    setZoom(1)
    setCrop({ x: 0, y: 0 })
  }

  return (
    <div className={styles.wrapper}>
      {value && !imageSrc && (
        <div className={styles.preview}>
          <img src={value} alt="پیش‌نمایش تصویر" className={styles.previewImg} />
          <button
            type="button"
            className={styles.removeBtn}
            onClick={() => onChange(null)}
            aria-label="حذف تصویر"
          >
            <X size={16} />
          </button>
        </div>
      )}

      {!value && !imageSrc && (
        <label className={styles.uploadZone}>
          <ImagePlus size={28} />
          <span>{uploadLabel}</span>
          <span className={styles.hint}>{hint}</span>
          <input type="file" accept="image/*" onChange={handleFile} hidden />
        </label>
      )}

      {imageSrc && (
        <div className={styles.cropPanel}>
          <div className={styles.cropArea}>
            <Cropper
              image={imageSrc}
              crop={crop}
              zoom={zoom}
              aspect={aspect}
              onCropChange={setCrop}
              onZoomChange={setZoom}
              onCropComplete={onCropComplete}
            />
          </div>
          <div className={styles.cropControls}>
            <label className={styles.zoomLabel}>
              بزرگ‌نمایی
              <input
                type="range"
                min={1}
                max={3}
                step={0.05}
                value={zoom}
                onChange={(e) => setZoom(Number(e.target.value))}
              />
            </label>
            <div className={styles.cropActions}>
              <button type="button" className={styles.cancelBtn} onClick={cancelCrop}>
                انصراف
              </button>
              <button
                type="button"
                className={styles.applyBtn}
                onClick={() => void applyCrop()}
                disabled={!croppedArea}
              >
                اعمال برش
              </button>
            </div>
          </div>
        </div>
      )}

      {value && !imageSrc && (
        <label className={styles.changeBtn}>
          {changeLabel}
          <input type="file" accept="image/*" onChange={handleFile} hidden />
        </label>
      )}
    </div>
  )
}
