'use client';

import * as React from 'react';
import { Loader2, Trash2 } from 'lucide-react';
import { useAuth } from '@/components/id/auth-provider';
import { fetchDocumentPhotoUrl } from '@/lib/api';
import { resolveBrowserMediaUrl } from '@/lib/resilient-media-fetch';
import { cn } from '@/lib/utils';
import { DocumentFullscreenViewer, DocumentPhotoThumbnail } from './document-photo-viewer';

interface DocumentPhotoGalleryProps {
  userId: string;
  token: string | null;
  storageKeys: string[];
  readOnly?: boolean;
  onRemove?: (storageKey: string) => void;
  layout?: 'grid' | 'strip';
  className?: string;
}

export function DocumentPhotoGallery({
  userId,
  token,
  storageKeys,
  readOnly,
  onRemove,
  layout = 'grid',
  className
}: DocumentPhotoGalleryProps) {
  const { isPinLocked } = useAuth();
  const [urls, setUrls] = React.useState<Record<string, string>>({});
  const [loadingKeys, setLoadingKeys] = React.useState<Set<string>>(new Set());
  const [viewerOpen, setViewerOpen] = React.useState(false);
  const [viewerIndex, setViewerIndex] = React.useState(0);

  React.useEffect(() => {
    if (!token || storageKeys.length === 0 || isPinLocked) {
      setUrls({});
      return;
    }

    let cancelled = false;
    setLoadingKeys(new Set(storageKeys));
    void Promise.all(
      storageKeys.map(async (storageKey) => {
        try {
          const response = await fetchDocumentPhotoUrl(userId, storageKey, token);
          return { storageKey, accessUrl: resolveBrowserMediaUrl(response.accessUrl) };
        } catch {
          return { storageKey, accessUrl: '' };
        }
      })
    ).then((results) => {
      if (cancelled) return;
      const next: Record<string, string> = {};
      for (const item of results) {
        if (item.accessUrl) next[item.storageKey] = item.accessUrl;
      }
      setUrls(next);
      setLoadingKeys(new Set());
    });

    return () => {
      cancelled = true;
    };
  }, [isPinLocked, storageKeys.join('|'), token, userId]);

  const resolvedImages = storageKeys
    .map((storageKey) => ({ storageKey, url: urls[storageKey] }))
    .filter((item) => Boolean(item.url));

  function openViewer(storageKey: string) {
    const resolvedIndex = resolvedImages.findIndex((item) => item.storageKey === storageKey);
    if (resolvedIndex >= 0) {
      setViewerIndex(resolvedIndex);
      setViewerOpen(true);
    }
  }

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

  const isStrip = layout === 'strip';

  return (
    <>
      <div
        className={cn(
          isStrip ? 'flex gap-2 overflow-x-auto pb-1' : 'grid grid-cols-2 gap-3',
          className
        )}
        onClick={(event) => event.stopPropagation()}
      >
        {storageKeys.map((storageKey) => (
          <div key={storageKey} className={cn('relative', isStrip && 'w-20 shrink-0')}>
            <DocumentPhotoThumbnail
              url={urls[storageKey]}
              loading={loadingKeys.has(storageKey)}
              className={isStrip ? 'aspect-square rounded-xl' : undefined}
              onClick={() => openViewer(storageKey)}
            />
            {!readOnly && onRemove ? (
              <button
                type="button"
                onClick={(event) => {
                  event.stopPropagation();
                  onRemove(storageKey);
                }}
                className="absolute right-2 top-2 rounded-full bg-black/60 p-1.5 text-white hover:bg-black/80"
                aria-label="Удалить фото"
              >
                <Trash2 className="h-3.5 w-3.5" />
              </button>
            ) : null}
            {loadingKeys.has(storageKey) ? (
              <div className="pointer-events-none absolute inset-0 flex items-center justify-center rounded-2xl bg-white/40">
                <Loader2 className="h-5 w-5 animate-spin text-[#667085]" />
              </div>
            ) : null}
          </div>
        ))}
      </div>

      <DocumentFullscreenViewer
        open={viewerOpen}
        onOpenChange={setViewerOpen}
        initialIndex={viewerIndex}
        images={resolvedImages}
      />
    </>
  );
}

interface DocumentPhotosInlineProps {
  userId: string;
  token: string | null;
  storageKeys: string[];
  className?: string;
}

/** Горизонтальная полоска фото документа для списков (страница «Документы», «Данные»). */
export function DocumentPhotosInline({ userId, token, storageKeys, className }: DocumentPhotosInlineProps) {
  if (!storageKeys.length) return null;
  return (
    <DocumentPhotoGallery
      userId={userId}
      token={token}
      storageKeys={storageKeys}
      readOnly
      layout="strip"
      className={className}
    />
  );
}
