import styled from '@emotion/styled';
import React, { useEffect, useRef } from 'react';

interface PopoutWrapperProps {
  popout: boolean;
  children: React.ReactNode;
  nested?: boolean;
  className?: string;
  style?: React.CSSProperties;
  positionContainerStyle?: React.CSSProperties;
  transparentBackground?: boolean;
}

const OriginalPositionContainer = styled.div`
  position: relative;
  width: 100%;
`;

const PopoutContainer = styled.div<{
  nested?: boolean;
  transparentBackground?: boolean;
  popout?: boolean;
}>`
  background: ${({ transparentBackground, popout }) => {
    if (transparentBackground) return 'transparent';
    if (popout)
      return 'linear-gradient(to bottom, var(--color-background-secondary), var(--color-background-primary))';
    return 'var(--color-background-fog-thin)';
  }};
  border-radius: ${({ nested }) => (nested ? '12px' : '16px')};
  padding: 0;
  display: flex;
  flex-direction: column;
  font-size: 14px;
  overflow: hidden;
  animation: fadeIn 0.3s ease-in-out;
`;

export const PopoutWrapper: React.FC<PopoutWrapperProps> = ({
  popout,
  children,
  nested = false,
  className,
  style,
  positionContainerStyle,
  transparentBackground = false,
}) => {
  const originalPositionRef = useRef<HTMLDivElement>(null);
  const popoutContainerRef = useRef<HTMLDivElement>(null);
  const resizeObserverRef = useRef<ResizeObserver | null>(null);
  const wasPoppedOutRef = useRef(popout);

  useEffect(() => {
    if (!originalPositionRef.current || !popoutContainerRef.current) return;

    const popoutBoundary =
      popoutContainerRef.current.closest('.card-popout-boundary') ||
      document.body;

    const popoutRounded = popoutBoundary.classList.contains('popout-rounded');
    const popoutBoundaryRect = popoutBoundary.getBoundingClientRect();

    // Clean up existing resize observer
    if (resizeObserverRef.current) {
      resizeObserverRef.current.disconnect();
      resizeObserverRef.current = null;
    }

    if (popout && !wasPoppedOutRef.current) {
      wasPoppedOutRef.current = true;
      const originalRect = originalPositionRef.current.getBoundingClientRect();
      originalPositionRef.current.style.height = `${originalRect.height}px`;
      originalPositionRef.current.style.zIndex = `10000`;

      popoutContainerRef.current.style.position = 'fixed';
      popoutContainerRef.current.style.left = `${originalRect.left}px`;
      popoutContainerRef.current.style.top = `${originalRect.top}px`;
      popoutContainerRef.current.style.width = `${originalRect.width}px`;
      popoutContainerRef.current.style.bottom = `${window.innerHeight - originalRect.bottom}px`;
      popoutContainerRef.current.style.borderRadius = `${nested ? '12px' : '16px'}`;

      popoutContainerRef.current.classList.add('transition-all');
      popoutContainerRef.current.classList.add('duration-300');
      popoutContainerRef.current.classList.add('ease-in-out');

      setTimeout(() => {
        if (!popoutContainerRef.current) return;
        popoutContainerRef.current.style.left = `${popoutBoundaryRect.left}px`;
        popoutContainerRef.current.style.top = `${popoutBoundaryRect.top}px`;
        popoutContainerRef.current.style.width = `${popoutBoundaryRect.width}px`;
        popoutContainerRef.current.style.bottom = `${window.innerHeight - popoutBoundaryRect.bottom}px`;
        if (popoutRounded) {
          popoutContainerRef.current.style.borderRadius = `16px`;
        } else {
          popoutContainerRef.current.style.borderRadius = `0px`;
        }
      });

      setTimeout(() => {
        if (!popoutContainerRef.current) return;
        popoutContainerRef.current.classList.remove('transition-all');
        popoutContainerRef.current.classList.remove('duration-300');
        popoutContainerRef.current.classList.remove('ease-in-out');
      }, 300);

      // Set up resize observer to continuously match the popout boundary size
      resizeObserverRef.current = new ResizeObserver(() => {
        if (!popoutContainerRef.current || !popout) return;
        const currentBoundaryRect = popoutBoundary.getBoundingClientRect();
        popoutContainerRef.current.style.left = `${currentBoundaryRect.left}px`;
        popoutContainerRef.current.style.top = `${currentBoundaryRect.top}px`;
        popoutContainerRef.current.style.width = `${currentBoundaryRect.width}px`;
        popoutContainerRef.current.style.bottom = `${window.innerHeight - currentBoundaryRect.bottom}px`;
      });
      resizeObserverRef.current.observe(popoutBoundary);
    } else if (!popout && wasPoppedOutRef.current) {
      wasPoppedOutRef.current = false;

      popoutContainerRef.current.classList.add('transition-all');
      popoutContainerRef.current.classList.add('duration-300');
      popoutContainerRef.current.classList.add('ease-in-out');

      const originalRect = originalPositionRef.current.getBoundingClientRect();
      popoutContainerRef.current.style.left = `${originalRect.left}px`;
      popoutContainerRef.current.style.top = `${originalRect.top}px`;
      popoutContainerRef.current.style.width = `${originalRect.width}px`;
      popoutContainerRef.current.style.bottom = `${window.innerHeight - originalRect.bottom}px`;
      popoutContainerRef.current.style.borderRadius = `${nested ? '12px' : '16px'}`;

      setTimeout(() => {
        if (!originalPositionRef.current || !popoutContainerRef.current) return;

        originalPositionRef.current.style.zIndex = ``;
        originalPositionRef.current.style.height = ``;

        popoutContainerRef.current.style.borderRadius = ``;
        popoutContainerRef.current.style.position = 'relative';
        popoutContainerRef.current.style.left = ``;
        popoutContainerRef.current.style.top = ``;
        popoutContainerRef.current.style.width = ``;
        popoutContainerRef.current.style.bottom = ``;

        popoutContainerRef.current.classList.remove('transition-all');
        popoutContainerRef.current.classList.remove('duration-300');
        popoutContainerRef.current.classList.remove('ease-in-out');
      }, 300);
    }

    // Cleanup function to disconnect resize observer
    return () => {
      if (resizeObserverRef.current) {
        resizeObserverRef.current.disconnect();
        resizeObserverRef.current = null;
      }
    };
  }, [popout, nested, wasPoppedOutRef]);

  return (
    <OriginalPositionContainer
      ref={originalPositionRef}
      style={positionContainerStyle}
    >
      <PopoutContainer
        ref={popoutContainerRef}
        className={className}
        style={style}
        nested={nested}
        transparentBackground={transparentBackground}
        popout={popout}
      >
        {children}
      </PopoutContainer>
    </OriginalPositionContainer>
  );
};

export default PopoutWrapper;
