import React, { type FC, useCallback, useMemo } from 'react';
import { Select } from '@theorchard/suite-components';
import { useCompositionsQuery } from 'src/data/queries/compositions/compositions';
import { useCompositionsSearchQuery } from 'src/data/queries/compositionSearch';
import type { Composition } from 'src/data/types';

export const CLASSNAME = 'CompositionSearchDropdown';

export interface Props {
    compositionId?: string;
    disabled?: boolean;
    menuWidth?: string;
    onChange: (data?: Composition) => void;
    placeholder: string;
    testId?: string;
}

export interface DropdownOption<T> {
    label: string;
    value: string;
    subtitle?: string;
    data?: T;
}

const CompositionSearchDropdown: FC<Props> = props => {
    const { compositionId, disabled, onChange, placeholder, testId } = props;
    const { data: compositionData } = useCompositionsQuery();
    const [executeSearch] = useCompositionsSearchQuery();

    const createOption = (
        composition: Composition
    ): DropdownOption<Composition> => ({
        label: `${composition.title}`,
        value: `${composition.id}`,
        subtitle: `${composition.pubSongId.toString()} · ${
            composition.vendorName
        }`,
        data: composition,
    });

    const compositionOptions = useMemo<DropdownOption<Composition>[]>(
        () => [...(compositionData ?? [])].map(createOption),
        [compositionData]
    );

    const onChangeHandler = useCallback(
        (newValue?: DropdownOption<Composition>) => {
            onChange(newValue?.data);
        },
        [onChange]
    );

    const onLoadOptionsHandler = async (searchParam?: string) => {
        let searchCompositionsData: Composition[] = [];
        const searchParamIsNumber = !isNaN(Number(searchParam));
        if (searchParam) {
            searchCompositionsData =
                (await executeSearch({
                    variables: {
                        filter: {
                            titleSearch: searchParam,
                            draft: false,
                            titleAndSongIdSearch: searchParamIsNumber,
                        },
                    },
                })) || [];

            return { data: searchCompositionsData?.map(createOption) ?? [] };
        }
        return {};
    };

    return (
        <Select
            name="compositionSearchDropdown"
            className={CLASSNAME}
            options={compositionOptions}
            onLoadOptions={onLoadOptionsHandler}
            onChange={onChangeHandler}
            placeholder={placeholder}
            disabled={disabled}
            testId={testId}
            selectedValue={compositionId}
        />
    );
};

export default CompositionSearchDropdown;
