import type { FC } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { Dropdown, TruncatedText } from '@theorchard/suite-components';
import {
    useAccountSearchLazyQuery,
    useAccountByIdQuery,
    useAccountsWithProductsQuery,
} from 'src/data/queries';
import { TRANSLATION_KEY } from 'src/pages/createOrder/constants';
import { useDebounceCallback } from 'src/utils';
import type { PhysicalDeliveryType } from 'src/data/globalTypes';
import type { Account } from 'src/data/types';
import type { DropdownOption, SearchableDropdownOption } from 'src/types';
import type { InputChangeCallback } from 'src/utils';

export const CLASSNAME = 'AccountSearchDropdown';

export interface Props {
    disabled?: boolean;
    onChange: (data?: Account) => void;
    accountId?: number;
    placeholder: string;
    deliveryType: PhysicalDeliveryType;
    storeId: string;
}

export const getOptionName = (account: Account) => `${account.name}`;

const createOption = (account: Account): DropdownOption<Account> => ({
    label: `${getOptionName(account)} (${account.id})`,
    value: `${account.id}`,
    data: account,
});

const AccountSearchDropdown: FC<Props> = props => {
    const {
        onChange,
        disabled,
        accountId,
        placeholder,
        deliveryType,
        storeId,
    } = props;
    const [term, setTerm] = useState<string>();
    const [executeSearch, { data: searchData, loading }] =
        useAccountSearchLazyQuery();

    const { data: listData } = useAccountsWithProductsQuery({
        storeId: storeId,
        type: deliveryType,
        limit: 100,
        offset: 0,
    });
    const dataSource: Account[] | undefined = term ? searchData : listData;
    const variables = { id: { subaccountId: 0, vendorId: accountId } };
    const { data: accountData } = useAccountByIdQuery(variables);

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

    const accountOptions = useMemo<DropdownOption<Account>[]>(
        () => [...(dataSource ?? [])].map(createOption),
        [dataSource]
    );

    const handleChange = useCallback(
        (newValue?: SearchableDropdownOption<Account>) => {
            onChange(newValue?.data);
        },
        [onChange]
    );

    let selectedOption: DropdownOption<Account> | null = null;
    if (accountData?.name) selectedOption = createOption(accountData);

    const isLoading = loading && !searchData;

    const formattedOption = (option: DropdownOption<Account>) => (
        <div className={`${CLASSNAME}-option`}>
            <div className={`${CLASSNAME}-option-name`}>
                <TruncatedText text={option.data?.name ?? ''} maxWidth={250} />
            </div>
            <div className={`${CLASSNAME}-option-id`}>
                <TruncatedText
                    text={option.data?.id.toString() ?? '-'}
                    maxWidth={250}
                />
            </div>
        </div>
    );

    const optionsWithLabel = [
        {
            label: $t(`${TRANSLATION_KEY}.filters.accountName`),
            options: accountOptions,
        },
    ];

    const CustomGroupHeading = () => (
        <>
            <span className={`${CLASSNAME}-account-name`}>
                {$t(`${TRANSLATION_KEY}.filters.accountName`)}
            </span>
        </>
    );

    return (
        <Dropdown.Custom
            type="Select"
            name="accountSearchDropdown"
            className={CLASSNAME}
            onChange={handleChange}
            onInputChange={handleInputChange}
            options={optionsWithLabel}
            isDisabled={disabled}
            isLoading={isLoading}
            formatOptionLabel={formattedOption}
            value={selectedOption}
            placeholder={placeholder}
            components={{ GroupHeading: CustomGroupHeading }}
            isClearable
        />
    );
};

export default AccountSearchDropdown;
