// @ts-nocheck
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useParams } from 'react-router-dom';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogFooter } from '@/components/ui/dialog';
import { fetchGalleryMeta, fetchGalleryPhotos, type GalleryMetaResponse, type GalleryPhotoResource } from '../services/galleryApi';
import { useTranslation } from '../i18n/useTranslation';
import { DEFAULT_LOCALE, isLocaleCode } from '../i18n/messages';
import { AlertTriangle, Download, Loader2, Share, X } from 'lucide-react';
import { createPhotoShareLink } from '../services/photosApi';
import { getContrastingTextColor } from '../lib/color';
import { applyGuestTheme } from '../lib/guestTheme';

interface GalleryState {
  meta: GalleryMetaResponse | null;
  photos: GalleryPhotoResource[];
  cursor: string | null;
  loading: boolean;
  loadingMore: boolean;
  error: string | null;
  expired: boolean;
}

const INITIAL_STATE: GalleryState = {
  meta: null,
  photos: [],
  cursor: null,
  loading: true,
  loadingMore: false,
  error: null,
  expired: false,
};

const GALLERY_PAGE_SIZE = 30;

export default function PublicGalleryPage(): React.ReactElement | null {
  const { token } = useParams<{ token: string }>();
  const { t } = useTranslation();
  const [state, setState] = useState<GalleryState>(INITIAL_STATE);
  const [lightboxOpen, setLightboxOpen] = useState(false);
  const [selectedPhoto, setSelectedPhoto] = useState<GalleryPhotoResource | null>(null);
  const [shareLoading, setShareLoading] = useState(false);
  const sentinelRef = useRef<HTMLDivElement | null>(null);

  const localeStorageKey = token ? `guestGalleryLocale_${token}` : 'guestGalleryLocale';
  const storedLocale = typeof window !== 'undefined' && token ? localStorage.getItem(localeStorageKey) : null;
  const effectiveLocale: LocaleCode = storedLocale && isLocaleCode(storedLocale) ? storedLocale : DEFAULT_LOCALE;

  const applyMeta = useCallback((meta: GalleryMetaResponse) => {
    if (typeof window !== 'undefined' && token) {
      localStorage.setItem(localeStorageKey, effectiveLocale);
    }
    setState((prev) => ({
      ...prev,
      meta,
    }));
  }, [effectiveLocale, localeStorageKey, token]);

  const loadInitial = useCallback(async () => {
    if (!token) {
      return;
    }

    setState((prev) => ({ ...prev, loading: true, error: null, expired: false, photos: [], cursor: null }));

    try {
      const meta = await fetchGalleryMeta(token, effectiveLocale);
      applyMeta(meta);

      const photoResponse = await fetchGalleryPhotos(token, null, GALLERY_PAGE_SIZE);

      setState((prev) => ({
        ...prev,
        loading: false,
        photos: photoResponse.data,
        cursor: photoResponse.next_cursor,
      }));
    } catch (error) {
      const err = error as Error & { code?: string | number };
      if (err.code === 'gallery_expired' || err.code === 410) {
        setState((prev) => ({ ...prev, loading: false, expired: true }));
      } else {
        setState((prev) => ({
          ...prev,
          loading: false,
          error: err.message || t('galleryPublic.loadError'),
        }));
      }
    }
  }, [token, applyMeta, effectiveLocale, t]);

  useEffect(() => {
    loadInitial();
  }, [loadInitial]);

  const resolvedBranding = useMemo(() => {
    if (!state.meta) {
      return null;
    }

    const palette = state.meta.branding.palette ?? {};
    const primary = palette.primary ?? state.meta.branding.primary_color ?? '#FF5A5F';
    const secondary = palette.secondary ?? state.meta.branding.secondary_color ?? '#FFF8F5';
    const background = palette.background ?? state.meta.branding.background_color ?? '#ffffff';
    const surface = palette.surface ?? state.meta.branding.surface_color ?? background;
    const mode = state.meta.branding.mode ?? 'auto';

    return {
      primary,
      secondary,
      background,
      surface,
      mode,
    };
  }, [state.meta]);

  useEffect(() => {
    if (!resolvedBranding) {
      return;
    }

    return applyGuestTheme(resolvedBranding);
  }, [resolvedBranding]);

  const loadMore = useCallback(async () => {
    if (!token || !state.cursor || state.loadingMore) {
      return;
    }

    setState((prev) => ({ ...prev, loadingMore: true }));

    try {
      const response = await fetchGalleryPhotos(token, state.cursor, GALLERY_PAGE_SIZE);
      setState((prev) => ({
        ...prev,
        photos: [...prev.photos, ...response.data],
        cursor: response.next_cursor,
        loadingMore: false,
      }));
    } catch (error) {
      const err = error as Error;
      setState((prev) => ({
        ...prev,
        loadingMore: false,
        error: err.message || t('galleryPublic.loadError'),
      }));
    }
  }, [state.cursor, state.loadingMore, token, t]);

  useEffect(() => {
    if (!state.cursor || !sentinelRef.current) {
      return;
    }

    const observer = new IntersectionObserver((entries) => {
      const firstEntry = entries[0];
      if (firstEntry?.isIntersecting) {
        loadMore();
      }
    }, {
      rootMargin: '400px',
      threshold: 0,
    });

    observer.observe(sentinelRef.current);

    return () => observer.disconnect();
  }, [state.cursor, loadMore]);

  const themeStyles = useMemo(() => {
    if (!resolvedBranding) {
      return {} as React.CSSProperties;
    }

    return {
      '--gallery-primary': resolvedBranding.primary,
      '--gallery-secondary': resolvedBranding.secondary,
      '--gallery-background': resolvedBranding.background,
      '--gallery-surface': resolvedBranding.surface,
    } as React.CSSProperties & Record<string, string>;
  }, [resolvedBranding]);

  const headerStyle = useMemo(() => {
    if (!resolvedBranding) {
      return {};
    }
    const textColor = getContrastingTextColor(resolvedBranding.primary, '#0f172a', '#ffffff');
    return {
      background: `linear-gradient(135deg, ${resolvedBranding.primary}, ${resolvedBranding.secondary})`,
      color: textColor,
    } satisfies React.CSSProperties;
  }, [resolvedBranding]);

  const accentStyle = useMemo(() => {
    if (!resolvedBranding) {
      return {};
    }
    return {
      color: resolvedBranding.primary,
    } satisfies React.CSSProperties;
  }, [resolvedBranding]);

  const backgroundStyle = useMemo(() => {
    if (!resolvedBranding) {
      return {};
    }
    return {
      backgroundColor: resolvedBranding.background,
    } satisfies React.CSSProperties;
  }, [resolvedBranding]);

  const openLightbox = useCallback((photo: GalleryPhotoResource) => {
    setSelectedPhoto(photo);
    setLightboxOpen(true);
  }, []);

  const closeLightbox = useCallback(() => {
    setLightboxOpen(false);
    setSelectedPhoto(null);
  }, []);

  if (!token) {
    return null;
  }

  if (state.expired) {
    return (
      <div className="flex min-h-screen flex-col items-center justify-center gap-6 px-6 text-center" style={backgroundStyle}>
        <AlertTriangle className="h-12 w-12 text-destructive" aria-hidden />
        <div className="space-y-2">
          <h1 className="text-2xl font-semibold text-foreground">{t('galleryPublic.expiredTitle')}</h1>
          <p className="text-sm text-muted-foreground">{t('galleryPublic.expiredDescription')}</p>
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-screen" style={{ ...themeStyles, ...backgroundStyle }}>
      <header className="sticky top-0 z-20 shadow-sm" style={headerStyle}>
        <div className="mx-auto flex w-full max-w-5xl items-center justify-between px-5 py-4">
          <div className="text-left">
            <p className="text-xs uppercase tracking-widest opacity-80">Fotospiel</p>
            <h1 className="text-xl font-semibold leading-tight">
              {state.meta?.event.name || t('galleryPublic.title')}
            </h1>
            {state.meta?.event.gallery_expires_at && (
              <p className="text-[11px] opacity-80">
                {new Date(state.meta.event.gallery_expires_at).toLocaleDateString()}
              </p>
            )}
          </div>
        </div>
      </header>

      <main className="mx-auto flex w-full max-w-5xl flex-col gap-6 px-5 py-6">
        {state.meta?.event.description && (
          <div className="rounded-xl bg-white/70 p-4 shadow-sm backdrop-blur">
            <p className="text-sm text-muted-foreground">{state.meta.event.description}</p>
          </div>
        )}

        {state.error && (
          <Alert variant="destructive">
            <AlertTitle>{t('galleryPublic.loadError')}</AlertTitle>
            <AlertDescription>
              {state.error}
            </AlertDescription>
          </Alert>
        )}

        {state.loading && (
          <div className="flex flex-col items-center justify-center gap-3 py-16 text-center">
            <Loader2 className="h-10 w-10 animate-spin" aria-hidden />
            <p className="text-sm text-muted-foreground">{t('galleryPublic.loading')}</p>
          </div>
        )}

        {!state.loading && state.photos.length === 0 && !state.error && (
          <div className="rounded-xl border border-dashed border-muted/60 p-10 text-center">
            <h2 className="text-lg font-semibold text-foreground">{t('galleryPublic.emptyTitle')}</h2>
            <p className="mt-2 text-sm text-muted-foreground">{t('galleryPublic.emptyDescription')}</p>
          </div>
        )}

        <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4">
          {state.photos.map((photo) => (
            <button
              key={photo.id}
              type="button"
              className="group relative overflow-hidden rounded-xl bg-white shadow-sm transition-transform hover:-translate-y-1 hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-offset-2"
              onClick={() => openLightbox(photo)}
              style={accentStyle}
            >
              <img
                src={photo.thumbnail_url ?? photo.full_url ?? ''}
                alt={photo.guest_name ? `${photo.guest_name}s Foto` : `Foto ${photo.id}`}
                loading="lazy"
                className="h-full w-full object-cover"
              />
            </button>
          ))}
        </div>

        <div ref={sentinelRef} className="h-1 w-full" aria-hidden />

        {state.loadingMore && (
          <div className="flex items-center justify-center gap-2 text-sm text-muted-foreground">
            <Loader2 className="h-4 w-4 animate-spin" aria-hidden />
            {t('galleryPublic.loadingMore')}
          </div>
        )}

        {!state.loading && state.cursor && (
          <div className="flex justify-center">
            <Button variant="outline" onClick={loadMore} disabled={state.loadingMore}>
              {state.loadingMore ? <Loader2 className="mr-2 h-4 w-4 animate-spin" aria-hidden /> : null}
              {t('galleryPublic.loadMore')}
            </Button>
          </div>
        )}
      </main>

      <Dialog open={lightboxOpen} onOpenChange={(open) => (open ? setLightboxOpen(true) : closeLightbox())}>
        <DialogContent className="max-w-3xl gap-6">
          <div className="flex items-center justify-between">
            <div>
              <p className="text-sm font-medium text-muted-foreground">
                {selectedPhoto?.guest_name || t('galleryPublic.lightboxGuestFallback')}
              </p>
              <p className="text-xs text-muted-foreground">
                {selectedPhoto?.created_at ? new Date(selectedPhoto.created_at).toLocaleString() : ''}
              </p>
            </div>
            <Button variant="ghost" size="icon" onClick={closeLightbox}>
              <X className="h-4 w-4" aria-hidden />
              <span className="sr-only">{t('common.actions.close')}</span>
            </Button>
          </div>

          <div className="relative overflow-hidden rounded-2xl bg-black/5">
            {selectedPhoto?.full_url && (
              <img
                src={selectedPhoto.full_url}
                alt={selectedPhoto?.guest_name || `Foto ${selectedPhoto?.id}`}
                className="w-full object-contain"
              />
            )}
          </div>

          <DialogFooter className="flex flex-col items-start gap-3 sm:flex-row sm:items-center sm:justify-between">
            <div className="text-xs text-muted-foreground">
              {selectedPhoto?.likes_count ? `${selectedPhoto.likes_count} ❤` : ''}
            </div>
            <div className="flex flex-wrap gap-2">
              {(state.meta?.event?.guest_downloads_enabled ?? true) && selectedPhoto?.download_url ? (
                <Button asChild className="gap-2" style={accentStyle}>
                  <a href={selectedPhoto.download_url} target="_blank" rel="noopener noreferrer">
                    <Download className="h-4 w-4" aria-hidden />
                    {t('galleryPublic.download')}
                  </a>
                </Button>
              ) : null}
              {(state.meta?.event?.guest_sharing_enabled ?? true) && selectedPhoto ? (
                <Button
                  variant="outline"
                  className="gap-2"
                  disabled={shareLoading}
                  onClick={async () => {
                    if (!token || !selectedPhoto) return;
                    setShareLoading(true);
                    try {
                      const payload = await createPhotoShareLink(token, selectedPhoto.id);
                      const shareData: ShareData = {
                        title: selectedPhoto.guest_name ?? t('share.title', 'Geteiltes Foto'),
                        text: t('share.shareText', { event: state.meta?.event?.name ?? 'Fotospiel' }),
                        url: payload.url,
                      };
                      if (navigator.share && (!navigator.canShare || navigator.canShare(shareData))) {
                        await navigator.share(shareData).catch(() => undefined);
                      } else if (payload.url) {
                        await navigator.clipboard.writeText(payload.url);
                      }
                    } catch (err) {
                      console.error('share failed', err);
                    } finally {
                      setShareLoading(false);
                    }
                  }}
                >
                  {shareLoading ? <Loader2 className="h-4 w-4 animate-spin" aria-hidden /> : <Share className="h-4 w-4" aria-hidden />}
                  {t('share.shareCta', 'Teilen')}
                </Button>
              ) : null}
            </div>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
