import { useState, useEffect, useCallback, useMemo } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { motion, AnimatePresence } from 'framer-motion';
import { X, ChevronLeft, ChevronRight, Download } from 'lucide-react';
import { RowsPhotoAlbum } from 'react-photo-album';
import 'react-photo-album/rows.css';
import { getAlbumByName } from '@/api';
import { LightboxIndicator } from '@/components/common';

// 갤러리 CSS 스타일
const galleryStyles = `
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(20px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}
.react-photo-album {
    overflow: visible !important;
}
.react-photo-album--row {
    overflow: visible !important;
}
.react-photo-album--photo {
    transition: transform 0.3s ease, filter 0.3s ease !important;
    cursor: pointer;
    overflow: visible !important;
}
.react-photo-album--photo:hover {
    transform: scale(1.05);
    filter: brightness(0.9);
    z-index: 10;
}
`;

/**
 * PC 앨범 갤러리 페이지
 */
function PCAlbumGallery() {
  const { name } = useParams();
  const navigate = useNavigate();
  const [lightbox, setLightbox] = useState({ open: false, index: 0 });
  const [imageLoaded, setImageLoaded] = useState(false);
  const [slideDirection, setSlideDirection] = useState(0);
  const [preloadedImages] = useState(() => new Set());

  // 앨범 데이터 로드
  const { data: album, isLoading: loading } = useQuery({
    queryKey: ['album', name],
    queryFn: () => getAlbumByName(name),
    enabled: !!name,
  });

  // 앨범 데이터에서 사진 목록 추출
  const photos = useMemo(() => {
    if (!album?.conceptPhotos) return [];
    const allPhotos = [];
    Object.entries(album.conceptPhotos).forEach(([concept, conceptPhotos]) => {
      conceptPhotos.forEach((p) =>
        allPhotos.push({
          mediumUrl: p.medium_url,
          originalUrl: p.original_url,
          width: p.width || 800,
          height: p.height || 1200,
          title: concept,
          members: p.members ? p.members.split(', ') : [],
        })
      );
    });
    return allPhotos;
  }, [album]);

  // 라이트박스 열기
  const openLightbox = useCallback((index) => {
    setImageLoaded(false);
    setLightbox({ open: true, index });
    window.history.pushState({ lightbox: true }, '');
  }, []);

  // 뒤로가기 처리
  useEffect(() => {
    const handlePopState = () => {
      if (lightbox.open) {
        setLightbox((prev) => ({ ...prev, open: false }));
      }
    };

    window.addEventListener('popstate', handlePopState);
    return () => window.removeEventListener('popstate', handlePopState);
  }, [lightbox.open]);

  // 라이트박스 열릴 때 body 스크롤 숨기기
  useEffect(() => {
    if (lightbox.open) {
      document.documentElement.style.overflow = 'hidden';
      document.body.style.overflow = 'hidden';
    } else {
      document.documentElement.style.overflow = '';
      document.body.style.overflow = '';
    }
    return () => {
      document.documentElement.style.overflow = '';
      document.body.style.overflow = '';
    };
  }, [lightbox.open]);

  // 이전/다음 이미지
  const goToPrev = useCallback(() => {
    if (photos.length <= 1) return;
    setImageLoaded(false);
    setSlideDirection(-1);
    setLightbox((prev) => ({
      ...prev,
      index: (prev.index - 1 + photos.length) % photos.length,
    }));
  }, [photos.length]);

  const goToNext = useCallback(() => {
    if (photos.length <= 1) return;
    setImageLoaded(false);
    setSlideDirection(1);
    setLightbox((prev) => ({
      ...prev,
      index: (prev.index + 1) % photos.length,
    }));
  }, [photos.length]);

  // 다운로드
  const downloadImage = useCallback(async () => {
    const photo = photos[lightbox.index];
    if (!photo) return;

    try {
      const response = await fetch(photo.originalUrl);
      const blob = await response.blob();
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = `fromis9_${album?.title || 'photo'}_${String(lightbox.index + 1).padStart(2, '0')}.webp`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
    } catch (error) {
      console.error('다운로드 오류:', error);
    }
  }, [photos, lightbox.index, album?.title]);

  // 키보드 이벤트
  useEffect(() => {
    if (!lightbox.open) return;

    const handleKeyDown = (e) => {
      switch (e.key) {
        case 'ArrowLeft':
          goToPrev();
          break;
        case 'ArrowRight':
          goToNext();
          break;
        case 'Escape':
          window.history.back();
          break;
        default:
          break;
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [lightbox.open, goToPrev, goToNext]);

  // 프리로딩
  useEffect(() => {
    if (!lightbox.open || photos.length <= 1) return;

    const indicesToPreload = [];
    for (let offset = -2; offset <= 2; offset++) {
      if (offset === 0) continue;
      const idx = (lightbox.index + offset + photos.length) % photos.length;
      indicesToPreload.push(idx);
    }

    indicesToPreload.forEach((idx) => {
      const url = photos[idx].originalUrl;
      if (preloadedImages.has(url)) return;

      const img = new Image();
      img.onload = () => preloadedImages.add(url);
      img.src = url;
    });
  }, [lightbox.open, lightbox.index, photos, preloadedImages]);

  if (loading) {
    return (
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        className="py-16 flex justify-center items-center min-h-[60vh]"
      >
        <div className="animate-spin rounded-full h-12 w-12 border-4 border-primary border-t-transparent" />
      </motion.div>
    );
  }

  return (
    <>
      <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.3 }} className="py-16">
        <div className="px-24">
          {/* 브레드크럼 스타일 헤더 */}
          <div className="mb-8">
            <div className="flex items-center gap-2 text-sm text-gray-500 mb-2">
              <button onClick={() => navigate('/album')} className="hover:text-primary transition-colors">
                앨범
              </button>
              <span>/</span>
              <button onClick={() => navigate(`/album/${name}`)} className="hover:text-primary transition-colors">
                {album?.title}
              </button>
              <span>/</span>
              <span className="text-gray-700">컨셉 포토</span>
            </div>
            <h1 className="text-3xl font-bold">컨셉 포토</h1>
            <p className="text-gray-500 mt-1">{photos.length}장의 사진</p>
          </div>

          {/* CSS 스타일 주입 */}
          <style>{galleryStyles}</style>

          {/* Justified 갤러리 */}
          <RowsPhotoAlbum
            photos={photos.map((photo, idx) => ({
              src: photo.mediumUrl,
              width: photo.width || 800,
              height: photo.height || 1200,
              key: idx.toString(),
            }))}
            targetRowHeight={280}
            spacing={16}
            rowConstraints={{ singleRowMaxHeight: 400, minPhotos: 1 }}
            onClick={({ index }) => openLightbox(index)}
            componentsProps={{
              image: {
                loading: 'lazy',
                style: { borderRadius: '12px' },
              },
            }}
          />
        </div>
      </motion.div>

      {/* 라이트박스 */}
      <AnimatePresence>
        {lightbox.open && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
            className="fixed inset-0 bg-black/95 z-50 overflow-scroll lightbox-no-scrollbar"
            style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
          >
            <div className="min-w-[1400px] min-h-[1200px] w-full h-full relative flex items-center justify-center">
              {/* 상단 버튼들 */}
              <div className="absolute top-6 right-6 flex gap-3 z-10">
                <button className="text-white/70 hover:text-white transition-colors" onClick={downloadImage}>
                  <Download size={28} />
                </button>
                <button className="text-white/70 hover:text-white transition-colors" onClick={() => window.history.back()}>
                  <X size={32} />
                </button>
              </div>

              {/* 카운터 */}
              <div className="absolute top-6 left-6 text-white/70 text-sm z-10">
                {lightbox.index + 1} / {photos.length}
              </div>

              {/* 이전 버튼 */}
              {photos.length > 1 && (
                <button
                  className="absolute left-6 p-2 text-white/70 hover:text-white transition-colors z-10"
                  onClick={goToPrev}
                >
                  <ChevronLeft size={48} />
                </button>
              )}

              {/* 로딩 스피너 */}
              {!imageLoaded && (
                <div className="absolute inset-0 flex items-center justify-center">
                  <div className="animate-spin rounded-full h-12 w-12 border-4 border-white border-t-transparent" />
                </div>
              )}

              {/* 이미지 + 컨셉 정보 */}
              <div className="flex flex-col items-center mx-24">
                <motion.img
                  key={lightbox.index}
                  src={photos[lightbox.index]?.originalUrl}
                  alt="확대 이미지"
                  className={`max-w-[1100px] max-h-[900px] object-contain transition-opacity duration-200 ${
                    imageLoaded ? 'opacity-100' : 'opacity-0'
                  }`}
                  onLoad={() => setImageLoaded(true)}
                  initial={{ x: slideDirection * 100 }}
                  animate={{ x: 0 }}
                  transition={{ duration: 0.25, ease: 'easeOut' }}
                />
                {/* 컨셉 정보 + 멤버 */}
                {imageLoaded &&
                  (() => {
                    const title = photos[lightbox.index]?.title;
                    const hasValidTitle = title && title.trim() && title !== 'Default';
                    const members = photos[lightbox.index]?.members;
                    const hasMembers = members && String(members).trim();

                    if (!hasValidTitle && !hasMembers) return null;

                    return (
                      <div className="mt-6 flex flex-col items-center gap-2">
                        {hasValidTitle && (
                          <span className="px-4 py-2 bg-white/10 backdrop-blur-sm rounded-full text-white font-medium text-base">
                            {title}
                          </span>
                        )}
                        {hasMembers && (
                          <div className="flex items-center gap-2">
                            {String(members)
                              .split(',')
                              .map((member, idx) => (
                                <span key={idx} className="px-3 py-1.5 bg-primary/80 rounded-full text-white text-sm">
                                  {member.trim()}
                                </span>
                              ))}
                          </div>
                        )}
                      </div>
                    );
                  })()}
              </div>

              {/* 다음 버튼 */}
              {photos.length > 1 && (
                <button
                  className="absolute right-6 p-2 text-white/70 hover:text-white transition-colors z-10"
                  onClick={goToNext}
                >
                  <ChevronRight size={48} />
                </button>
              )}

              {/* 하단 점 인디케이터 */}
              <LightboxIndicator
                count={photos.length}
                currentIndex={lightbox.index}
                goToIndex={(i) => setLightbox((prev) => ({ ...prev, index: i }))}
              />
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </>
  );
}

export default PCAlbumGallery;
