'use client'

import { useState, useRef } from 'react'
import { useRouter } from 'next/navigation'
import { Upload, X } from 'lucide-react'

export interface UploadedImage {
  id?: string
  path: string
  url: string
  isCover?: boolean
}

interface Props {
  listingId: string
  images: UploadedImage[]
  onChange: (imgs: UploadedImage[]) => void
}

const ALLOWED = 'image/jpeg,image/png,image/webp'

export function ImageUploader({ listingId, images, onChange }: Props) {
  const router = useRouter()
  const [uploading, setUploading] = useState(false)
  const [error, setError] = useState('')
  const inputRef = useRef<HTMLInputElement>(null)

  async function handleFiles(files: FileList) {
    if (!files.length) return
    setUploading(true)
    setError('')
    try {
      const fd = new FormData()
      fd.append('listingId', listingId)
      for (const f of Array.from(files)) fd.append('files', f)
      const res = await fetch('/api/upload', { method: 'POST', body: fd })
      if (!res.ok) {
        const err = await res.json().catch(() => ({}))
        throw new Error(err.error || `Upload failed (${res.status})`)
      }
      const { data } = await res.json()
      onChange([...images, ...data])
      router.refresh()
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Upload failed')
    } finally {
      setUploading(false)
    }
  }

  async function removeImage(img: UploadedImage, idx: number) {
    if (!img.id) {
      // Imagen recién subida sin persistir — solo local
      onChange(images.filter((_, i) => i !== idx))
      return
    }
    if (!confirm('Delete this image?')) return
    try {
      const res = await fetch(`/api/agent/listings/${listingId}/images/${img.id}`, {
        method: 'DELETE',
      })
      if (!res.ok) throw new Error(`Delete failed (${res.status})`)
      onChange(images.filter((_, i) => i !== idx))
      router.refresh()
    } catch (e) {
      alert(e instanceof Error ? e.message : 'Delete failed')
    }
  }

  async function setCover(img: UploadedImage, idx: number) {
    if (!img.id) return
    try {
      const res = await fetch(`/api/agent/listings/${listingId}/images/${img.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ isCover: true }),
      })
      if (!res.ok) throw new Error(`Set cover failed (${res.status})`)
      onChange(images.map((cur, i) => ({ ...cur, isCover: i === idx })))
      router.refresh()
    } catch (e) {
      alert(e instanceof Error ? e.message : 'Set cover failed')
    }
  }

  return (
    <div>
      <div
        onClick={() => inputRef.current?.click()}
        onDragOver={(e) => e.preventDefault()}
        onDrop={(e) => {
          e.preventDefault()
          if (e.dataTransfer.files.length) handleFiles(e.dataTransfer.files)
        }}
        className="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center cursor-pointer hover:border-[#374527] transition"
      >
        <Upload className="mx-auto text-gray-400 mb-2" size={32} />
        <p className="text-sm text-gray-600">
          {uploading ? 'Uploading...' : 'Click or drag images here'}
        </p>
        <p className="text-xs text-gray-400 mt-1">
          JPG, PNG or WebP. Max 20MB each. Up to 20 at once.
        </p>
        <input
          ref={inputRef}
          type="file"
          accept={ALLOWED}
          multiple
          hidden
          onChange={(e) => e.target.files && handleFiles(e.target.files)}
        />
      </div>

      {error && (
        <p className="text-sm text-red-600 mt-2" role="alert">
          {error}
        </p>
      )}

      {images.length > 0 && (
        <div className="grid grid-cols-2 md:grid-cols-4 gap-3 mt-4">
          {images.map((img, idx) => (
            <div key={img.path + idx} className="relative group">
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img
                src={img.url}
                alt=""
                className="w-full aspect-square object-cover rounded"
              />
              <button
                onClick={() => removeImage(img, idx)}
                type="button"
                className="absolute top-1 right-1 bg-red-500 text-white rounded-full p-1 opacity-0 group-hover:opacity-100 transition"
                aria-label="Remove"
              >
                <X size={14} />
              </button>
              {img.isCover ? (
                <span className="absolute bottom-1 left-1 bg-[#374527] text-white text-xs px-2 py-0.5 rounded">
                  Cover
                </span>
              ) : (
                <button
                  onClick={() => setCover(img, idx)}
                  type="button"
                  className="absolute bottom-1 left-1 bg-white text-xs px-2 py-0.5 rounded opacity-0 group-hover:opacity-100 transition"
                >
                  Set cover
                </button>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  )
}