import React, { useCallback, useEffect, useRef, useState } from 'react';
import { v4 } from 'uuid';
import { Placemark, useYMaps } from '@pbe/react-yandex-maps';
import type ymaps from 'yandex-maps';

import { IMapState } from 'yandex-maps';
import Portal from '@/components/Portal';
import Image from '@/components/Image';

interface IProps {
  mapRef?: React.RefObject<HTMLDivElement>;
  position: [number, number];
  setStateMap: (state: IMapState) => void;

  description: {
    title: string;
    subtitle: string;
  };
}

interface IPin {
  onPinClick: () => void;
  onVideoClick: () => void;
  onInfoClick: () => void;
  description: {
    title: string;
    subtitle: string;
  };
  isActive: boolean;
  className: string;
  id: string;
}

const createPinTemplateFactory =
  (ymap: typeof ymaps | null) =>
  ({ id, description, onPinClick, onVideoClick, onInfoClick, className, isActive }: IPin) => {
    if (!ymap) {
      return;
    }

    const ComponentPin = ymap?.templateLayoutFactory.createClass(
      `<div id="${id}" class="${className}">
      </div>`,
      {
        build: function () {
          (ComponentPin as any)?.superclass.build.call(this);
          const pin = this as any;

          if (!pin.inited) {
            pin.inited = true;

            pin.getData().geoObject.events.remove('click', onPinClick);
            pin.getData().geoObject.events.add('click', onPinClick);

            pin.getData().options.set('shape', {
              coordinates: [
                [-14, -14],
                [14, 14],
              ],
              type: 'Rectangle',
            });
          }
        },
      },
    );

    return ComponentPin;
  };

const Pin: React.FC<IProps> = ({ position, mapRef, description, setStateMap }) => {
  const [id] = useState(() => {
    return 'p' + v4().replaceAll('-', '');
  });

  const baloonref = useRef<HTMLDivElement>(null);
  const [isActive, setIsActive] = useState(false);
  const mapInstanceRef = useYMaps();

  const handleClick = useCallback(() => {
    console.log('click pin');
    setIsActive((prev) => !prev);
  }, []);

  const handleClickVideo = useCallback(() => {
    console.log('click Video');
    setIsActive((prev) => !prev);
  }, []);

  const handleClickInfo = useCallback(() => {
    console.log('click info');
    setIsActive((prev) => !prev);
  }, []);

  // Тут создаю template для проброса в iconLayout, о createPinTemplateFactory дальше
  const template = createPinTemplateFactory(mapInstanceRef)({
    onPinClick: handleClick,
    onInfoClick: handleClickInfo,
    onVideoClick: handleClickVideo,
    isActive,
    description,
    className: 'mapPin',
    id,
  });

  useEffect(() => {
    setStateMap({ center: position, zoom: 15 });
  }, [position]);

  useEffect(() => {
    if (!isActive) {
      return;
    }

    const int = setInterval(() => {
      const baloon = baloonref.current;
      const map = mapRef?.current;

      if (baloon && map) {
        const pin = map.querySelector(`#${id}`);

        if (!pin) {
          return;
        }

        const bodyRect = mapRef.current.getBoundingClientRect(),
          elemRect = pin.getBoundingClientRect(),
          offsetY = !elemRect ? 0 : elemRect.top - bodyRect.top,
          offsetX = !elemRect ? 0 : elemRect.left - bodyRect.left;

        baloon.style.left = offsetX + 'px';
        baloon.style.top = offsetY + 'px';
      }
    }, 1000 / 60);

    return () => {
      clearInterval(int);
    };
  }, [id, mapRef, isActive]);

  return (
    <div>
      {isActive && (
        <Portal parent={mapRef?.current}>
          <div className='mapPin__modal' ref={baloonref}>
            <div className='mapPin__modalTitle'>{description.title}</div>
            <div className='mapPin__modalSubtitle'>{description.subtitle}</div>

            <hr className='mapPin__hr' />

            <div className='mapPin__actions'>
              <div className='mapPin__action'>
                <Image
                  alt=''
                  src='/images/icons/icon-pin-video.svg'
                  className='mapPin__actionIcon'
                />
                <span className='mapPin__actionLabel'>Видео</span>
              </div>

              <div className='mapPin__action'>
                <Image
                  alt=''
                  src='/images/icons/icon-pin-info.svg'
                  className='mapPin__actionIcon'
                />
                <span className='mapPin__actionLabel'>Подробнее</span>
              </div>
            </div>
          </div>
        </Portal>
      )}

      <Placemark
        // Проброс позиции пина на карте
        geometry={position}
        options={{
          // Проброс темплейта
          iconLayout: template,
        }}
      />
    </div>
  );
};

export default Pin;
