import React, {
  Fragment,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import { Splide, SplideSlide } from '@splidejs/react-splide';
import '@splidejs/react-splide/css';
import { Options } from '@splidejs/splide';
import Modal from 'react-modal';
import CancelIcon from '@mui/icons-material/Cancel';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import VideocamOffOutlinedIcon from '@mui/icons-material/VideocamOffOutlined';
import InsertPhotoOutlinedIcon from '@mui/icons-material/InsertPhotoOutlined';
import DescriptionIcon from '@mui/icons-material/Description';
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import { useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { getDocumentByDeputy, getGalleryCarousel } from '../utils/gallery';
import NavTab from './NavTab';
import PDFCard from './PDFCard';
import PDFViewerModal from './PDFViewerModal';

const AUTOPLAY_INTERVAL = 3500;

enum TAB_INDEX {
  PHOTO = 1,
  VIDEO = 2,
  DOCUMENT = 3,
}

interface MediaItem {
  type: 'img' | 'video';
  src: string;
  thumbnail?: string;
  alt?: string;
}

const GalleryCarousel: React.FC<{}> = () => {
  const { t } = useTranslation();
  const { id } = useParams();

  const staticAllItem = getGalleryCarousel(id);
  const staticDocs = getDocumentByDeputy(id);

  const [allItems, setAllItems] = useState<MediaItem[]>(staticAllItem as MediaItem[]);
  const [documents, setDocuments] = useState(staticDocs);
  const [activeTab, setActiveTab] = useState<number>(TAB_INDEX.PHOTO);

  // Video State
  const [selectedVideoIndex, setSelectedVideoIndex] = useState(0);

  // Photo Modal State
  const [modalPhotoIndex, setModalPhotoIndex] = useState<number | null>(null);

  // PDF Modal State
  const [selectedDocPath, setSelectedDocPath] = useState('');
  const [isPDFModalOpen, setIsPDFModalOpen] = useState(false);

  const mainRef = useRef<Splide | null>(null);
  const thumbsRef = useRef<Splide | null>(null);

  useEffect(() => {
    const sItems = getGalleryCarousel(id) as MediaItem[];
    const sDocs = getDocumentByDeputy(id);

    fetch(`/api/galleries?deputy_id=${id}`)
      .then((res) => res.json())
      .then((data) => {
        if (Array.isArray(data) && data.length > 0) {
          const mediaList: MediaItem[] = [];
          const docList: any[] = [];

          data.forEach((item: any) => {
            const isDoc = item.type === 'document' || item.type === 'pdf';
            const isVideo = item.type === 'video';

            if (isDoc) {
              docList.push({
                name: item.title,
                path: item.media_url || item.src,
                thumb: item.thumbnail_url || item.thumbnail || '',
              });
            } else if (isVideo) {
              mediaList.push({
                type: 'video',
                src: item.media_url || item.src,
                thumbnail: item.thumbnail_url || item.thumbnail || '',
                alt: item.title,
              });
            } else {
              mediaList.push({
                type: 'img',
                src: item.media_url || item.src,
                thumbnail: item.thumbnail_url || item.thumbnail || '',
                alt: item.title,
              });
            }
          });

          if (mediaList.length > 0) setAllItems(mediaList);
          else setAllItems(sItems);

          if (docList.length > 0) setDocuments(docList);
          else setDocuments(sDocs);
        } else {
          setAllItems(sItems);
          setDocuments(sDocs);
        }
      })
      .catch(() => {
        setAllItems(sItems);
        setDocuments(sDocs);
      });
  }, [id]);

  // Derived filtered lists
  const photoItems = useMemo(
    () => allItems.filter((item) => item.type === 'img'),
    [allItems]
  );
  const videoItems = useMemo(
    () => allItems.filter((item) => item.type === 'video'),
    [allItems]
  );

  const havePhoto = photoItems.length > 0;
  const haveVideo = videoItems.length > 0;
  const haveDoc = documents.length > 0;

  const tabs = useMemo(() => {
    const _tabs = [
      {
        id: TAB_INDEX.PHOTO,
        title: t('photo') || 'Foto',
        isShown: havePhoto,
      },
      {
        id: TAB_INDEX.VIDEO,
        title: t('video') || 'Video',
        isShown: haveVideo,
      },
      {
        id: TAB_INDEX.DOCUMENT,
        title: t('document') || 'Dokumen',
        isShown: haveDoc,
      },
    ];
    return _tabs.filter((tab) => tab.isShown);
  }, [havePhoto, haveVideo, haveDoc, t]);

  // Auto fallback active tab if current tab is not available
  useEffect(() => {
    if (tabs.length === 0) return;
    const isCurrentTabValid = tabs.some((tab) => tab.id === activeTab);
    if (!isCurrentTabValid) {
      setActiveTab(tabs[0].id);
    }
  }, [tabs, activeTab]);

  // Sync main & thumbs Splide for photos
  useEffect(() => {
    if (
      activeTab === TAB_INDEX.PHOTO &&
      photoItems.length > 1 &&
      mainRef.current &&
      thumbsRef.current &&
      thumbsRef.current.splide
    ) {
      mainRef.current.splide?.sync(thumbsRef.current.splide);
    }
  }, [activeTab, photoItems]);

  const pauseCarouselAutoplay = () => {
    if (thumbsRef.current && thumbsRef.current.splide) {
      const { Autoplay } = thumbsRef.current.splide.Components;
      Autoplay?.pause();
    }
  };

  const resumeCarouselAutoplay = () => {
    if (thumbsRef.current && thumbsRef.current.splide) {
      const { Autoplay } = thumbsRef.current.splide.Components;
      Autoplay?.play();
    }
  };

  const openImageModal = (idx: number) => {
    setModalPhotoIndex(idx);
    pauseCarouselAutoplay();
  };

  const closeImageModal = () => {
    setModalPhotoIndex(null);
    resumeCarouselAutoplay();
  };

  const mainOptions: Options = useMemo(
    () => ({
      type: 'fade',
      perPage: 1,
      perMove: 1,
      pagination: false,
      arrows: photoItems.length > 1,
      height: '380px',
      breakpoints: {
        1440: {
          height: '340px',
        },
        1024: {
          height: '300px',
        },
        768: {
          height: '240px',
        },
      },
    }),
    [photoItems.length]
  );

  const thumbsOptions: Options = useMemo(
    () => ({
      type: 'slide',
      rewind: true,
      gap: '0.75rem',
      pagination: false,
      fixedWidth: 130,
      fixedHeight: 75,
      cover: true,
      focus: 'center',
      isNavigation: true,
      width: '100%',
      dragMinThreshold: {
        mouse: 4,
        touch: 10,
      },
      autoplay: photoItems.length > 1,
      interval: AUTOPLAY_INTERVAL,
    }),
    [photoItems.length]
  );

  // Render Video Section
  const renderVideoSection = () => {
    if (videoItems.length === 0) {
      return (
        <div className="flex flex-col items-center justify-center py-20 text-slate-400">
          <VideocamOffOutlinedIcon sx={{ fontSize: 56 }} className="mb-3 opacity-40 text-slate-400" />
          <p className="text-sm md:text-base font-medium">Belum ada video dokumentasi untuk kedeputian ini.</p>
        </div>
      );
    }

    const currentVideo = videoItems[selectedVideoIndex] || videoItems[0];
    const poster =
      currentVideo.thumbnail &&
      !currentVideo.thumbnail.toLowerCase().endsWith('.mp4') &&
      !currentVideo.thumbnail.toLowerCase().endsWith('.mkv')
        ? currentVideo.thumbnail
        : undefined;

    return (
      <div className="w-full flex flex-col items-center justify-center py-2 animate-fadeIn">
        {/* Main Video Player */}
        <div className="w-full max-w-[850px] bg-black/95 rounded-2xl overflow-hidden border border-white/15 shadow-2xl relative">
          <div className="w-full aspect-video max-h-[460px] bg-black flex items-center justify-center">
            <video
              key={currentVideo.src}
              controls
              playsInline
              preload="metadata"
              poster={poster}
              className="w-full h-full object-contain bg-black mx-auto"
            >
              <source src={currentVideo.src} type="video/mp4" />
              Browser Anda tidak mendukung pemutar video HTML5.
            </video>
          </div>

          {currentVideo.alt && (
            <div className="px-5 py-3 bg-slate-900/95 border-t border-white/10 flex items-center justify-between">
              <span className="text-sm font-semibold text-white tracking-wide flex items-center gap-2">
                <span className="w-2.5 h-2.5 rounded-full bg-[#00AFDD] animate-pulse"></span>
                {currentVideo.alt}
              </span>
              <span className="text-xs text-slate-400 font-mono">
                {selectedVideoIndex + 1} / {videoItems.length}
              </span>
            </div>
          )}
        </div>

        {/* Video Playlist Selector if more than 1 video */}
        {videoItems.length > 1 && (
          <div className="w-full max-w-[850px] mt-4 flex flex-wrap gap-2.5 justify-center items-center">
            {videoItems.map((vid, idx) => {
              const isSelected = idx === selectedVideoIndex;
              return (
                <button
                  key={vid.src + idx}
                  type="button"
                  onClick={() => setSelectedVideoIndex(idx)}
                  className={`px-4 py-2 rounded-xl text-xs font-semibold flex items-center gap-2 transition-all cursor-pointer ${
                    isSelected
                      ? 'bg-[#00AFDD] text-white shadow-lg shadow-[#00AFDD]/40 border border-[#00AFDD]'
                      : 'bg-slate-800/80 text-slate-300 hover:text-white hover:bg-slate-700 border border-white/10'
                  }`}
                >
                  <PlayArrowIcon sx={{ fontSize: 16 }} />
                  <span className="max-w-[200px] truncate">{vid.alt || `Video ${idx + 1}`}</span>
                </button>
              );
            })}
          </div>
        )}
      </div>
    );
  };

  // Render Photo Section
  const renderPhotoSection = () => {
    if (photoItems.length === 0) {
      return (
        <div className="flex flex-col items-center justify-center py-20 text-slate-400">
          <InsertPhotoOutlinedIcon sx={{ fontSize: 56 }} className="mb-3 opacity-40 text-slate-400" />
          <p className="text-sm md:text-base font-medium">Belum ada foto dokumentasi untuk kedeputian ini.</p>
        </div>
      );
    }

    if (photoItems.length === 1) {
      const singlePhoto = photoItems[0];
      return (
        <div className="w-full flex flex-col items-center justify-center py-2 animate-fadeIn">
          <div
            className="w-full max-w-[850px] bg-black/40 rounded-2xl overflow-hidden border border-white/10 shadow-xl cursor-pointer group relative"
            onClick={() => openImageModal(0)}
          >
            <img
              src={singlePhoto.src}
              alt={singlePhoto.alt || 'Foto Dokumentasi'}
              className="mx-auto h-[380px] max-w-full object-contain transition-transform duration-300 group-hover:scale-[1.02]"
            />
            {singlePhoto.alt && (
              <div className="px-5 py-2.5 bg-slate-900/80 border-t border-white/10 text-center">
                <span className="text-sm font-semibold text-white tracking-wide">
                  {singlePhoto.alt}
                </span>
              </div>
            )}
          </div>
        </div>
      );
    }

    return (
      <div className="w-full flex flex-col items-center justify-center animate-fadeIn">
        <div className="w-full max-w-[850px]">
          <Splide options={mainOptions} ref={mainRef}>
            {photoItems.map((slide, idx) => (
              <SplideSlide key={slide.src + idx}>
                <div
                  className="w-full h-full flex items-center justify-center cursor-pointer group"
                  onClick={() => openImageModal(idx)}
                >
                  <img
                    src={slide.src}
                    alt={slide.alt || 'Foto Dokumentasi'}
                    className="mx-auto h-full max-w-full object-contain rounded-xl transition-transform duration-300 group-hover:scale-[1.02]"
                  />
                </div>
              </SplideSlide>
            ))}
          </Splide>
        </div>

        <div className="w-full max-w-[650px] mt-4">
          <Splide options={thumbsOptions} ref={thumbsRef} className="mx-auto">
            {photoItems.map((slide, idx) => (
              <SplideSlide key={'thumb-' + slide.src + idx}>
                <img
                  src={slide.thumbnail || slide.src}
                  alt={slide.alt}
                  className="w-full h-full object-cover rounded-lg cursor-pointer border border-white/20 hover:border-[#00AFDD] transition-all"
                />
              </SplideSlide>
            ))}
          </Splide>
        </div>
      </div>
    );
  };

  // Render Document Section
  const renderDocSection = () => {
    if (documents.length === 0) {
      return (
        <div className="flex flex-col items-center justify-center py-20 text-slate-400">
          <DescriptionIcon sx={{ fontSize: 56 }} className="mb-3 opacity-40 text-slate-400" />
          <p className="text-sm md:text-base font-medium">Belum ada dokumen untuk kedeputian ini.</p>
        </div>
      );
    }

    return (
      <div className="w-full max-h-[460px] overflow-y-auto overscroll-contain pr-2 custom-scrollbar flex justify-center py-4 animate-fadeIn">
        <div className="w-full max-w-[800px] grid grid-cols-2 sm:grid-cols-3 gap-6 sm:gap-10 my-auto">
          {documents.map((doc) => (
            <Fragment key={doc.name}>
              <PDFCard
                name={doc.name}
                thumb={doc.thumb}
                onClick={() => {
                  setSelectedDocPath(doc.path);
                  setIsPDFModalOpen(true);
                }}
              />
            </Fragment>
          ))}
        </div>
      </div>
    );
  };

  const renderContent = useCallback(() => {
    if (activeTab === TAB_INDEX.VIDEO) {
      return renderVideoSection();
    }
    if (activeTab === TAB_INDEX.DOCUMENT) {
      return renderDocSection();
    }
    return renderPhotoSection();
  }, [activeTab, videoItems, selectedVideoIndex, photoItems, documents]);

  const currentModalPhoto =
    modalPhotoIndex !== null && photoItems[modalPhotoIndex]
      ? photoItems[modalPhotoIndex]
      : null;

  return (
    <>
      {tabs.length > 1 && (
        <NavTab tabs={tabs} activeTab={activeTab} setActiveTab={setActiveTab} />
      )}

      {renderContent()}

      {/* Fullscreen Photo Preview Modal */}
      <Modal
        isOpen={modalPhotoIndex !== null}
        onRequestClose={closeImageModal}
        contentLabel="Image Modal"
        style={{
          overlay: {
            zIndex: 100,
            backgroundColor: 'rgba(0, 0, 0, 0.88)',
            backdropFilter: 'blur(10px)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            padding: '16px',
          },
          content: {
            position: 'relative',
            inset: 'auto',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            background: 'transparent',
            border: 'none',
            padding: 0,
            maxWidth: '95vw',
            maxHeight: '90vh',
            overflow: 'visible',
          },
        }}
      >
        {currentModalPhoto && (
          <div className="relative flex flex-col items-center justify-center max-w-full max-h-full">
            {/* Previous Arrow */}
            {photoItems.length > 1 && (
              <button
                type="button"
                onClick={(e) => {
                  e.stopPropagation();
                  setModalPhotoIndex((prev) =>
                    prev !== null ? (prev - 1 + photoItems.length) % photoItems.length : 0
                  );
                }}
                className="absolute left-[-48px] top-1/2 -translate-y-1/2 text-white/80 hover:text-white bg-black/60 hover:bg-black/90 p-2.5 rounded-full transition-all cursor-pointer z-10 hidden sm:block border border-white/20"
                aria-label="Sebelumnya"
              >
                <ArrowBackIosIcon sx={{ fontSize: 28, marginLeft: '6px' }} />
              </button>
            )}

            {/* Photo Image */}
            <img
              src={currentModalPhoto.src}
              alt={currentModalPhoto.alt || 'Foto Preview'}
              className="max-h-[82vh] max-w-[90vw] object-contain rounded-xl shadow-2xl border border-white/15"
            />

            {/* Next Arrow */}
            {photoItems.length > 1 && (
              <button
                type="button"
                onClick={(e) => {
                  e.stopPropagation();
                  setModalPhotoIndex((prev) =>
                    prev !== null ? (prev + 1) % photoItems.length : 0
                  );
                }}
                className="absolute right-[-48px] top-1/2 -translate-y-1/2 text-white/80 hover:text-white bg-black/60 hover:bg-black/90 p-2.5 rounded-full transition-all cursor-pointer z-10 hidden sm:block border border-white/20"
                aria-label="Selanjutnya"
              >
                <ArrowForwardIosIcon sx={{ fontSize: 28 }} />
              </button>
            )}

            {/* Close Button */}
            <button
              type="button"
              onClick={closeImageModal}
              className="absolute -top-12 right-0 text-white/80 hover:text-white bg-black/60 hover:bg-black/90 p-1.5 rounded-full transition-all cursor-pointer shadow-lg border border-white/20"
              aria-label="Tutup"
            >
              <CancelIcon sx={{ fontSize: 32 }} />
            </button>

            {/* Caption */}
            {currentModalPhoto.alt && (
              <div className="mt-3 px-4 py-1.5 bg-black/70 backdrop-blur-md rounded-full border border-white/10 text-xs sm:text-sm text-slate-200">
                {currentModalPhoto.alt}
              </div>
            )}
          </div>
        )}
      </Modal>

      {/* PDF Viewer Modal */}
      {selectedDocPath && (
        <PDFViewerModal
          fileUrl={selectedDocPath}
          isOpen={isPDFModalOpen}
          onClose={() => setIsPDFModalOpen(false)}
        />
      )}
    </>
  );
};

export default GalleryCarousel;
