import * as Ariakit from '@ariakit/react';
import { getClassNames } from '@websolutespa/bom-core';
import { forwardRef, ReactNode, useContext, useEffect, useState } from 'react';
import styled from 'styled-components';
import { getVariantKey } from '../../variants';
import { ComboboxContext } from './combobox.context';
import { comboboxVariants, IComboboxVariants } from './combobox.variants';

const ComboboxPopoverStyle = styled(Ariakit.ComboboxPopover) <ComboboxPopoverProps>`
  ${props => getVariantKey('popover', props.variant, props.variants)}
`;

export type ComboboxPopoverProps = Ariakit.ComboboxPopoverProps & {
  variant?: keyof typeof comboboxVariants | (string & {});
  variants?: IComboboxVariants;
  renderOptions?: (value?: string) => ReactNode;
};

export const ComboboxPopover = forwardRef<HTMLDivElement, ComboboxPopoverProps>(
  function ComboboxPopover({
    variant,
    variants,
    className,
    renderOptions,
    children,
    ...props
  }: ComboboxPopoverProps, ref) {
    const [nodes, setNodes] = useState<ReactNode>();
    const store = Ariakit.useComboboxContext();
    const value = Ariakit.useStoreState(store, 'value');
    const context = useContext(ComboboxContext);
    useEffect(() => {
      if (renderOptions) {
        const promise = async () => {
          return await renderOptions(value);
        };
        promise().then((nodes) => setNodes(nodes));
      }
    }, [value, renderOptions]);
    if (!context) {
      return;
    }
    const classNames = getClassNames('combobox__popover', className);
    return (
      <ComboboxPopoverStyle
        ref={ref}
        className={classNames}
        variant={variant || context.variant}
        variants={variants || context.variants}
        getAnchorRect={(anchor: HTMLElement | null) => {
          return anchor?.parentElement?.parentElement?.getBoundingClientRect() || null;
        }}
        {...props}
      >
        {renderOptions ? (
          nodes
        ) : (
          children
        )}
      </ComboboxPopoverStyle>
    );
  });
