import React, { useCallback, useEffect, useLayoutEffect, useRef } from "react";
import classNames from "classnames";
import { NotificationType, NotificationTypeMap } from "ui/domain/types";
import { ReactComponent as SVGLockIcon } from "assets/svg/lock.svg";

type Props = {
  title?: string;
  delay?: number;
  children: React.ReactNode;
  onClose: VoidFunction;
  type?: NotificationType;
};

const styling: NotificationTypeMap<string> = {
  error: "bg-red-500 text-red-800",
  success: "bg-emerald-800 text-white",
  warning: "bg-yellow-500 text-yellow-900",
};

const icon: NotificationTypeMap<React.ReactElement> = {
  error: (
    <div className="basis-12 bg-red-300/50 w-12 h-12 flex justify-center items-center rounded-md text-lg leading-[48px] p-3">
      <SVGLockIcon className="stroke-red-700 w-full h-full" />
    </div>
  ),
  success: (
    <div className="basis-12 bg-white/50 w-12 h-12 flex justify-center items-center rounded-md text-lg leading-[48px] p-3">
      <SVGLockIcon className="stroke-emerald-900 w-full h-full" />
    </div>
  ),
  warning: (
    <div className="basis-12 bg-red-300/50 w-12 h-12 flex justify-center items-center rounded-md text-lg leading-[48px] p-3">
      <SVGLockIcon className="stroke-red-700 w-full h-full" />
    </div>
  ),
};

const Notification = ({ title, type, delay, ...props }: Props) => {
  const notifRef = useRef<HTMLDivElement>(null);

  const clickHandler = (e: React.MouseEvent) => {
    e.preventDefault();
    hideNotification();
    setTimeout(() => {
      props.onClose && props.onClose();
    }, 500);
  };

  const hideNotification = useCallback(() => {
    const notification = notifRef.current;
    if (!notification) return;
    const parent = notification.parentElement;
    parent!.style.height = "0px";
    parent!.style.opacity = "0";
  }, [notifRef]);

  useLayoutEffect(() => {
    const notification = notifRef.current;
    if (!notification) {
      return;
    }
    console.log(notification);
    const height = notification.clientHeight;
    const parent = notification.parentElement;
    parent!.style.height = height + "px";
    parent!.style.opacity = "1";
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [notifRef, notifRef.current]);

  useEffect(() => {
    let handler: NodeJS.Timeout | null = null;
    if (delay) {
      handler = setTimeout(() => {
        hideNotification();
      }, delay);
    }
    return () => {
      handler && clearTimeout(handler);
    };
  }, [delay, hideNotification]);

  return (
    <div
      onClick={(e) => clickHandler(e)}
      className={classNames(
        "overflow-hidden opacity-0 w-full h-0 rounded-md mb-2 transition-all shadow-md cursor-pointer",
        {
          "bg-serv-600 hover:bg-serv-500": !type,
          [`${styling[type ?? "error"]}`]: type,
        }
      )}
    >
      <div ref={notifRef} className="flex items-center px-4">
        {type && icon[type]}
        <div className="relative w-full px-4 py-3 flex-grow">
          {title && (
            <div className="flex items-center font-bold transition-colors leading-5">
              {title}
            </div>
          )}
          {!!props.children && (
            <div className="text-sm leading-4">{props.children}</div>
          )}
        </div>
      </div>
    </div>
  );
};

export default Notification;
