// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { ComboboxProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import { useId } from "@coreai-ds/react-components";
import { useStaticVirtualizerMeasure } from "@fluentui/react-components/unstable";
import * as React from 'react';
import { makeStyles } from "@coreai-ds/react-components";
import { useMergedRefs } from "@coreai-ds/react-components";
import { useTimeout } from "@coreai-ds/react-components";
import { Combobox } from "@coreai-ds/react-components";
import { Virtualizer } from "@fluentui/react-components/unstable";
import { Option } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    listbox: {
        // maxHeight will be applied only positioning autoSize set.
        maxHeight: '250px',
    },
    option: {
        height: '32px',
    },
});

export const ComboboxVirtualizer = (props: Partial<Omit<ComboboxProps, "label" | "dynamicWidth">>): JSXElement => {
    const comboId = useId('combobox');
    //This should include the item height (32px) and account for rowGap (2px)
    const itemHeight = 32;
    const rowGap = 2;
    const numberOfItems = 10000;
    const { virtualizerLength, bufferItems, bufferSize, scrollRef, containerSizeRef } = useStaticVirtualizerMeasure({
        defaultItemSize: itemHeight,
        direction: 'vertical',
        // We want at least 10 additional items on each side of visible items for page up/down (+ 1 buffer)
        bufferItems: 11,
        // We need to recalculate index when at least 10 items (+1px) from the bottom or top for page up/down
        bufferSize: itemHeight * 10 + 1,
    });
    const selectedIndex = React.useRef(0);
    const styles = useStyles();
    const mergedRefs = useMergedRefs(scrollRef);
    // Scroll timer required to post scrollTo on stack post-open state change
    const [setScrollTimer, clearScrollTimer] = useTimeout();
    return (<div>
      <div>
        <label htmlFor={`${comboId}`}>Medium</label>
        <Combobox id={`${comboId}`} placeholder="Select a number" positioning={{ autoSize: true }} listbox={{ ref: mergedRefs, className: styles.listbox }} onOpenChange={(e, data) => {
            clearScrollTimer();
            if (data.open) {
                setScrollTimer(() => {
                    mergedRefs.current?.scrollTo({ top: (itemHeight + rowGap) * selectedIndex.current });
                }, 0);
            }
        }} onOptionSelect={(e, data) => {
            if (data.optionValue) {
                selectedIndex.current = parseInt(data.optionValue, 10);
            }
        }}>
          <Virtualizer numItems={numberOfItems} virtualizerLength={virtualizerLength} bufferItems={bufferItems} bufferSize={bufferSize} itemSize={itemHeight} containerSizeRef={containerSizeRef} gap={rowGap}>
            {index => {
            return (<Option className={styles.option} aria-posinset={index} aria-setsize={numberOfItems} key={`item-${index}`} value={index.toString()}>
                  {`Item ${index + 1}`}
                </Option>);
        }}
          </Virtualizer>
        </Combobox>
      </div>
    </div>);
};

export default ComboboxVirtualizer;
