import React, { useRef, useState } from 'react';

import { ResourceBrowserSource, PluginLaunchMode } from '../types';
import { Icon, IconOptions, uuid } from '@squiz/generic-browser-lib';
import { useFocusWithin, useKeyboard } from 'react-aria';
import { ArrowDownIcon } from '../Icons/ArrowDownIcon';

export default function SourceDropdown({
    sources,
    selectedSource,
    onSourceSelect,
}: {
    sources: ResourceBrowserSource[];
    selectedSource: ResourceBrowserSource;
    onSourceSelect(source: ResourceBrowserSource, mode?: PluginLaunchMode): void;
}) {
    const [uniqueId] = useState(uuid());
    const buttonRef = useRef<HTMLButtonElement>(null);
    const [isOpen, setIsOpen] = useState(false);

    // Watch the focus and blur on the menu and close if focus leaves the control
    const { focusWithinProps } = useFocusWithin({
        onBlurWithin: () => {
            setIsOpen(false);
        },
    });

    // Listen for Esc key within this element
    const { keyboardProps } = useKeyboard({
        onKeyDown: (e) => {
            if (isOpen && e.key === 'Escape') {
                setIsOpen(false);
                buttonRef.current?.focus(); // Restore focus to the element which opened the menu
            }
        },
    });

    const handleSourceClick = (source: ResourceBrowserSource) => {
        setIsOpen(false);
        buttonRef.current?.focus();
        onSourceSelect(source);
    };

    if (!sources.length) {
        return <></>;
    }

    return (
        <div {...focusWithinProps} {...keyboardProps} className="relative w-full ">
            <button
                ref={buttonRef}
                type="button"
                aria-label="Source quick select"
                aria-expanded={isOpen}
                aria-controls={`${uniqueId}-button-menu`}
                onClick={() => setIsOpen(!isOpen)}
                className="relative flex items-center p-2 w-full rounded bg-blue-100"
            >
                <span className="sr-only">current source </span>
                <div className="truncate max-w-[200px] text-md font-semibold text-blue-400">{selectedSource.name}</div>
                <ArrowDownIcon aria-hidden className="absolute right-2 fill-blue-300" />
            </button>
            <ul
                id={`${uniqueId}-button-menu`}
                aria-hidden={!isOpen}
                className={`absolute z-50 top-[calc(100%+8px)] w-[100%] bg-gray-100 border-1 shadow-md rounded border-gray-300 p-2 pb-0 overflow-y-scroll max-h-80 ${
                    !isOpen ? 'hidden' : ''
                }`}
            >
                {sources.map((source) => {
                    const { id, name, type } = source;
                    const isSelectedSource = id === selectedSource.id;

                    return (
                        <li key={id} className="flex items-center text-sm font-semibold mb-2 bg-white rounded">
                            <button
                                type="button"
                                onClick={() => handleSourceClick(source)}
                                className={`relative grow flex items-center p-2 border-1 border-white rounded hover:bg-gray-50 hover:border-gray-300 focus:bg-gray-100`}
                            >
                                <Icon icon={type as IconOptions} aria-label={type} className="shrink-0 mr-2.5" />
                                <span className="text-left mr-7">{name}</span>
                                {isSelectedSource && (
                                    <Icon icon={'selected' as IconOptions} aria-label="selected" className="absolute right-4" />
                                )}
                            </button>
                        </li>
                    );
                })}
            </ul>
        </div>
    );
}
