import type { FC } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Dropdown } from '@theorchard/suite-components';
import { filterData } from '@theorchard/suite-frontend';
import { useDebounceCallback } from 'src/components/utils';
import {
    useGetNrParticipants,
    useNrParticipantSearchQuery,
} from 'src/data/queries';
import type { DropdownProps } from '@theorchard/suite-components';
import type { InputChangeCallback } from 'src/components/utils';
import type { Participant } from 'src/data/types';
import type { DropdownOption } from 'src/types';

export const CLASSNAME = 'ParticipantMultiSearchDropdown';

type DropdownChangeCallback = Required<
    DropdownProps<DropdownOption<Participant>, true>
>['onChange'];

export interface Props {
    placeholder?: string;
    participants: Participant[];
    onChange: (values: Participant[]) => void;
    resetForm: boolean;
    disabled: boolean;
}

const createOption = (
    participant: Participant
): DropdownOption<Participant> => ({
    label: participant.name,
    value: participant.id,
    data: participant,
});

const ParticipantMultiSearchDropdown: FC<Props> = props => {
    const { placeholder, participants, onChange, resetForm, disabled } = props;
    const [term, setTerm] = useState<string>();
    const [newSelections, setNewSelections] = useState<
        DropdownOption<Participant>[]
    >([]);
    const [executeSearch, { data: searchData }] = useNrParticipantSearchQuery();
    const { data: listData } = useGetNrParticipants({ limit: 100 });
    const dataSource = filterData(term ? searchData : listData?.participants);

    const handleInputChange = useDebounceCallback<InputChangeCallback>(
        (searchTerm: string, { action }) => {
            setTerm(searchTerm);
            if (action !== 'menu-close')
                void executeSearch({ variables: { term: searchTerm } });
        },
        300
    );

    const participantOptions = useMemo<DropdownOption<Participant>[]>(
        () => dataSource.map(createOption),
        [dataSource]
    );

    const handleChange = useCallback<DropdownChangeCallback>(
        newValue => {
            setNewSelections(filterData([...newValue]));
            onChange(
                newValue.map(item => ({
                    id: item.value,
                    name: item.label ?? '',
                }))
            );
        },
        [onChange]
    );

    const presetOptions = filterData(participants).map(createOption);

    useEffect(() => {
        if (resetForm) setNewSelections([]);
    }, [onChange, resetForm]);

    const showPresetOptions =
        participants.length > 0 && newSelections.length < 1;

    return (
        <Dropdown.Custom
            type="Select"
            name="ParticipantMultiSearchDropdown"
            options={participantOptions}
            placeholder={placeholder}
            isMulti
            onChange={handleChange}
            onInputChange={handleInputChange}
            value={showPresetOptions ? presetOptions : newSelections}
            isDisabled={disabled}
        />
    );
};

export default ParticipantMultiSearchDropdown;
