import styled from '@emotion/styled';
import { RefObject, useCallback, useEffect, useRef, useState } from 'react';

import useClickDrag from '@/hooks/useClickDrag';

export const RESIZABLE_CONTAINER_CLASS_NAME = `useResizer-resizable-container`;

export const ResizerHandle = styled.div`
  position: absolute;
  bottom: 4px;
  left: 50%;
  transform: translateX(-50%);
  width: 48px;
  height: 4px;
  border-radius: 4px;
  cursor: ns-resize;
  background-color: var(--color-foreground-inactive);
  z-index: 100;

  opacity: 0;
  transition: opacity 0.15s ease-in-out;

  &:before {
    content: '';
    display: block;
    position: absolute;
    top: -4px;
    bottom: -4px;
    left: -4px;
    right: -4px;
    opacity: 0;
  }

  .${RESIZABLE_CONTAINER_CLASS_NAME}:hover &,
  &.dragging {
    opacity: 1;
  }

  &.dragging {
    background-color: var(--color-foreground-tertiary);
  }
`;

export default function useResizer({
  height,
  setHeight,
  minHeight = 0,
  maxHeight = Infinity,
  fullHeight,
  resizeTargetRef,
}: {
  height: number;
  setHeight?: (height: number) => void;
  minHeight?: number;
  maxHeight?: number;
  fullHeight?: boolean;
  resizeTargetRef: RefObject<HTMLElement | null>;
}) {
  const [isResizing, setIsResizing] = useState(false);

  // Handle external height changes with smooth animation
  useEffect(() => {
    if (!isResizing && !fullHeight) {
      if (resizeTargetRef.current) {
        resizeTargetRef.current.classList.add(
          'transition-all',
          'duration-300',
          'ease-out'
        );
      }
      const timer = setTimeout(() => {
        if (resizeTargetRef.current) {
          resizeTargetRef.current.classList.remove(
            'transition-all',
            'duration-300',
            'ease-out'
          );
        }
      }, 300); // Match transition duration

      setTimeout(() => {
        if (resizeTargetRef.current) {
          resizeTargetRef.current.style.height = `${height}px`;
        }
      }, 0);

      return () => clearTimeout(timer);
    }

    if (fullHeight) {
      if (!resizeTargetRef.current) return;

      setTimeout(() => {
        if (resizeTargetRef.current) {
          resizeTargetRef.current.style.height = '100%';
        }
      });
    }
  }, [height, isResizing, fullHeight]);

  const resizerHandleRef = useRef<HTMLDivElement>(null);

  // Handle drag for resizing
  const receiveClickDragRef = useClickDrag(
    useCallback(() => {
      if (!setHeight) return;

      if (resizeTargetRef.current) {
        resizeTargetRef.current.classList.remove(
          'transition-all',
          'duration-300',
          'ease-out'
        );
      }

      if (resizerHandleRef.current) {
        resizerHandleRef.current.classList.add('dragging');
      }

      setIsResizing(true);

      let newHeight = height;

      return {
        onMouseMove: ({ deltaYFromStart }) => {
          newHeight = Math.min(
            Math.max(minHeight, height + deltaYFromStart),
            maxHeight
          );

          if (resizeTargetRef.current) {
            resizeTargetRef.current.style.height = `${newHeight}px`;
          }
        },
        onMouseUp: () => {
          setIsResizing(false);
          setHeight(newHeight);

          if (resizerHandleRef.current) {
            resizerHandleRef.current.classList.remove('dragging');
          }
        },
      };
    }, [height, setHeight, minHeight, maxHeight])
  );

  const receiveResizerRef = useCallback(
    (ref: HTMLDivElement | null) => {
      resizerHandleRef.current = ref;
      receiveClickDragRef(ref);
    },
    [receiveClickDragRef]
  );

  return receiveResizerRef;
}
