import type { FC } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { Select } from '@theorchard/suite-components';
import {
    useGetNrParticipants,
    useNrParticipantByIdQuery,
    useNrParticipantSearchQuery,
} from 'src/data/queries';
import { recordPrimaryArtistFilter } from 'src/utils/segment/filterEvents';
import type { MainArtist } from 'src/data/globalTypes';
import type { Participant } from 'src/data/types';
import type { DropdownOption, SearchableDropdownOption } from 'src/types';
import type { SetParamsCallback } from 'src/utils/route';

export const CLASSNAME = 'ParticipantSearchDropdown';
export const TEST_ID = 'Select_participantSearchDropdown';

interface OptionValue {
    value: string;
    label: string;
    data: Participant;
}

export interface Props {
    disabled?: boolean;
    onChange: SetParamsCallback;
    participantId?: string;
    placeholder: string;
    relationshipType?: MainArtist;
}

const mapLabelToOption = (participant: Participant): OptionValue => ({
    label: participant.name,
    value: participant.id,
    data: participant,
});

const ParticipantSearchDropdown: FC<Props> = props => {
    const { onChange, disabled, participantId, placeholder, relationshipType } =
        props;
    const [term, setTerm] = useState<string>();
    const [executeSearch, { data: searchData }] = useNrParticipantSearchQuery();
    const { data: listData } = useGetNrParticipants({ limit: 100 });
    const dataSource: Participant[] | null | undefined = term
        ? searchData
        : listData?.participants;
    const { data: participantData } = useNrParticipantByIdQuery({
        id: participantId || '',
    });

    const onLoadOptionsHandler = async (searchTerm?: string) => {
        if (searchTerm) {
            setTerm(searchTerm);
            const data = await executeSearch({
                variables: { term: searchTerm, relType: relationshipType },
            });
            const options = data?.map(item => mapLabelToOption(item));
            return {
                data: options,
            };
        }
        return {};
    };

    const participantOptions = useMemo(
        () => [...(dataSource ?? [])].map(item => mapLabelToOption(item)),
        [dataSource]
    );

    const handleChange = useCallback(
        (newValue?: SearchableDropdownOption<Participant>) => {
            onChange({ participant: newValue?.data?.id });
            recordPrimaryArtistFilter(newValue?.data?.name);
        },
        [onChange]
    );

    let selectedOption: DropdownOption<Participant> | null = null;
    if (participantData?.name)
        selectedOption = mapLabelToOption(participantData);

    return (
        <Select
            name="participantSearchDropdown"
            className={CLASSNAME}
            testId={TEST_ID}
            onChange={handleChange}
            onLoadOptions={onLoadOptionsHandler}
            options={participantOptions}
            selectedValue={selectedOption ? selectedOption : undefined}
            placeholder={selectedOption ? '' : placeholder}
            disabled={disabled}
            compact
        />
    );
};

export default ParticipantSearchDropdown;
