'use client';

import { useState } from 'react';
import { ChevronLeftIcon, ImagesIcon, XIcon } from 'lucide-react';
import { AnimatePresence, motion } from 'motion/react';
import { type GeneratedImage, useGeneratedImages } from '@/hooks/useGeneratedImages';
import { cn } from '@/lib/shadcn/utils';

const MotionPanel = motion.create('div');
const MotionOverlay = motion.create('div');

interface ThumbnailProps {
  image: GeneratedImage;
  onClick: () => void;
}

function Thumbnail({ image, onClick }: ThumbnailProps) {
  return (
    <button
      onClick={onClick}
      className="group border-input/50 bg-muted hover:border-foreground/20 focus-visible:ring-ring relative aspect-square overflow-hidden rounded-lg border transition-all hover:shadow-md focus-visible:ring-2 focus-visible:outline-none"
    >
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img
        src={image.imageUrl}
        alt={image.prompt}
        className="h-full w-full object-cover transition-transform duration-200 group-hover:scale-105"
      />
    </button>
  );
}

interface FullImageViewProps {
  image: GeneratedImage;
  onBack: () => void;
}

function FullImageView({ image, onBack }: FullImageViewProps) {
  return (
    <MotionPanel
      key="full"
      initial={{ opacity: 0, x: 24 }}
      animate={{ opacity: 1, x: 0 }}
      exit={{ opacity: 0, x: 24 }}
      transition={{ duration: 0.2, ease: 'easeOut' }}
      className="flex h-full flex-col"
    >
      <button
        onClick={onBack}
        className="text-muted-foreground hover:text-foreground mb-3 flex items-center gap-1 text-sm transition-colors"
      >
        <ChevronLeftIcon className="size-4" />
        All images
      </button>
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img src={image.imageUrl} alt={image.prompt} className="w-full rounded-xl object-contain" />
      {image.prompt && <p className="text-muted-foreground mt-3 text-sm">{image.prompt}</p>}
    </MotionPanel>
  );
}

/**
 * Floating gallery button + slide-in panel for all agent-generated images.
 * The button appears once at least one image has been generated.
 */
export function ImageGallery() {
  const images = useGeneratedImages();
  const [open, setOpen] = useState(false);
  const [selected, setSelected] = useState<GeneratedImage | null>(null);

  if (images.length === 0) return null;

  return (
    <>
      {/* Floating trigger button */}
      <AnimatePresence>
        {!open && (
          <MotionPanel
            key="trigger"
            initial={{ opacity: 0, scale: 0.85 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.85 }}
            transition={{ duration: 0.2, ease: 'easeOut' }}
            className="fixed right-4 bottom-36 z-40 md:bottom-44"
          >
            <button
              onClick={() => setOpen(true)}
              aria-label="View generated images"
              className={cn(
                'relative flex items-center justify-center rounded-full p-3',
                'bg-background border-input/50 border shadow-lg',
                'hover:bg-accent focus-visible:ring-ring transition-colors focus-visible:ring-2 focus-visible:outline-none'
              )}
            >
              <ImagesIcon className="text-foreground size-5" />
              <span className="bg-primary text-primary-foreground absolute -top-1.5 -right-1.5 flex h-5 min-w-5 items-center justify-center rounded-full px-1 text-[10px] font-bold">
                {images.length}
              </span>
            </button>
          </MotionPanel>
        )}
      </AnimatePresence>

      {/* Gallery panel + backdrop */}
      <AnimatePresence>
        {open && (
          <>
            <MotionOverlay
              key="overlay"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              transition={{ duration: 0.2 }}
              className="fixed inset-0 z-40 bg-black/40 backdrop-blur-sm"
              onClick={() => {
                setSelected(null);
                setOpen(false);
              }}
            />

            <MotionPanel
              key="panel"
              initial={{ x: '100%' }}
              animate={{ x: 0 }}
              exit={{ x: '100%' }}
              transition={{ duration: 0.25, ease: 'easeOut' }}
              className="border-input/50 bg-background fixed top-0 right-0 bottom-0 z-[60] flex w-80 flex-col overflow-hidden border-l shadow-2xl md:top-16"
            >
              {/* Header */}
              <div className="border-input/50 flex items-center justify-between border-b px-4 py-3">
                <div>
                  <h2 className="text-sm font-semibold">Generated images</h2>
                  <p className="text-muted-foreground text-xs">
                    {images.length} {images.length === 1 ? 'image' : 'images'}
                  </p>
                </div>
                <button
                  onClick={() => {
                    setSelected(null);
                    setOpen(false);
                  }}
                  aria-label="Close gallery"
                  className="hover:bg-accent focus-visible:ring-ring rounded-full p-1.5 transition-colors focus-visible:ring-2 focus-visible:outline-none"
                >
                  <XIcon className="text-muted-foreground size-4" />
                </button>
              </div>

              {/* Content */}
              <div className="flex-1 overflow-y-auto p-4">
                <AnimatePresence mode="wait">
                  {selected ? (
                    <FullImageView
                      key={selected.id}
                      image={selected}
                      onBack={() => setSelected(null)}
                    />
                  ) : (
                    <MotionPanel
                      key="grid"
                      initial={{ opacity: 0 }}
                      animate={{ opacity: 1 }}
                      exit={{ opacity: 0 }}
                      transition={{ duration: 0.15 }}
                      className="grid grid-cols-2 gap-2"
                    >
                      {[...images].reverse().map((img) => (
                        <Thumbnail key={img.id} image={img} onClick={() => setSelected(img)} />
                      ))}
                    </MotionPanel>
                  )}
                </AnimatePresence>
              </div>
            </MotionPanel>
          </>
        )}
      </AnimatePresence>
    </>
  );
}
