import React, { useCallback, useState } from 'react';
import { DOMAttributes, FocusableElement } from '@react-types/shared';

import SourceList from '../SourceList/SourceList';
import ResourceLauncher from '../ResourceLauncher/ResourceLauncher';
import SourceDropdownContainer from '../SourceDropdownContainer/SourceDropdownContainer';
import SourceDropdown from '../SourceDropdown/SourceDropdown';
import {
    ResourceBrowserPlugin,
    ResourceBrowserSource,
    ResourceBrowserResource,
    ResourceBrowserSourceWithPlugin,
    PluginLaunchMode,
    PluginLaunchModeType,
    ResourceBrowserSearchUIArgs,
    ResourceBrowserUIArgs,
} from '../types';

interface MainContainerProps {
    title: string;
    titleAriaProps: DOMAttributes<FocusableElement>;
    allowedTypes: string[] | undefined;
    sources: ResourceBrowserSourceWithPlugin[];
    selectedSource: ResourceBrowserSource | null;
    onSourceSelect(source: ResourceBrowserSource, mode?: PluginLaunchMode): void;
    onChange(resource: ResourceBrowserResource | null): void;
    onClose: () => void;
    preselectedResource?: ResourceBrowserResource | null;
    plugin: ResourceBrowserPlugin | null;
    pluginMode: PluginLaunchMode | null;
    searchEnabled: boolean;
}

function MainContainer({
    title,
    titleAriaProps,
    allowedTypes,
    sources,
    selectedSource,
    onSourceSelect,
    onChange,
    onClose,
    preselectedResource,
    plugin,
    pluginMode,
    searchEnabled,
}: MainContainerProps) {
    const [headerPortal, setHeaderPortal] = useState<HTMLDivElement | null>(null);
    const pluginToRender = pluginMode ? pluginMode.type : PluginLaunchModeType.Browse; // Cant default a 'null' property in signature so set it here
    const SourceBrowser = plugin?.sourceBrowserComponent();
    const SourceSearch = plugin?.sourceSearchComponent();

    // Can't use a useRef as it wont update on change when a source is selected, so need to use a ref callback to store in state
    const setHeaderPortalRef = useCallback(
        (node: HTMLDivElement) => {
            if (node !== null) {
                setHeaderPortal(node);
            }
        },
        [setHeaderPortal],
    );

    // MainContainer will either render the source list view if no source is set or the plugins UI if a source has been selected
    return (
        <div className="relative flex flex-col h-full text-gray-800">
            <div className="flex items-center py-3 pl-6 pr-10 min-h-[68px]">
                <h2 {...titleAriaProps} className="text-xl leading-6 text-gray-800 font-semibold mr-6">
                    {title?.charAt(0).toUpperCase() + title?.slice(1).toLowerCase()}
                </h2>

                {plugin && selectedSource && (
                    <>
                        {/* Custom header if plugin supports it */}
                        {plugin.createHeaderPortal && <div ref={setHeaderPortalRef} className="squiz-rb-plugin"></div>}
                        {/* Default header if plugin does not support */}
                        {!plugin.createHeaderPortal && sources.length > 1 && (
                            <SourceDropdownContainer isCollapsed={false} onExpand={() => {}}>
                                <div className={`border-l border-blue-200 pl-1 w-[204px]`}>
                                    <SourceDropdown sources={sources} selectedSource={selectedSource} onSourceSelect={onSourceSelect} />
                                </div>
                            </SourceDropdownContainer>
                        )}
                    </>
                )}

                <div className="flex gap-3 p-3 absolute right-0 top-0">
                    <button
                        type="button"
                        aria-label={`Close ${title} dialog`}
                        onClick={onClose}
                        className="border-0 bg-transparent cursor-pointer p-0 relative"
                    >
                        <svg
                            height="24px"
                            viewBox="0 0 24 24"
                            width="24px"
                            xmlns="http://www.w3.org/2000/svg"
                            className="text-gray-600 hover:text-gray-800 fill-current"
                        >
                            <path d="M0 0h24v24H0V0z" fill="none"></path>
                            <path d="M18.3 5.71c-.39-.39-1.02-.39-1.41 0L12 10.59 7.11 5.7c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41L10.59 12 5.7 16.89c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0L12 13.41l4.89 4.89c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4z"></path>
                        </svg>
                    </button>
                </div>
            </div>
            <div className="border-t border-gray-300 overflow-y-hidden">
                {plugin && selectedSource && (
                    <div className={`squiz-rb-plugin squiz-rb-plugin--${pluginMode?.type}`}>
                        {pluginToRender === PluginLaunchModeType.Browse && SourceBrowser && (
                            <SourceBrowser
                                source={selectedSource}
                                sources={sources}
                                onSourceSelect={onSourceSelect}
                                allowedTypes={allowedTypes}
                                headerPortal={plugin.createHeaderPortal && headerPortal ? headerPortal : undefined}
                                searchEnabled={searchEnabled}
                                preselectedResource={preselectedResource || undefined}
                                browseTo={(pluginMode?.args as ResourceBrowserUIArgs)?.browseTo}
                                onSelected={(resource: ResourceBrowserResource) => {
                                    onChange(resource);
                                    onClose();
                                }}
                            />
                        )}
                        {pluginToRender === PluginLaunchModeType.Search && SourceSearch && (
                            <SourceSearch
                                source={selectedSource}
                                sources={sources}
                                onSourceSelect={onSourceSelect}
                                allowedTypes={allowedTypes}
                                headerPortal={plugin.createHeaderPortal && headerPortal ? headerPortal : undefined}
                                searchEnabled={searchEnabled}
                                query={(pluginMode?.args as ResourceBrowserSearchUIArgs)?.query}
                                onSelected={(resource: ResourceBrowserResource) => {
                                    onChange(resource);
                                    onClose();
                                }}
                            />
                        )}
                    </div>
                )}
                {!selectedSource && searchEnabled && <ResourceLauncher sources={sources} onSourceSelect={onSourceSelect} />}
                {!selectedSource && !searchEnabled && <SourceList sources={sources} onSourceSelect={onSourceSelect} />}
            </div>
        </div>
    );
}

export default MainContainer;
