"use client"

import { AnimatePresence, motion } from "motion/react"
import { useEffect, useState } from "react"
import { useIntl } from "react-intl"

import Image from "../../Image"

import { IconButton } from "../../IconButton"
import { Typography } from "../../Typography"

import { LightboxImage } from "../index"
import styles from "./fullView.module.css"

type FullViewProps = {
  image: LightboxImage
  onClose: () => void
  onNext: () => void
  onPrev: () => void
  currentIndex: number
  totalImages: number
  hideLabel?: boolean
}

export default function FullView({
  image,
  onClose,
  onNext,
  onPrev,
  currentIndex,
  totalImages,
  hideLabel,
}: FullViewProps) {
  const intl = useIntl()
  const [animateLeft, setAnimateLeft] = useState(true)

  function handleSwipe(offset: number) {
    if (offset > 30) {
      setAnimateLeft(false)
      onPrev()
    }
    if (offset < -30) {
      setAnimateLeft(true)
      onNext()
    }
  }

  function handleNext() {
    setAnimateLeft(true)
    onNext()
  }

  function handlePrev() {
    setAnimateLeft(false)
    onPrev()
  }

  const handleKeyDown = (e: KeyboardEvent) => {
    if (e.key === "ArrowLeft") {
      handlePrev()
    } else if (e.key === "ArrowRight") {
      handleNext()
    }
  }

  useEffect(() => {
    window.addEventListener("keydown", handleKeyDown)

    return () => {
      window.removeEventListener("keydown", handleKeyDown)
    }
  })

  const variants = {
    initial: (animateLeft: boolean) => ({
      opacity: 0,
      x: animateLeft ? 300 : -300,
    }),
    animate: { opacity: 1, x: 0 },
    exit: (animateLeft: boolean) => ({
      opacity: 0,
      x: animateLeft ? -300 : 300,
    }),
  } as const

  return (
    <div className={styles.fullView}>
      <IconButton
        variant="Muted"
        className={styles.closeButton}
        onPress={onClose}
        aria-label={intl.formatMessage({
          id: "common.close",
          defaultMessage: "Close",
        })}
        iconName="close"
      />
      <div className={styles.header}>
        <Typography variant="Tag/sm">
          <span className={styles.imageCount}>
            {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
            {`${currentIndex + 1} / ${totalImages}`}
          </span>
        </Typography>
      </div>
      <div className={styles.content}>
        <AnimatePresence initial={false} custom={animateLeft}>
          <motion.div
            key={image.src}
            custom={animateLeft}
            variants={variants}
            initial="initial"
            animate="animate"
            exit="exit"
            transition={{ duration: 0.3 }}
            className={styles.motionContainer}
            drag="x"
            onDragEnd={(_e, info) => handleSwipe(info.offset.x)}
          >
            <div className={styles.imageWrapper}>
              <Image
                alt={image.alt}
                fill
                sizes="90vw"
                src={image.src}
                className={styles.image}
              />
              {image.caption && !hideLabel ? (
                <Typography variant="Body/Paragraph/mdRegular">
                  <p className={styles.caption}>{image.caption}</p>
                </Typography>
              ) : null}
            </div>
          </motion.div>
        </AnimatePresence>
      </div>

      <IconButton
        variant="Muted"
        className={`${styles.navigationButton} ${styles.prev}`}
        onPress={handlePrev}
        iconName="arrow_back"
      />
      <IconButton
        variant="Muted"
        className={`${styles.navigationButton} ${styles.next}`}
        onPress={handleNext}
        iconName="arrow_forward"
      />
    </div>
  )
}
