'use client';
import { useState, useEffect, useRef, useCallback } from 'react';
import { productsApi } from '@/lib/api-client';
import type { ProductImage } from '@/types';

interface ImagesSectionProps {
  productId?: string;
}

export function ImagesSection({ productId }: ImagesSectionProps) {
  const [images, setImages] = useState<ProductImage[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [urlInput, setUrlInput] = useState('');
  const [savingUrl, setSavingUrl] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [dragOver, setDragOver] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);

  const load = useCallback(async () => {
    if (!productId) return;
    const pid = productId;
    try {
      const p = await productsApi.get(pid);
      setImages(p.images ?? []);
    } catch {
      setError('Error al cargar imágenes');
    } finally {
      setLoading(false);
    }
  }, [productId]);

  useEffect(() => { load(); }, [load]);

  const addImageByUrl = async (url: string) => {
    if (!url.trim()) return;
    setSavingUrl(true);
    try {
      const uploadResponse = await fetch('/api/upload', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ url: url.trim() }),
      });
      const uploadData = await uploadResponse.json().catch(() => ({})) as { url?: string; error?: string };
      if (!uploadResponse.ok || !uploadData.url) {
        throw new Error(uploadData.error ?? 'No se pudo descargar la imagen');
      }

      const attachResponse = await fetch(`/api/products/${productId}/images`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ url: uploadData.url, altText: '', role: 'gallery' }),
      });
      if (!attachResponse.ok) {
        const attachData = await attachResponse.json().catch(() => ({})) as { message?: string; error?: string };
        throw new Error(attachData.message ?? attachData.error ?? 'No se pudo adjuntar la imagen');
      }
      setUrlInput('');
      load();
    } catch (cause) {
      setError(cause instanceof Error ? cause.message : 'Error al añadir imagen');
    } finally {
      setSavingUrl(false);
    }
  };

  const uploadFile = async (file: File) => {
    setUploading(true);
    setError('');
    try {
      const fd = new FormData();
      fd.append('file', file);
      const res = await fetch('/api/upload', { method: 'POST', body: fd, credentials: 'include' });
      if (!res.ok) {
        const data = await res.json();
        throw new Error(data.error ?? 'Error al subir');
      }
      const { url } = await res.json() as { url: string };
      await fetch(`/api/products/${productId}/images`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', credentials: 'include' },
        body: JSON.stringify({ url, altText: '', role: 'gallery' }),
      });
      load();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Error al subir');
    } finally {
      setUploading(false);
    }
  };

  const handleFileInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      if (productId) uploadFile(file);
      else queueFile(file);
    }
  };

  // Cola de archivos dropeados antes de tener productId — se suben automáticamente
  // cuando productId se setea desde el padre (F-135).
  const [pendingFiles, setPendingFiles] = useState<File[]>([]);
  const queueFile = (file: File) => {
    setPendingFiles(prev => [...prev, file]);
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setDragOver(false);
    const files = Array.from(e.dataTransfer.files).filter(f => f.type.startsWith('image/'));
    if (files.length === 0) return;
    if (productId) {
      // Subir inmediatamente (en serie para evitar carreras)
      void (async () => {
        for (const f of files) {
          await uploadFile(f);
        }
      })();
    } else {
      // Pendiente: encolar para subir tras crear el producto
      setPendingFiles(prev => [...prev, ...files]);
    }
  };

  // Efecto: cuando productId pasa de undefined a definido, subir la cola
  const prevProductIdRef = useRef<string | undefined>(productId);
  useEffect(() => {
    const prev = prevProductIdRef.current;
    prevProductIdRef.current = productId;
    if (!productId || prev === productId) return;
    if (pendingFiles.length === 0) return;
    const queue = pendingFiles;
    setPendingFiles([]);
    void (async () => {
      for (const f of queue) {
        await uploadFile(f);
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [productId]);

  const setMain = async (imageId: string) => {
    // Reorder: put this image first
    await fetch(`/api/products/${productId}/images/reorder`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json', credentials: 'include' },
      body: JSON.stringify({
        items: [
          { imageId, position: 0 },
          ...images.filter(i => i.id !== imageId).map((img, idx) => ({ imageId: img.id, position: idx + 1 })),
        ],
      }),
    });
    load();
  };

  const deleteImage = async (imageId: string) => {
    await fetch(`/api/products/${productId}/images/${imageId}`, { method: 'DELETE', credentials: 'include' });
    load();
  };

  if (!productId) {
    // Pending state: render UI con drop zone funcional — los archivos dropeados
    // se encolan y se suben automáticamente cuando productId se setea (F-135).
    return (
      <div className="space-y-5">
        <div className="flex items-center justify-between">
          <h3 className="text-sm font-bold text-gray-900">Imágenes</h3>
          <span className="text-xs text-gray-400">Se subirán al crear el producto</span>
        </div>
        <div className="flex flex-col gap-3 sm:flex-row opacity-50 pointer-events-none">
          <input
            type="text"
            value=""
            readOnly
            placeholder="Pega una URL de imagen..."
            className="flex-1 px-4 py-2.5 border border-gray-300 rounded-xl text-sm bg-gray-50"
          />
          <button
            type="button"
            disabled
            className="px-5 py-2.5 bg-[#2D6A4F] disabled:opacity-50 text-white text-sm font-semibold rounded-xl transition-colors"
          >
            Añadir URL
          </button>
          <button
            type="button"
            disabled
            className="px-5 py-2.5 border border-gray-300 text-gray-700 text-sm font-medium rounded-xl transition-colors"
          >
            📤 Subir imagen
          </button>
        </div>
        <div
          onDragOver={e => { e.preventDefault(); setDragOver(true); }}
          onDragLeave={() => setDragOver(false)}
          onDrop={handleDrop}
          className={`border-2 border-dashed rounded-xl p-8 text-center transition-colors ${
            dragOver ? 'border-[#2D6A4F] bg-[#2D6A4F]/5' : 'border-gray-300'
          }`}
        >
          <p className="text-gray-600 text-sm">
            🖼️ Arrastra imágenes aquí para añadirlas al producto
          </p>
          {pendingFiles.length > 0 && (
            <p className="mt-2 text-xs text-amber-700">
              {pendingFiles.length} imagen{pendingFiles.length === 1 ? '' : 'es'} en cola — se subirán al crear el producto
            </p>
          )}
        </div>
      </div>
    );
  }

  if (loading) return <div className="p-8 text-gray-400 text-sm">Cargando imágenes...</div>;

  return (
    <div className="space-y-5">
      {/* Upload / URL / Drag&drop */}
      <div className="flex flex-col gap-3 sm:flex-row">
        <input
          type="text"
          value={urlInput}
          onChange={e => setUrlInput(e.target.value)}
          onKeyDown={e => e.key === 'Enter' && addImageByUrl(urlInput)}
          placeholder="Pega una URL de imagen..."
          className="flex-1 px-4 py-2.5 border border-gray-300 rounded-xl text-sm focus:ring-2 focus:ring-[#2D6A4F] outline-none"
        />
        <button
          onClick={() => addImageByUrl(urlInput)}
          disabled={savingUrl || !urlInput.trim()}
          className="px-5 py-2.5 bg-[#2D6A4F] hover:bg-[#1B4332] disabled:opacity-50 text-white text-sm font-semibold rounded-xl transition-colors"
        >
          {savingUrl ? 'Añadiendo...' : 'Añadir URL'}
        </button>
        <button
          onClick={() => fileRef.current?.click()}
          disabled={uploading}
          className="px-5 py-2.5 border border-gray-300 hover:border-[#2D6A4F] text-gray-700 text-sm font-medium rounded-xl transition-colors"
        >
          {uploading ? 'Subiendo...' : '📤 Subir imagen'}
        </button>
        <input ref={fileRef} type="file" accept="image/*" className="hidden" onChange={handleFileInput} />
      </div>

      {/* Drop zone */}
      <div
        onDragOver={e => { e.preventDefault(); setDragOver(true); }}
        onDragLeave={() => setDragOver(false)}
        onDrop={handleDrop}
        className={`border-2 border-dashed rounded-xl p-8 text-center transition-colors ${
          dragOver ? 'border-[#2D6A4F] bg-[#2D6A4F]/5' : 'border-gray-200'
        }`}
      >
        <p className="text-gray-400 text-sm">
          🖼️ Arrastra imágenes aquí para añadirlas al producto
        </p>
      </div>

      {error && (
        <div className="p-3 bg-red-50 border border-red-200 rounded-xl text-sm text-red-700">{error}</div>
      )}

      {/* Gallery */}
      {images.length === 0 ? (
        <div className="p-8 text-center text-gray-400 text-sm border border-dashed border-gray-300 rounded-xl">
          No hay imágenes para este producto
        </div>
      ) : (
        <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4">
          {images.map((img, idx) => (
            <div key={img.id} className="relative group">
              {/* Use 200px thumbnail for editor preview to reduce bandwidth.
                  Container caps the bounding box (max 280px tall to match the
                  1.4 aspect ratio used by the backend thumbnail); the image
                  preserves its source aspect ratio via `object-contain`. */}
              <div className="w-full max-h-72 aspect-[5/7] bg-gray-100 rounded-xl overflow-hidden flex items-center justify-center">
                <img
                  src={img.url.replace('/uploads/', '/uploads/200/')}
                  alt={img.altText ?? img.url}
                  className="max-w-full max-h-full w-auto h-auto object-contain"
                />
              </div>
              {/* Main badge */}
              {idx === 0 && (
                <span className="absolute top-2 left-2 px-2 py-0.5 bg-[#2D6A4F] text-white text-xs font-medium rounded-full">
                  Principal
                </span>
              )}
              {/* Actions */}
              <div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity rounded-xl flex items-center justify-center gap-2">
                {idx !== 0 && (
                  <button
                    onClick={() => setMain(img.id)}
                    className="px-2 py-1 bg-white text-gray-800 text-xs rounded-lg hover:bg-gray-100"
                  >
                    Principal
                  </button>
                )}
                <button
                  onClick={() => deleteImage(img.id)}
                  className="p-2 bg-white text-red-600 rounded-lg hover:bg-red-50"
                  title="Eliminar"
                >
                  🗑️
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
