'use client';

/**
 * Chat image album — a Telegram/WhatsApp-style adaptive collage for 1–N
 * images. NOT a true masonry: messengers use a small set of deterministic
 * album layouts (no JS height measuring, no extra deps), which is the right
 * call for a chat where albums are a small, bounded case.
 *
 *   1 → single image            2 → two equal columns
 *   3 → one tall + two stacked  4 → 2×2 grid
 *   5+ → 2×2 grid, the last visible tile shows a "+N more" overlay
 *
 * Clicking any tile opens the shared zoom/pan `ImageViewer` lightbox in a
 * dialog, seeded at the clicked index, with prev/next across the whole set.
 */

import { useCallback, useState } from 'react';

import { Dialog, DialogContent, DialogTitle } from '@djangocfg/ui-core/components';
import { cn } from '@djangocfg/ui-core/lib';

import { LazyImageViewer } from '../../../../media/ImageViewer/lazy';

export interface ChatAlbumImage {
  id: string;
  src: string;
  thumbnail?: string;
  alt?: string;
}

export interface ChatImageAlbumProps {
  images: ChatAlbumImage[];
  /** Max tiles shown before collapsing the rest into a "+N" overlay. */
  maxVisible?: number;
}

/** Tile — a single clickable image cell. */
function Tile({
  image,
  onClick,
  className,
  overlayCount,
}: {
  image: ChatAlbumImage;
  onClick: () => void;
  className?: string;
  overlayCount?: number;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      aria-label={`Open image${image.alt ? `: ${image.alt}` : ''}`}
      className={cn(
        'group relative block overflow-hidden bg-muted',
        'cursor-zoom-in focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring',
        className,
      )}
    >
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img
        src={image.thumbnail ?? image.src}
        alt={image.alt ?? ''}
        loading="lazy"
        className="h-full w-full object-cover transition-transform duration-200 group-hover:scale-[1.02]"
      />
      {overlayCount ? (
        <span className="absolute inset-0 flex items-center justify-center bg-black/50 text-xl font-semibold text-white">
          +{overlayCount}
        </span>
      ) : null}
    </button>
  );
}

export function ChatImageAlbum({ images, maxVisible = 4 }: ChatImageAlbumProps) {
  const [open, setOpen] = useState(false);
  const [index, setIndex] = useState(0);

  const openAt = useCallback((i: number) => {
    setIndex(i);
    setOpen(true);
  }, []);

  const count = images.length;
  const visible = images.slice(0, Math.min(count, maxVisible));
  const hiddenCount = count - visible.length;

  // Layout per count. `gap-0.5` mimics the tight messenger seam; the outer
  // BLOCK_SURFACE provides the rounded clip + border.
  let grid: React.ReactNode;
  if (count === 1) {
    const img = images[0];
    grid = (
      <Tile image={img} onClick={() => openAt(0)} className="max-h-96 w-full" />
    );
  } else if (count === 2) {
    grid = (
      <div className="grid aspect-[2/1] grid-cols-2 gap-0.5">
        {visible.map((img, i) => (
          <Tile key={img.id} image={img} onClick={() => openAt(i)} />
        ))}
      </div>
    );
  } else if (count === 3) {
    grid = (
      <div className="grid aspect-[3/2] grid-cols-2 grid-rows-2 gap-0.5">
        <Tile image={visible[0]} onClick={() => openAt(0)} className="row-span-2" />
        <Tile image={visible[1]} onClick={() => openAt(1)} />
        <Tile image={visible[2]} onClick={() => openAt(2)} />
      </div>
    );
  } else {
    // 4+ → 2×2, last visible tile carries the "+N" overlay when collapsed.
    grid = (
      <div className="grid aspect-square grid-cols-2 grid-rows-2 gap-0.5">
        {visible.map((img, i) => {
          const isLast = i === visible.length - 1;
          return (
            <Tile
              key={img.id}
              image={img}
              onClick={() => openAt(i)}
              overlayCount={isLast && hiddenCount > 0 ? hiddenCount : undefined}
            />
          );
        })}
      </div>
    );
  }

  return (
    <>
      {grid}

      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="h-[90vh] w-[90vw] max-w-[1400px] overflow-hidden p-0 sm:rounded-xl">
          <DialogTitle className="sr-only">Image {index + 1} of {count}</DialogTitle>
          {open && (
            <LazyImageViewer
              images={images.map((img) => ({
                file: { name: img.alt ?? 'image', path: img.src },
                src: img.src,
              }))}
              initialIndex={index}
              inDialog
              autoFocus
            />
          )}
        </DialogContent>
      </Dialog>
    </>
  );
}
