import { useRef, useEffect, useState, useCallback } from '@wordpress/element';
import SizeIcon from 'blockbite-icons/dist/Size';
import useMousePosition from './useMousePosition';
import {
  getNewDesignClasses,
  getMergedDesignList,
} from '@components/DesignPanel/Helpers';
import { BiteStyleProps } from '@components/DesignPanel/types';
import has from 'lodash/has';

export type mousePositionProps = {
  x: number;
  y: number;
};

export type AreaResizeProps = {
  currentResponsive: string;
  flexStyle: BiteStyleProps[];
  setAttributes: (attributes: any) => void;
};

export default function AreaBlock({
  flexStyle,
  setAttributes,
}: AreaResizeProps) {
  const ref = useRef<HTMLDivElement>(null);
  const resizeHandleRef = useRef<HTMLButtonElement>(null);

  const [isResizing, setIsResizing] = useState(false);

  const [position, setPosition] = useState({
    h: 100, // Start with a minimum height of 100px
    y: null,
  });
  const [initialPosition, setInitialPosition] = useState({
    y: null,
    h: 100, // Start with minimum height for reference
  });

  const mousePosition = useMousePosition();

  /* Initialize block position */
  useEffect(() => {
    const { parentHeight } = getParentCoordinates();
    // get the current height from the design list
    const currentBlock = flexStyle.find((style) => style.id === 'flexheight');

    let currentHeight = 0;
    // if default set it as a flexStyle
    if (has(currentBlock, 'value')) {
      // parse number out of min-h-[640px]
      const height = currentBlock.value.match(/\d+/);
      currentHeight = height ? parseInt(height[0]) : 100;
    } else {
      currentHeight = 50;
    }
    if (currentHeight < parentHeight) {
      currentHeight = parentHeight;
    }

    update(currentHeight);

    setPosition({
      h: currentHeight,
      y: 0,
    });
  }, []);

  /* Update block height on mouse move if resizing */
  useEffect(() => {
    if (isResizing) {
      handleResize(mousePosition);
    }
  }, [mousePosition.y]);

  const handleMouseUp = useCallback(() => {
    setIsResizing(false);
  }, []);

  useEffect(() => {
    if (isResizing) {
      document.addEventListener('mouseup', handleMouseUp);
    } else {
      document.removeEventListener('mouseup', handleMouseUp);
    }
    return () => {
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isResizing, handleMouseUp]);

  const setHandleResize = useCallback(
    (e: React.MouseEvent) => {
      // Only handle left mouse button
      if (e.button !== 0) return;

      const { parentTop } = getParentCoordinates();

      setInitialPosition({
        y: mousePosition.y - parentTop,
        h: position.h,
      });

      setIsResizing(true);
    },
    [mousePosition.y]
  );

  const handleResize = (mousePosition: mousePositionProps) => {
    const { parentTop } = getParentCoordinates(); // Only get parentTop for offset

    const mouseY = mousePosition.y - parentTop;

    // Calculate the new height, ensuring only a minimum of 100px
    const newHeight = Math.max(
      initialPosition.h + (mouseY - initialPosition.y),
      100
    );

    setPosition((prev) => ({
      ...prev,
      h: newHeight,
    }));

    update(newHeight);
  };

  const getParentCoordinates = () => {
    return {
      parentHeight: ref.current?.parentElement?.offsetHeight || 0,
      parentTop: ref.current?.parentElement?.getBoundingClientRect().top || 0,
    };
  };

  const update = (newHeight: number) => {
    // only update the height in the design list for desktop
    const newList = [
      {
        id: 'flexheight',
        value: `[${Math.round(newHeight)}px]`,
        screen: 'xl',
      },
    ];

    const newDesign = getMergedDesignList(newList, flexStyle);

    // Get the new class
    const newClass = getNewDesignClasses(newDesign);

    setAttributes({
      flexStyle: newDesign,
      flexClass: newClass,
    });
  };

  return (
    <div
      ref={ref}
      style={{
        top: `${position.y ?? 0}%`,
        height: `${position.h}px`,
        position: 'absolute',
        left: '50%',
        transform: 'translateX(-50%)',
      }}
      className="relative"
    >
      {/* Drag handle button positioned at the bottom center */}
      <button
        ref={resizeHandleRef}
        title="Resize block"
        onMouseDown={setHandleResize}
        className="resize-handle absolute bottom-0 left-1/2 z-10 -translate-x-1/2 transform cursor-ns-resize bg-white/50 p-2 group-hover:opacity-100 hover:bg-white"
      >
        <SizeIcon className="scale-x-[-1]" />
      </button>
    </div>
  );
}
