"use client";

import {
  useEffect,
  useRef,
  useState,
  cloneElement,
  isValidElement,
  ReactElement,
  useCallback,
} from "react";

type ToggleSectionProps = {
  id: string;
  showText: boolean;
  showBadge: boolean;
  countBadge: number;
  buttonText: string;
  iconName: string;
  children:
    | React.ReactNode
    | ((props: { onClose: () => void }) => React.ReactNode); 
  onCloseExternal?: () => void;
};

export const ToggleSection = ({
  id,
  showText,
  showBadge,
  countBadge,
  buttonText,
  iconName,
  children,
  onCloseExternal,
}: ToggleSectionProps) => {
  const [isOpen, setIsOpen] = useState(false);
  const wrapperRef = useRef<HTMLDivElement>(null);
  const [isScrollLocked, setIsScrollLocked] = useState(false);

  const handleClose = useCallback(() => {
    setIsOpen(false);
    setIsScrollLocked(false);
    document.body.style.overflow = "auto";
    if (onCloseExternal) onCloseExternal();
  }, [onCloseExternal]);

  const handleClickOutside = useCallback(
    (event: MouseEvent) => {
      if (
        wrapperRef.current &&
        !wrapperRef.current.contains(event.target as Node)
      ) {
        handleClose();
      }
    },
    [handleClose],
  );

  useEffect(() => {
    if (isOpen) {
      document.addEventListener("mousedown", handleClickOutside);
    }
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [isOpen, handleClickOutside]);

  const toggleScrollLock = () => {
    if (isScrollLocked) {
      document.body.style.overflow = "auto";
    } else {
      document.body.style.overflow = "auto";
    }
    setIsScrollLocked(!isScrollLocked);
    setIsOpen(!isOpen);
  };

  useEffect(() => {
    return () => {
      document.body.style.overflow = "auto";
    };
  }, []);

  useEffect(() => {
    const handleCloseAll = () => handleClose();
    window.addEventListener("close-all-toggles", handleCloseAll);
    return () =>
      window.removeEventListener("close-all-toggles", handleCloseAll);
  }, [handleClose]);

  let childrenWithProps: React.ReactNode;
  if (typeof children === "function") {
    childrenWithProps = children({ onClose: handleClose });
  } else if (isValidElement(children)) {
    childrenWithProps = cloneElement(children as ReactElement<any>, {
      onClose: handleClose,
    });
  } else {
    childrenWithProps = children;
  }

  return (
    <div ref={wrapperRef} className="relative">
      <button
        onClick={toggleScrollLock}
        aria-label={buttonText}
        className="m-0 flex h-10 w-10 flex-row items-center justify-center p-0 align-middle"
      >
        <span className="flex flex-col items-center justify-center align-middle">
          <i className={iconName}></i>
        </span>
        {showText && <span className="text-xs uppercase">{buttonText}</span>}
        {showBadge && (
          <i className="flex-inline absolute top-[2px] -right-1 rounded-full bg-gray-950 p-1 text-xs/2 font-medium text-white not-italic">
            {countBadge}
          </i>
        )}
      </button>

      {isOpen && <div>{childrenWithProps}</div>}
    </div>
  );
};
