'use client';

import { useEffect, useMemo } from 'react';
import { useQueries } from '@tanstack/react-query';
import LightGallery from 'lightgallery/react';
import lgThumbnail from 'lightgallery/plugins/thumbnail';
import lgZoom from 'lightgallery/plugins/zoom';

import { Skeleton } from '@/components/ui/skeleton';
import { protectedMediaService } from '@/services/api';

interface RepairProofGalleryProps {
  imageUrls: string[];
  maxVisibleImages?: number;
}

const MAX_VISIBLE_IMAGES = 8;

export function RepairProofGallery({
  imageUrls,
  maxVisibleImages = MAX_VISIBLE_IMAGES,
}: RepairProofGalleryProps) {
  const queries = useQueries({
    queries: imageUrls.map((url) => ({
      queryKey: ['protected-media', 'v2', url],
      queryFn: () => protectedMediaService.getBlob(url),
      staleTime: Infinity,
      gcTime: 1000 * 60 * 30,
    })),
  });

  const blobs = queries.map((query) => query.data);
  const objectUrls = useMemo(
    () => blobs.map((blob) => (blob ? URL.createObjectURL(blob) : null)),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [...blobs],
  );

  useEffect(
    () => () => {
      objectUrls.forEach((url) => {
        if (url) URL.revokeObjectURL(url);
      });
    },
    [objectUrls],
  );

  if (queries.some((query) => query.isLoading)) {
    return (
      <div className="grid grid-cols-4 gap-1 overflow-hidden rounded-lg">
        {imageUrls.slice(0, maxVisibleImages).map((url, index) => (
          <Skeleton
            key={`${url}-${index}`}
            className="aspect-square rounded-lg"
          />
        ))}
      </div>
    );
  }

  const images = objectUrls.flatMap((url, index) =>
    url ? [{ url, originalIndex: index }] : [],
  );
  const visibleCount = Math.min(maxVisibleImages, images.length);
  const overflowCount = images.length - visibleCount;

  if (images.length === 0) {
    return (
      <div className="rounded-lg border border-dashed py-8 text-center text-sm text-muted-foreground">
        Repair images are unavailable.
      </div>
    );
  }

  return (
    <LightGallery
      elementClassNames="grid grid-cols-4 gap-1 overflow-hidden rounded-lg"
      mode="lg-fade"
      speed={400}
      plugins={[lgThumbnail, lgZoom]}
      thumbnail
      download={false}
      mobileSettings={{ controls: true, showCloseIcon: true, download: false }}
    >
      {images.map(({ url, originalIndex }, index) => {
        const isVisible = index < visibleCount;
        const isOverflowTile = overflowCount > 0 && index === visibleCount - 1;

        return (
          <a
            key={imageUrls[originalIndex]}
            data-src={url}
            data-sub-html={`<p>Repair evidence ${originalIndex + 1}</p>`}
            className={isVisible ? 'group relative aspect-square' : 'hidden'}
            aria-label={
              isOverflowTile
                ? `View all ${images.length} repair images`
                : `View repair image ${originalIndex + 1} of ${images.length}`
            }
          >
            {/* Blob URLs cannot be handled by next/image. */}
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img
              src={url}
              alt={`Repair evidence ${originalIndex + 1}`}
              className="size-full object-cover transition duration-300 group-hover:scale-[1.03] group-hover:brightness-90"
            />
            {isOverflowTile ? (
              <span className="absolute inset-0 flex items-center justify-center bg-black/55 px-2 text-center text-sm font-semibold text-white transition-colors group-hover:bg-black/65 sm:text-base">
                +{overflowCount} more
              </span>
            ) : null}
          </a>
        );
      })}
    </LightGallery>
  );
}
