import React, {
  ReactNode,
  useState,
  useEffect,
  useRef,
  useMemo,
  useCallback,
  Fragment,
} 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 { getDocumentByDeputy, getGalleryCarousel } from '../utils/gallery';
import { useParams } from 'react-router-dom';
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import NavTab from './NavTab';
import { useTranslation } from 'react-i18next';
import PDFCard from './PDFCard';
import PDFViewerModal from './PDFViewerModal';

const AUTOPLAY_INTERVAL = 3000;

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

const GalleryCarousel: React.FC<{}> = () => {
  const { t } = useTranslation();
  const mainRef = useRef<Splide | null>(null);
  const thumbsRef = useRef<Splide | null>(null);

  const [activeTab, setActiveTab] = useState(TAB_INDEX.PHOTO);
  const [isImageModalOpen, setImageModalOpen] = useState(false);
  const { id } = useParams();

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

  const [allItems, setAllItems] = useState(staticAllItem);
  const [documents, setDocuments] = useState(staticDocs);

  useEffect(() => {
    const sItems = getGalleryCarousel(id);
    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: any[] = [];
          const docList: any[] = [];

          data.forEach((item: any) => {
            if (item.type === 'document' || item.type === 'pdf') {
              docList.push({
                name: item.title,
                path: item.media_url,
                thumb: item.thumbnail_url || '',
              });
            } else {
              mediaList.push({
                type: item.type === 'video' ? 'video' : 'img',
                src: item.media_url,
                thumbnail: item.thumbnail_url || item.media_url,
                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]);

  const haveVideo = allItems.filter((item) => item.type === 'video').length > 0;
  const carouselItems = useMemo(() => {
    if (activeTab === TAB_INDEX.PHOTO) {
      return allItems.filter((item) => item.type === 'img');
    } else if (activeTab === TAB_INDEX.VIDEO) {
      return allItems.filter((item) => item.type === 'video');
    }
    return allItems;
  }, [activeTab, allItems]);

  const [selectedDocPath, setSelectedDocPath] = useState('');
  const [isPDFModalOpen, setIsPDFModalOpen] = useState(false);

  const [imageSrc, setImageSrc] = useState<string>(
    carouselItems?.[0]?.src || ''
  );
  const [videoSrc, setVideoSrc] = useState<string>(
    carouselItems?.[0]?.src || ''
  );

  useEffect(() => {
    if (mainRef.current && thumbsRef.current && thumbsRef.current.splide) {
      mainRef.current.splide?.sync(thumbsRef.current.splide);
    }
  }, [carouselItems]);

  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 = useCallback(() => {
    setImageModalOpen(true);
    pauseCarouselAutoplay();
  }, []);

  const closeImageModal = () => {
    setImageModalOpen(false);
    resumeCarouselAutoplay();
  };

  const handleCarouselMove = useCallback(
    (_: any, newIndex: number) => {
      const type = carouselItems[newIndex]?.type;
      const src = carouselItems[newIndex]?.src;
      if (type === 'img') {
        setImageSrc(src);
        setVideoSrc('');
      } else if (type === 'video') {
        setVideoSrc(src);
        setImageSrc('');
      }

      const videoElements = document.getElementsByTagName('video');
      for (let i = 0; i < videoElements.length; i++) {
        const video = videoElements[i];
        video.pause();
      }
    },
    [carouselItems]
  );

  const renderSlides = useCallback(
    (isThumbnail?: boolean): ReactNode[] => {
      return carouselItems.map((slide, idx) => {
        return (
          <SplideSlide key={slide.src + idx}>
            {slide.type === 'img' || isThumbnail ? (
              <img
                src={slide.thumbnail || slide.src}
                alt={slide.alt}
                className="mx-auto sm:h-[480px] xl:h-[600px] cursor-pointer object-contain"
                onClick={() => {
                  if (!isThumbnail) openImageModal();
                }}
              />
            ) : (
              <video
                width={1000}
                height={600}
                controls
                className="mx-auto"
                onPlay={pauseCarouselAutoplay}
                onPause={resumeCarouselAutoplay}
              >
                <source src={slide.src} type="video/mp4" />
                Your browser does not support the video tag.
              </video>
            )}
          </SplideSlide>
        );
      });
    },
    [carouselItems, openImageModal]
  );

  const mainOptions: Options = useMemo(
    () => ({
      type: 'fade',
      perPage: 1,
      perMove: 1,
      pagination: false,
      arrows: false,
      height: '600px',
      breakpoints: {
        1440: {
          height: '480px',
        },
      },
    }),
    []
  );

  const thumbsOptions: Options = useMemo(
    () => ({
      type: 'slide',
      rewind: true,
      gap: '1rem',
      pagination: false,
      fixedWidth: 200,
      fixedHeight: 100,
      cover: true,
      focus: 'center',
      isNavigation: true,
      width: '792px',
      breakpoints: {
        1440: {
          width: '600px',
        },
      },
      dragMinThreshold: {
        mouse: 4,
        touch: 10,
      },
      autoplay: true,
      interval: AUTOPLAY_INTERVAL,
    }),
    []
  );

  const tabs = useMemo(() => {
    const _tabs = [
      {
        id: TAB_INDEX.PHOTO,
        title: t('photo'),
        isShown: true,
      },
      {
        id: TAB_INDEX.VIDEO,
        title: t('video'),
        isShown: haveVideo,
      },
      {
        id: TAB_INDEX.DOCUMENT,
        title: t('document'),
        isShown: documents.length > 0,
      },
    ];
    return _tabs.filter((tab) => tab.isShown);
  }, [documents.length, haveVideo, t]);

  const renderRightSection = useCallback(() => {
    if (activeTab === TAB_INDEX.DOCUMENT) {
      return (
        <div className="flex justify-center">
          <div className="w-[800px] grid grid-cols-3 gap-24 mt-30">
            {documents.map((doc) => (
              <Fragment key={doc.name}>
                <PDFCard
                  name={doc.name}
                  thumb={doc.thumb}
                  onClick={() => {
                    setSelectedDocPath(doc.path);
                    setIsPDFModalOpen(true);
                  }}
                />
              </Fragment>
            ))}
          </div>
        </div>
      );
    }

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

    return (
      <>
        <Splide options={mainOptions} ref={mainRef}>
          {renderSlides()}
        </Splide>
        <div className="w-full">
          <Splide
            options={thumbsOptions}
            ref={thumbsRef}
            className="mt-24 mx-auto"
            onMove={handleCarouselMove}
          >
            {renderSlides(true)}
          </Splide>
        </div>
      </>
    );
  }, [
    activeTab,
    carouselItems.length,
    documents,
    handleCarouselMove,
    mainOptions,
    renderSlides,
    thumbsOptions,
  ]);

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

      {renderRightSection()}

      <Modal
        isOpen={isImageModalOpen}
        onRequestClose={closeImageModal}
        contentLabel="Image Modal"
        style={{
          overlay: {
            zIndex: 100,
            backgroundColor: 'rgba(0, 0, 0, 0.7)',
          },
          content: {
            display: 'flex',
            background: 'transparent',
            border: 'none',
          },
        }}
      >
        <ArrowBackIosIcon
          className="absolute top-1/2 -translate-y-1/2 text-white cursor-pointer"
          sx={{ fontSize: 50 }}
          onClick={() => {
            thumbsRef.current?.splide?.go('-1');
          }}
        />

        {imageSrc && <img src={imageSrc} alt="img" className="mx-auto max-h-[85vh] object-contain" />}

        {videoSrc && (
          <video
            src={videoSrc}
            width="85%"
            height="100%"
            controls
            className="mx-auto"
          />
        )}

        <ArrowForwardIosIcon
          className="absolute top-1/2 -translate-y-1/2 right-16 text-white cursor-pointer"
          sx={{ fontSize: 50 }}
          onClick={() => {
            thumbsRef.current?.splide?.go('+1');
          }}
        />

        <CancelIcon
          className="absolute right-12 top-12 text-white cursor-pointer"
          sx={{ fontSize: 50 }}
          onClick={closeImageModal}
        />
      </Modal>

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

export default GalleryCarousel;
