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 { AdsClickIcon } from '../Icons/AdsClickIcon';
import { ArrowDownIcon } from '../Icons/ArrowDownIcon';

export default function BrowseToSource({
    sources,
    selectedSource,
    onSourceSelect,
    className = '',
}: {
    sources: ResourceBrowserSource[];
    selectedSource: ResourceBrowserSource;
    onSourceSelect(source: ResourceBrowserSource, mode?: PluginLaunchMode): void;
    className?: string;
}): React.JSX.Element {
    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
            className={`inline-block ${isOpen ? 'flex items-center border-2 border-gray-200 rounded-lg px-1 py-0.5 w-[320px]' : 'p-0'} ${className}`}
        >
            {isOpen && <AdsClickIcon aria-hidden className="ml-1 mr-2 shrink-0" />}
            {sources.length >= 1 && (
                <div {...focusWithinProps} {...keyboardProps} className={`relative w-full ${isOpen && 'border-l border-gray-400 pl-1 '}`}>
                    <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-lg ${!isOpen && 'border-2 border-gray-200 hover:bg-gray-100'}`}
                    >
                        {isOpen ? (
                            <>
                                <span className="text-gray-700 text-md leading-5 mr-2">Browse to ...</span>
                                <ArrowDownIcon aria-hidden className="absolute right-3" />
                            </>
                        ) : (
                            <>
                                <AdsClickIcon aria-hidden className="ml-[6px] mr-2" />
                                <span className="text-gray-700 text-md font-semibold leading-5 mr-[6px]">Browse</span>
                            </>
                        )}
                    </button>
                    <ul
                        id={`${uniqueId}-button-menu`}
                        aria-hidden={!isOpen}
                        className={`absolute z-50 top-[calc(100%+8px)] left-1 w-[calc(100%-2px)] bg-gray-100 border-1 shadow-md rounded border-gray-300 p-2 pb-0 overflow-y-auto 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>
            )}
        </div>
    );
}
