import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";
import { usePopper } from "react-popper";
import styled from "styled-components";
import { editingCellContext } from "../context/EditorContext";
import { hoveredCellContext } from "../context/hoveredCellContext";
import { isSelectingContext } from "../context/SelectionContext";

const HOVER_DELAY_MS = 500;

/**
 * This positions the error tooltips on the correct cell. The same component is
 * reused for every cell, so only one error tooltip can ever be present
 */
export const ErrorTooltip = <TError extends unknown>({
  renderErrorTooltip,
  errors,
}: {
  renderErrorTooltip: (error: TError) => React.ReactNode;
  errors: (TError | null)[][];
}) => {
  const { el, x, y } = hoveredCellContext.useState() ?? {};
  const isSelecting = isSelectingContext.useState();
  const editingCell = editingCellContext.useState();
  const [tooltipElement, setTooltipElement] = useState<HTMLDivElement | null>(
    null
  );
  const errorData = x !== undefined && y !== undefined ? errors[y][x] : null;
  const error = editingCell ? null : errorData;
  const { styles, attributes } = usePopper(error ? el : null, tooltipElement, {
    placement: "bottom-start",
  });

  const [visible, setVisible] = useState(false);
  useEffect(() => {
    setVisible(false);
    if (error) {
      const timeout = setTimeout(() => setVisible(true), HOVER_DELAY_MS);
      return () => clearTimeout(timeout);
    }
    return;
  }, [error, x, y, isSelecting]);

  return ReactDOM.createPortal(
    <TooltipContainer
      style={styles.popper}
      {...attributes}
      ref={setTooltipElement}
      visible={!!error && visible && !isSelecting}
    >
      {error && x !== undefined && renderErrorTooltip(error)}
    </TooltipContainer>,
    document.body
  );
};

const TooltipContainer = styled.div<{ visible: boolean }>`
  display: ${({ visible }) => (visible ? "block" : "none")};
  z-index: 10;
`;
