import { useEffect, useRef, useState } from "react";
import styles from "./styles.module.css";
import { EDirectionOnboarding } from "@/types";

interface OnboardingProps {
  targetRef: HTMLElement;
  isShow: boolean;
  direction?: EDirectionOnboarding;
  showBackground?: boolean;
  children: JSX.Element;
  classNameContainer?: string;
}
interface IBoardingCoordinates {
  top: number;
  left: number;
}

const getCoordinates = (
  targetRef: HTMLElement,
  direction: EDirectionOnboarding,
  onboardingRef: React.RefObject<HTMLDivElement>
): IBoardingCoordinates => {
  if (targetRef && onboardingRef.current) {
    switch (direction) {
      case EDirectionOnboarding.LEFT:
        return {
          top:
            targetRef.offsetTop +
            targetRef.offsetHeight / 2 -
            onboardingRef.current.offsetHeight / 2,
          left: targetRef.offsetLeft - onboardingRef.current.offsetWidth,
        };
      case EDirectionOnboarding.RIGHT:
        return {
          top:
            targetRef.offsetTop +
            targetRef.offsetHeight / 2 -
            onboardingRef.current.offsetHeight / 2,
          left: targetRef.offsetLeft + targetRef.offsetWidth,
        };
      case EDirectionOnboarding.TOP:
        return {
          top: targetRef.offsetTop - onboardingRef.current.offsetHeight,
          left:
            targetRef.offsetLeft +
            targetRef.offsetWidth / 2 -
            onboardingRef.current.offsetWidth / 2,
        };
      case EDirectionOnboarding.BOTTOM:
        return {
          top: targetRef.offsetTop + targetRef.offsetHeight,
          left:
            targetRef.offsetLeft +
            targetRef.offsetWidth / 2 -
            onboardingRef.current.offsetWidth / 2,
        };
    }
  }
  return {
    top: 0,
    left: 0,
  };
};

const getClassNameContainer = (
  direction: EDirectionOnboarding,
  showBackground: boolean,
  classNameContainer?: string
) => {
  return `${styles["onboarding-container"]} ${
    styles[`direction-${direction}`]
  } ${showBackground ? styles["background"] : ""} ${classNameContainer}`;
};

function Onboarding({
  targetRef,
  isShow,
  direction = EDirectionOnboarding.TOP,
  showBackground = false,
  classNameContainer = "",
  children,
}: OnboardingProps): JSX.Element {
  const onboardingRef = useRef<HTMLDivElement>(null);
  const [coordinates, setCoordinates] = useState<IBoardingCoordinates>({
    top: 0,
    left: 0,
  });
  useEffect(() => {
    if (!onboardingRef.current || !targetRef) {
      return;
    }
    setCoordinates(getCoordinates(targetRef, direction, onboardingRef));
  }, [direction, targetRef, children]);

  if (!isShow) {
    return <></>;
  }

  return (
    <div
      className={getClassNameContainer(
        direction,
        showBackground,
        classNameContainer
      )}
    >
      <div
        className={`${styles["onboarding"]} ${
          !targetRef || !onboardingRef.current ? styles["hide"] : ""
        }`}
        style={{ top: `${coordinates.top}px`, left: `${coordinates.left}px` }}
        ref={onboardingRef}
      >
        {children}
      </div>
    </div>
  );
}

export default Onboarding;
