import React, { useState } from 'react';
import { MultiSelect, TruncatedText } from '@theorchard/suite-components';
import { formatMessage } from '@theorchard/suite-frontend';
import { useLazyPublishingSongWritersSimpleSearch } from 'src/data/queries/songWritersSearchSimple/songWritersSearchSimple';
import type { ListViewItem } from '@theorchard/suite-components';
import type { SimpleSongWriter } from 'src/data/queries/songWritersSearchSimple/songWritersSearchSimple';
import type { Label } from 'src/types';

const CLASSNAME = 'SongWriterMultiSelector';

interface SongWriterLegalName {
    legalName: string;
}
type SelectedSongWriter = SimpleSongWriter | SongWriterLegalName;

interface Props {
    label: Label | null;
    onChange: (value: string[] | null) => void;
    defaultValue?: SongWriterLegalName[];
}

const SongWriterMultiSelect: React.FC<Props> = ({
    label,
    onChange,
    defaultValue,
}) => {
    const [selectedSongWriters, setSelectedSongWriters] = useState<
        SelectedSongWriter[]
    >(defaultValue || []);

    const [fetchSongWriters, { data }] =
        useLazyPublishingSongWritersSimpleSearch(label);

    const formatOptions = (songWriters?: SelectedSongWriter[] | null) =>
        [
            ...selectedSongWriters,
            ...(songWriters ?? []).filter(
                i =>
                    !selectedSongWriters?.some(j => i.legalName === j.legalName)
            ),
        ].map(i => ({
            label: i.legalName,
            value: i.legalName,
            subtitle:
                'professionallyKnownAs' in i
                    ? i.professionallyKnownAs.join(', ')
                    : undefined,
            data: i,
        }));

    const handleSelect = (
        options: (ListViewItem & { data: SelectedSongWriter })[]
    ) => {
        const selected = options.map(i => i.data);
        setSelectedSongWriters(selected);

        if (options.length === 0) onChange(null);
        else {
            onChange(selected.map(i => i.legalName));
        }
    };

    const onLoadOptionsHandler = async (term?: string) =>
        await fetchSongWriters({
            variables: {
                filter: {
                    legalNameSearch: term,
                    label: label?.uuid ? { uuid: label.uuid } : null,
                    professionallyKnownAs: term,
                },
            },
        }).then(({ data }) => ({
            data: formatOptions(data?.publishingSongWriters.songWriters),
        }));

    return (
        <MultiSelect
            testId={CLASSNAME}
            initialValue={formatOptions(defaultValue)}
            options={formatOptions(data?.publishingSongWriters.songWriters)}
            placeholder={formatMessage(
                'SongWriterSelector.songWritersPlaceholder'
            )}
            menuWidth="100%"
            onSelect={handleSelect}
            onLoadOptions={onLoadOptionsHandler}
            components={{
                OptionLabel: ({ option }) => (
                    <span className={`${CLASSNAME}-title`}>{option.label}</span>
                ),
                OptionSubtitle: ({ option }) =>
                    option.subtitle ? (
                        <TruncatedText
                            className={`${CLASSNAME}-subtitle`}
                            text={option.subtitle}
                            maxWidth={400}
                            numberOfLines={2}
                        />
                    ) : null,
            }}
        />
    );
};

export default SongWriterMultiSelect;
