import React, { useEffect, useRef, useState, type ReactNode } from 'react';
import styled, { css } from 'styled-components';

const Container = styled.div<{ $height?: number; $fill?: boolean }>`
  width: 100%;
  min-width: 0;
  min-height: 0;

  ${({ $fill, $height }) =>
    $fill
      ? css`
          flex: 1;
          height: 100%;
          min-height: 120px;
        `
      : css`
          height: ${$height}px;
        `}
`;

export interface ChartSize {
  width: number;
  height: number;
}

interface ChartResponsiveContainerProps {
  height?: number;
  fill?: boolean;
  children: (size: ChartSize) => ReactNode;
}

/**
 * Measures the container and passes numeric width/height to charts.
 * Avoids Recharts ResponsiveContainer, which logs width/height -1 in flex layouts.
 */
export const ChartResponsiveContainer: React.FC<ChartResponsiveContainerProps> = ({
  height = 260,
  fill = false,
  children,
}) => {
  const ref = useRef<HTMLDivElement>(null);
  const [size, setSize] = useState<ChartSize | null>(null);

  useEffect(() => {
    const element = ref.current;
    if (!element) {
      return;
    }

    const measure = () => {
      const { width, height: measuredHeight } = element.getBoundingClientRect();
      const w = Math.floor(width);
      const h = Math.floor(measuredHeight);
      if (w > 0 && h > 0) {
        setSize({ width: w, height: h });
      }
    };

    measure();

    if (typeof ResizeObserver === 'undefined') {
      setSize({ width: 400, height });
      return;
    }

    const observer = new ResizeObserver(() => {
      requestAnimationFrame(measure);
    });
    observer.observe(element);
    return () => observer.disconnect();
  }, [height, fill]);

  return (
    <Container ref={ref} $height={height} $fill={fill}>
      {size ? children(size) : null}
    </Container>
  );
};
