import { useState, useEffect, useMemo } from "react";
import { useMutation, useQuery } from "@tanstack/react-query";
import { queryClient } from "@/client/rpc-client";

export function AdminGallery() {
  // Component state
  const [photoTitle, setPhotoTitle] = useState<string>("");
  const [photoPreview, setPhotoPreview] = useState<string>("");
  const [photoBase64, setPhotoBase64] = useState<string>("");
  const [errorMsg, setErrorMsg] = useState<string>("");
  const [successMsg, setSuccessMsg] = useState<string>("");
  const [draggedPhotoId, setDraggedPhotoId] = useState<string | null>(null);

  // Data fetching with live query
  const { data: photos, refetch: refetchPhotos } = useQuery(
    queryClient.gallery.live.adminListPhotos.experimental_liveOptions({
      input: { sessionId: localStorage.getItem("sessionId") || "" }
    })
  );

  // Memoized sorted photos to avoid re-sorting on every render and prevent cache mutation
  const sortedPhotos = useMemo(() => [...(photos || [])].sort((a, b) => a.order - b.order), [photos]);

  // Mutations
  const { mutate: uploadPhoto, isPending: isUploading } = useMutation(
    queryClient.gallery.uploadPhoto.mutationOptions()
  );
  const { mutate: deletePhoto } = useMutation(
    queryClient.gallery.deletePhoto.mutationOptions()
  );
  const { mutate: updatePhotoOrder } = useMutation(
    queryClient.gallery.updatePhotoOrder.mutationOptions()
  );
  const { mutate: setCoverPhoto } = useMutation(
    queryClient.gallery.setCoverPhoto.mutationOptions()
  );

  // Auto-clear messages after 5 seconds
  useEffect(() => {
    if (errorMsg) {
      const timer = setTimeout(() => setErrorMsg(""), 5000);
      return () => clearTimeout(timer);
    }
  }, [errorMsg]);

  useEffect(() => {
    if (successMsg) {
      const timer = setTimeout(() => setSuccessMsg(""), 5000);
      return () => clearTimeout(timer);
    }
  }, [successMsg]);

  // Image compression function (adapted from booking-form.tsx)
  const compressImage = (file: File, maxWidth: number = 800, quality: number = 0.8): Promise<string> => {
    return new Promise((resolve, reject) => {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      const img = new Image();
      
      img.onload = () => {
        // Calculate new dimensions
        let { width, height } = img;
        if (width > maxWidth) {
          height = (height * maxWidth) / width;
          width = maxWidth;
        }
        
        canvas.width = width;
        canvas.height = height;
        
        // Draw and compress
        ctx?.drawImage(img, 0, 0, width, height);
        const compressedDataUrl = canvas.toDataURL('image/jpeg', quality);
        resolve(compressedDataUrl);
      };
      
      img.onerror = reject;
      img.src = URL.createObjectURL(file);
    });
  };

  // File upload handler
  const handlePhotoUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    
    // Validate file type
    if (!file.type.startsWith('image/')) {
      setErrorMsg("Bitte wähle nur Bilddateien aus.");
      return;
    }

    // Check file size (max 1MB)
    if (file.size > 1 * 1024 * 1024) {
      setErrorMsg("Das Foto ist zu groß. Bitte wähle ein Bild unter 1MB.");
      return;
    }

    try {
      // Helper: measure DataURL size via Blob
      const getDataUrlSizeBytes = async (dataUrl: string): Promise<number> => {
        const res = await fetch(dataUrl);
        const blob = await res.blob();
        return blob.size;
      };

      // Try compressing with decreasing quality until <= 1MB or give up
      const qualitySteps = [0.8, 0.6, 0.4];
      let finalDataUrl = "";
      for (const q of qualitySteps) {
        const candidate = await compressImage(file, 800, q);
        const sizeBytes = await getDataUrlSizeBytes(candidate);
        if (sizeBytes <= 1 * 1024 * 1024) {
          finalDataUrl = candidate;
          break;
        }
      }

      if (!finalDataUrl) {
        setErrorMsg("Das komprimierte Bild ist weiterhin größer als 1MB. Bitte wähle ein kleineres Bild.");
        return;
      }

      setPhotoBase64(finalDataUrl);
      setPhotoPreview(finalDataUrl);
      setErrorMsg("");
    } catch (error) {
      console.error('Photo compression failed:', error);
      setErrorMsg('Fehler beim Verarbeiten des Bildes. Bitte versuche es mit einem anderen Bild.');
      return;
    }
  };

  const removePhoto = () => {
    setPhotoBase64("");
    setPhotoPreview("");
    // Reset file input
    const fileInput = document.getElementById('gallery-photo-upload') as HTMLInputElement;
    if (fileInput) fileInput.value = '';
  };

  // Drag and drop handlers
  const handleDragStart = (e: React.DragEvent, photoId: string) => {
    setDraggedPhotoId(photoId);
    e.dataTransfer.effectAllowed = 'move';
  };

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
  };

  const handleDrop = (e: React.DragEvent, targetPhotoId: string) => {
    e.preventDefault();
    
    if (!draggedPhotoId || draggedPhotoId === targetPhotoId) {
      setDraggedPhotoId(null);
      return;
    }

    const draggedPhoto = photos?.find(p => p.id === draggedPhotoId);
    const targetPhoto = photos?.find(p => p.id === targetPhotoId);
    
    if (!draggedPhoto || !targetPhoto) {
      setDraggedPhotoId(null);
      return;
    }

    const sessionId = localStorage.getItem("sessionId");
    if (!sessionId) {
      setErrorMsg("Nicht eingeloggt. Bitte als Inhaber anmelden.");
      setDraggedPhotoId(null);
      return;
    }

    // Build a fully reordered list based on the current sorted order
    const sorted = [...(photos || [])].sort((a, b) => a.order - b.order);
    const fromIndex = sorted.findIndex(p => p.id === draggedPhotoId);
    const toIndex = sorted.findIndex(p => p.id === targetPhotoId);
    if (fromIndex === -1 || toIndex === -1) {
      setDraggedPhotoId(null);
      return;
    }

    const reordered = [...sorted];
    const [moved] = reordered.splice(fromIndex, 1);
    reordered.splice(toIndex, 0, moved);

    // Reindex orders 0..n-1
    const photoOrders = reordered.map((p, idx) => ({ id: p.id, order: idx }));

    updatePhotoOrder(
      {
        sessionId,
        photoOrders
      },
      {
        onSuccess: () => {
          setSuccessMsg("Foto-Reihenfolge aktualisiert.");
          // Sofortige Aktualisierung der Thumbnails in korrekter Reihenfolge
          refetchPhotos();
        },
        onError: (err: any) => {
          setErrorMsg(err?.message || "Fehler beim Aktualisieren der Reihenfolge.");
        }
      }
    );

    setDraggedPhotoId(null);
  };

  const handleDragEnd = () => {
    setDraggedPhotoId(null);
  };

  return (
    <div className="max-w-6xl mx-auto space-y-6">
      {/* Error and Success Messages */}
      {errorMsg && (
        <div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-md">
          <div className="flex items-center">
            <svg className="w-5 h-5 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
              <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
            </svg>
            <span className="font-medium">{errorMsg}</span>
          </div>
        </div>
      )}

      {successMsg && (
        <div className="bg-green-50 border border-green-200 text-green-700 px-4 py-3 rounded-md">
          <div className="flex items-center">
            <svg className="w-5 h-5 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
              <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
            </svg>
            <span className="font-medium">{successMsg}</span>
          </div>
        </div>
      )}

      {/* Upload Form Section */}
      <div className="bg-white rounded-lg shadow p-6">
        <h3 className="text-lg font-semibold mb-4">Neues Foto hochladen</h3>
        
        <div className="space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Foto auswählen *
            </label>
            <input
              id="gallery-photo-upload"
              type="file"
              accept="image/*"
              onChange={handlePhotoUpload}
              className="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-medium file:bg-pink-50 file:text-pink-700 hover:file:bg-pink-100"
            />
            <p className="text-xs text-gray-500 mt-1">
              Max. 1MB, alle Bildformate erlaubt
            </p>
          </div>

          {photoPreview && (
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">
                Vorschau
              </label>
              <div className="relative inline-block">
                <img
                  src={photoPreview}
                  alt="Foto Vorschau"
                  className="w-32 h-32 object-cover rounded-lg border border-gray-200"
                />
                <button
                  type="button"
                  onClick={removePhoto}
                  className="absolute -top-2 -right-2 bg-red-500 text-white rounded-full w-6 h-6 flex items-center justify-center text-sm hover:bg-red-600"
                >
                  ×
                </button>
              </div>
            </div>
          )}

          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Titel (optional)
            </label>
            <input
              type="text"
              value={photoTitle}
              onChange={(e) => setPhotoTitle(e.target.value)}
              placeholder="z.B. French Manicure, Gel Nails..."
              className="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-pink-500"
            />
          </div>

          <button
            onClick={() => {
              setErrorMsg("");
              setSuccessMsg("");
              
              if (!photoBase64) {
                setErrorMsg("Bitte wähle zuerst ein Foto aus.");
                return;
              }

              const sessionId = localStorage.getItem("sessionId") || "";
              if (!sessionId) {
                setErrorMsg("Nicht eingeloggt. Bitte als Inhaber anmelden.");
                return;
              }

              uploadPhoto(
                { 
                  sessionId, 
                  base64Data: photoBase64, 
                  title: photoTitle || undefined 
                },
                {
                  onSuccess: () => {
                    setSuccessMsg("Foto erfolgreich hochgeladen.");
                    setPhotoTitle("");
                    setPhotoPreview("");
                    setPhotoBase64("");
                    // Reset file input
                    const fileInput = document.getElementById('gallery-photo-upload') as HTMLInputElement;
                    if (fileInput) fileInput.value = '';
                    // Sofortige Aktualisierung der Liste
                    refetchPhotos();
                  },
                  onError: (err: any) => {
                    setErrorMsg(err?.message || "Fehler beim Hochladen des Fotos.");
                  }
                }
              );
            }}
            disabled={isUploading}
            className={`bg-pink-600 text-white px-4 py-2 rounded-md font-medium transition-colors ${isUploading ? 'opacity-60 cursor-not-allowed' : 'hover:bg-pink-700'}`}
          >
            {isUploading ? 'Lädt hoch…' : 'Foto hochladen'}
          </button>
        </div>
      </div>

      {/* Photo Grid Section */}
      <div className="bg-white rounded-lg shadow">
        <div className="p-4 border-b">
          <h3 className="text-lg font-semibold">Foto-Galerie verwalten</h3>
          <p className="text-sm text-gray-600 mt-1">
            Ziehe Fotos per Drag & Drop, um die Reihenfolge zu ändern. Klicke auf das X, um ein Foto zu löschen.
          </p>
        </div>
        
        <div className="p-6">
          {photos?.length === 0 && (
            <div className="text-center text-gray-500 py-8">
              <div className="text-lg font-medium mb-2">Noch keine Fotos hochgeladen</div>
              <div className="text-sm">Lade dein erstes Foto hoch, um deine Galerie zu starten.</div>
            </div>
          )}
          
          {sortedPhotos && sortedPhotos.length > 0 && (
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
              {sortedPhotos.map((photo) => (
                <div
                  key={photo.id}
                  draggable={true}
                  onDragStart={(e) => handleDragStart(e, photo.id)}
                  onDragOver={handleDragOver}
                  onDrop={(e) => handleDrop(e, photo.id)}
                  onDragEnd={handleDragEnd}
                  className={`relative bg-gray-50 rounded-lg overflow-hidden border-2 transition-all duration-200 hover:shadow-md cursor-move ${
                    draggedPhotoId === photo.id ? 'opacity-50 border-pink-300' : 'border-transparent'
                  }`}
                >
                  <img
                    src={photo.base64Data}
                    alt={photo.title || "Galerie Foto"}
                    className="w-full h-48 object-cover"
                  />
                  <div className="p-3">
                    <div className="flex items-center justify-between">
                      <div className="flex-1">
                        {photo.title && (
                          <div className="font-medium text-gray-900 text-sm mb-1">
                            {photo.title}
                          </div>
                        )}
                        <div className="text-xs text-gray-500">
                          Reihenfolge: {photo.order}
                        </div>
                        <div className="text-xs text-gray-400">
                          {new Date(photo.createdAt).toLocaleDateString('de-DE')}
                        </div>
                      </div>
                      <button
                        onClick={() => {
                          if (confirm("Möchtest du dieses Foto wirklich löschen?")) {
                            const sessionId = localStorage.getItem("sessionId");
                            if (!sessionId) {
                              setErrorMsg("Nicht eingeloggt. Bitte als Inhaber anmelden.");
                              return;
                            }
                            deletePhoto(
                              { sessionId, id: photo.id },
                              {
                                onSuccess: () => {
                                  setSuccessMsg("Foto gelöscht.");
                                  // Sofortige Aktualisierung der Liste
                                  refetchPhotos();
                                },
                                onError: (err: any) => {
                                  setErrorMsg(err?.message || "Fehler beim Löschen des Fotos.");
                                }
                              }
                            );
                          }
                        }}
                        className="ml-2 text-red-600 hover:text-red-800 hover:bg-red-50 rounded-full p-1 transition-colors"
                        title="Foto löschen"
                      >
                        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                        </svg>
                      </button>
                      <button
                        onClick={() => {
                          const sessionId = localStorage.getItem("sessionId");
                          if (!sessionId) {
                            setErrorMsg("Nicht eingeloggt. Bitte als Inhaber anmelden.");
                            return;
                          }
                          setCoverPhoto(
                            { sessionId, id: photo.id },
                            {
                              onSuccess: () => setSuccessMsg("Als Cover-Bild gesetzt."),
                              onError: (err: any) => setErrorMsg(err?.message || "Fehler beim Setzen des Cover-Bildes."),
                            }
                          );
                        }}
                        className={`ml-2 ${photo.cover ? 'text-green-700 hover:text-green-800 hover:bg-green-50' : 'text-gray-600 hover:text-gray-800 hover:bg-gray-50'} rounded-full p-1 transition-colors`}
                        title={photo.cover ? "Cover-Bild (aktiv)" : "Als Cover-Bild setzen"}
                      >
                        {photo.cover ? (
                          <svg className="w-4 h-4" viewBox="0 0 20 20" fill="currentColor">
                            <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-7.25 7.25a1 1 0 01-1.414 0l-3-3a1 1 0 111.414-1.414L8.5 11.086l6.543-6.543a1 1 0 011.414 0z" clipRule="evenodd" />
                          </svg>
                        ) : (
                          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l6-6 4 4 6-6" />
                          </svg>
                        )}
                      </button>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
