// gallery-app.jsx

function ImageCard({ image, onDelete, ratingInfo, refreshRatings, onOpenPreview }) {
  const user = window.USER || {};
  const canDelete = user.isAdmin || user.id === image.uploader_id;
  const [loaded, setLoaded] = React.useState(false);

  return (
    <div className="bg-gray-800 rounded-xl shadow hover:shadow-lg transition relative overflow-visible">
      {/* 📷 Image */}
      <img
        src={image.src}
        alt={image.title}
        loading="lazy"
        onLoad={() => setLoaded(true)}
        onClick={() => onOpenPreview?.()} // ✅ only open preview when image is clicked
        className={`cursor-pointer w-full h-48 lg:h-64 object-cover transition-opacity duration-700 ${
          loaded ? 'opacity-100' : 'opacity-0'
        }`}
      />

      {/* 📄 Card Content */}
      <div className="p-3 space-y-2">
        {/* Title + Delete */}
        <div className="flex justify-between items-center">
          <h2 className="text-base font-semibold text-white">{image.title}</h2>
          {canDelete && (
            <button
              onClick={(e) => {
                e.stopPropagation();
                onDelete(image);
              }}
              className="text-red-500 hover:text-red-400 text-sm"
              title="Delete image"
            >
              🗑
            </button>
          )}
        </div>

        {/* Description */}
        <p className="text-sm text-gray-400 leading-tight">{image.description}</p>

        {/* Bottom Row: uploader + mic + avg */}
        <div className="flex justify-between items-end mt-2 text-xs">
          {/* by: callsign - Bottom Left */}
          {image.uploader && (
            <div className="text-left text-gray-500">
              by:{' '}
              <a
                href={`/profile.php?user_id=${image.uploader_id}`}
                className="text-blue-400 hover:underline"
                onClick={(e) => e.stopPropagation()} // ✅ prevent preview opening
              >
                {image.uploader}
              </a>
            </div>
          )}

          {/* Mic + average - Bottom Right */}
          <div className="flex flex-col items-end">
            <MicRating
              key={`mic-${image.id}-${ratingInfo?.avg}`} // 👈 this forces re-render when avg changes
              initial={ratingInfo?.avg || 0}
              imageId={image.id}
              userCallsign={user.callsign}
              onRate={refreshRatings}
              displayOnly={!user.callsign}
            />

            {ratingInfo && (
              <div className="text-gray-400 mt-1">
                ⭐ {ratingInfo.avg} average from {ratingInfo.votes} votes
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function UploadForm() {
  const fileInputRef = React.useRef(null);
  const formRef = React.useRef(null);
  const [uploading, setUploading] = React.useState(false);
  const [fileSelected, setFileSelected] = React.useState(false);

  const handleFileChange = () => {
    setFileSelected(true);
  };

  const handleUploadClick = () => {
    if (!fileSelected) {
      fileInputRef.current.click();
      return;
    }

    const form = formRef.current;
    const title = form.title.value.trim();
    const description = form.description.value.trim();

    if (!title || !description) {
      Swal.fire({
        icon: 'warning',
        title: 'Missing fields',
        text: 'Please fill in both the title and description.',
        toast: true,
        position: 'top-end',
        timer: 3000,
        showConfirmButton: false,
      });
      return;
    }

    setUploading(true);
    form.submit();
  };

  return (
    <form
      ref={formRef}
      className="space-y-4"
      method="POST"
      action="/gallery/upload.php"
      encType="multipart/form-data"
    >
      <input
        type="file"
        name="image"
        ref={fileInputRef}
        onChange={handleFileChange}
        className="hidden"
        required
      />

      <input
        type="text"
        name="title"
        placeholder="Image Title"
        className="w-full text-white px-4 py-2 rounded"
        style={{
          backgroundColor: '#0e0e0e',
          borderWidth: '1px',
          borderStyle: 'solid',
          borderColor: '#0d6efd24',
        }}
        required
      />

      <textarea
        name="description"
        placeholder="Description"
        className="w-full text-white px-4 py-2 rounded"
        style={{
          backgroundColor: '#0e0e0e',
          borderWidth: '1px',
          borderStyle: 'solid',
          borderColor: 'rgb(30, 36, 45)',
        }}
        rows="2"
        required
      ></textarea>

      <button
        type="button"
        onClick={handleUploadClick}
        disabled={uploading}
        className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 disabled:opacity-50 flex items-center gap-2"
      >
        {uploading && (
          <svg
            className="animate-spin h-5 w-5 text-white"
            fill="none"
            viewBox="0 0 24 24"
          >
            <circle
              className="opacity-25"
              cx="12"
              cy="12"
              r="10"
              stroke="currentColor"
              strokeWidth="4"
            ></circle>
            <path
              className="opacity-75"
              fill="currentColor"
              d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"
            ></path>
          </svg>
        )}
        {fileSelected ? 'Upload Image' : 'Choose Image'}
      </button>
    </form>
  );
}

function GalleryApp() {
  const [images, setImages] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [currentPage, setCurrentPage] = React.useState(1);
  const [selectedImageIndex, setSelectedImageIndex] = React.useState(null);
  const imagesPerPage = 8;
  const [ratingsMap, setRatingsMap] = React.useState({});

  // Refresh ratings after vote
  const refreshRatings = () => {
    fetch('/gallery/get-image-ratings.php')
      .then((res) => res.json())
      .then((json) => {
        if (json.success && json.data) {
          setRatingsMap(json.data);
        }
      });
  };

  // Load images once
  React.useEffect(() => {
    fetch('/gallery/gallery-data.php')
      .then((res) => res.json())
      .then((data) => {
        setImages(data);
        setLoading(false);
      });
  }, []);

  // Load ratings once on mount
  React.useEffect(() => {
    refreshRatings();
  }, []);

  const handleDelete = (image) => {
    Swal.fire({
      title: 'Delete this image?',
      text: `"${image.title}" will be permanently removed.`,
      icon: 'warning',
      showCancelButton: true,
      confirmButtonText: 'Yes, delete it!',
      cancelButtonText: 'Cancel',
      confirmButtonColor: '#e3342f',
    }).then((result) => {
      if (result.isConfirmed) {
        fetch('/gallery/delete.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ id: image.id }),
        })
          .then((res) => res.json())
          .then((res) => {
            if (res.success) {
              setImages((prev) => prev.filter((img) => img.id !== image.id));
              Swal.fire({
                toast: true,
                position: 'top-end',
                icon: 'success',
                title: 'Image deleted',
                showConfirmButton: false,
                timer: 2000,
              });
            } else {
              Swal.fire('Error', res.message || 'Could not delete image.', 'error');
            }
          });
      }
    });
  };

  const totalPages = Math.ceil(images.length / imagesPerPage);
  const startIndex = (currentPage - 1) * imagesPerPage;
  const paginatedImages = images.slice(startIndex, startIndex + imagesPerPage);

  return (
    <div className="space-y-12">
      {/* Gallery Section */}
      <div
        className="rounded-xl p-6 shadow-md"
        style={{ backgroundColor: '#04203591', border: '1px solid rgb(65 82 107)' }}
      >
        {loading ? (
          <p className="text-gray-500">Loading images...</p>
        ) : (
          <>
            <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-7 mb-6">
              {paginatedImages.map((img, i) => (
                <div key={img.id}>
                  <ImageCard
                    image={img}
                    onDelete={handleDelete}
                    ratingInfo={ratingsMap[img.id]}
                    refreshRatings={refreshRatings}
                    onOpenPreview={() => setSelectedImageIndex(startIndex + i)}
                  />
                </div>
              ))}
            </div>

            {totalPages > 1 && (
              <div className="flex justify-center mt-6 space-x-2">
                {Array.from({ length: totalPages }, (_, i) => (
                  <button
                    key={i}
                    onClick={() => setCurrentPage(i + 1)}
                    className={`px-3 py-1 rounded ${
                      currentPage === i + 1
                        ? 'bg-blue-600 text-white'
                        : 'bg-gray-700 text-gray-300'
                    }`}
                  >
                    {i + 1}
                  </button>
                ))}
              </div>
            )}
          </>
        )}
      </div>

      <div
        className="rounded-xl p-6 shadow-md"
        style={{ backgroundColor: '#04203591', border: '1px solid rgb(65 82 107)' }}
      >
        <h2 className="text-xl font-semibold text-white mb-4">➕ Add New Image</h2>
        <UploadForm />
      </div>

      {selectedImageIndex !== null && (
        <FancyLightbox
          images={images}
          activeIndex={selectedImageIndex}
          onClose={() => setSelectedImageIndex(null)}
          ratingInfo={ratingsMap[images[selectedImageIndex].id] || { avg: 0, votes: 0 }}
          refreshRatings={refreshRatings}
        />
      )}
    </div>
  );
}

if (!window.__GALLERY_ROOT__) {
  window.__GALLERY_ROOT__ = ReactDOM.createRoot(
    document.getElementById('gallery-root')
  );
}
window.__GALLERY_ROOT__.render(<GalleryApp />);
