import { AnimatePresence, motion } from 'framer-motion';
import { devices } from '../consts/devices';
import { IDevice } from '../types/IDevice';
import { Title } from './ui/Title';
import { useEffect, useRef, useState } from 'react';
import { useHover, useOnClickOutside } from 'usehooks-ts';
import { ChevronUpIcon } from './icons/ChevronUpIcon';
import { ChevronDownIcon } from './icons/ChevronDownIcon';

export function Devices() {
  return (
    <div
      id="devices"
      className="space-y-8 scroll-m-14 lg:scroll-m-20 sm:space-y-10 lg:space-y-20 lg:pt-[180px] sm:pt-[140px] pt-20"
    >
      <Title>
        Работаем с
        <span className="text-gradient"> любыми типами оборудования</span>
        <br /> и предложим лучшее мультимедийное оснащение
      </Title>
      <div className="max-lg:hidden">
        {devices.map((device, index) => (
          <DesktopDevice key={device.title} {...device} number={index + 1} />
        ))}
      </div>
      <div className="lg:hidden">
        {devices.map(device => (
          <Device key={device.title} {...device} />
        ))}
      </div>
    </div>
  );
}

function DesktopDevice({
  title,
  description,
  img,
  number,
}: IDevice & {
  number: number;
}) {
  const root = useRef<HTMLDivElement>(null);
  const descriptionRef = useRef<HTMLParagraphElement>(null);

  const [descriptionHeight, setDescriptionHeight] = useState(0);

  const hovered = useHover(root);

  useEffect(() => {
    setDescriptionHeight(descriptionRef.current?.clientHeight ?? 0);
  }, [descriptionRef, hovered]);

  return (
    <motion.div
      ref={root}
      className="py-10 border-b border-[#3D425C] flex justify-between items-start relative [clip-path:polygon(0%_-50%,100%_-50%,100%_100%,-50%_100%)]"
      style={{ maxHeight: 112 + descriptionHeight + 21 }}
      animate={{
        height: hovered
          ? (root.current?.clientHeight ?? 0) + descriptionHeight + 24
          : 112,
      }}
      transition={{ delay: 0.3 }}
    >
      <div className="space-y-6">
        <p className="font-medium h3">{title}</p>
        <AnimatePresence>
          {hovered && (
            <motion.div
              ref={descriptionRef}
              initial={{ opacity: 0 }}
              animate={{ opacity: 0.6 }}
              exit={{ opacity: 0 }}
              transition={{ delay: 0.3 }}
              className="l-text space-y-4 max-w-[calc(600/1552*100%)] absolute"
            >
              {description.map(paragraph => (
                <p key={paragraph}>
                  {paragraph}
                  <br />
                </p>
              ))}
            </motion.div>
          )}
        </AnimatePresence>
      </div>
      <AnimatePresence>
        {hovered && (
          <motion.img
            src={img}
            alt={title}
            className="bottom-0 right-[calc(144/1552*100%)] w-[calc(560/1552*100%)] max-w-[560px] absolute"
            initial={{ opacity: 0, y: 500 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: 100 }}
            transition={{ duration: 0.5, delay: 0.3 }}
          />
        )}
      </AnimatePresence>
      <p className="m-text text-[#52587A] font-medium">[0{number}]</p>
    </motion.div>
  );
}

function Device({ title, description, img }: IDevice) {
  const [expanded, setExpanded] = useState(false);
  const [descriptionHeight, setDescriptionHeight] = useState(0);
  const [imgHeight, setImgHeight] = useState(0);

  const root = useRef<HTMLDivElement>(null);
  const descriptionRef = useRef<HTMLParagraphElement>(null);
  const imgRef = useRef<HTMLImageElement>(null);

  useEffect(() => {
    if (!imgRef.current) return;
    imgRef.current!.onload = () =>
      setImgHeight(imgRef.current?.clientHeight ?? 0);
  }, [imgRef, expanded]);

  useEffect(() => {
    setDescriptionHeight(descriptionRef.current?.clientHeight ?? 0);
  }, [descriptionRef, expanded]);

  useOnClickOutside(root, () => setExpanded(false), 'mouseup');

  return (
    <motion.div
      animate={{
        height: expanded
          ? (root.current?.clientHeight ?? 0) +
            descriptionHeight +
            imgHeight +
            56
          : 72,
      }}
      transition={{ duration: 0.3 }}
      ref={root}
      onClick={() => setExpanded(prev => !prev)}
      className="py-4 space-y-6 border-t last:border-b border-[#3D425C] relative select-none"
    >
      <div className="flex items-center justify-between py-2">
        <p className="font-medium h3">{title}</p>
        {expanded ? <ChevronUpIcon /> : <ChevronDownIcon />}
      </div>
      <AnimatePresence>
        {expanded && (
          <motion.p
            ref={descriptionRef}
            initial={{ opacity: 0 }}
            animate={{ opacity: +expanded, transition: { delay: 0.3 } }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.3 }}
            className="mb-4 space-y-4 h4"
          >
            {description.map(paragraph => (
              <p key={paragraph}>{paragraph}</p>
            ))}
          </motion.p>
        )}
      </AnimatePresence>
      <AnimatePresence>
        {expanded && (
          <motion.img
            ref={imgRef}
            initial={{ opacity: 0 }}
            animate={{ opacity: +expanded, transition: { delay: 0.3 } }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.3 }}
            src={img}
            alt={title}
          />
        )}
      </AnimatePresence>
    </motion.div>
  );
}
