import type { FC } from 'react';
import React, { useCallback, useMemo } from 'react';
import { Select } from '@theorchard/suite-components';
import { BrandIcon } from '@theorchard/suite-icons';
import { BRAND_ORCHARD, SIZE_16 } from 'src/constants';
import {
    useVendorAndSubaccountsQuery,
    useVendorAndSubaccountSearchQuery,
} from 'src/data/queries';
import type { VendorAndSubaccount } from 'src/data/types';
import type {
    AccountDropdownGroupedOption,
    VendorAndSubaccountSearchDropdownProps,
    DropdownOptionWithIcon,
    SearchableDropdownOption,
} from 'src/types';

export const CLASSNAME = 'VendorAndSubaccountSearchDropdown';

const createLabel = (account: VendorAndSubaccount): string | undefined => {
    if (account.type == 'Subaccount') {
        return createSubaccountLabel(account);
    } else if (account.type == 'Vendor') {
        return createVendorLabel(account);
    }
};

const createVendorLabel = (account: VendorAndSubaccount): string =>
    `${account.name} • ${account.vendorId}`;

const createSubaccountLabel = (account: VendorAndSubaccount): string =>
    `${account.name} • ${account.subaccountId}`;

const createOption = (
    account: VendorAndSubaccount
): DropdownOptionWithIcon<VendorAndSubaccount> => ({
    label: createLabel(account),
    value: account.name + '--' + account.vendorId.toString(),
    icon: <BrandIcon brand={BRAND_ORCHARD} size={SIZE_16} />,
    data: account,
});

const createSubaccountsOption = (
    account: VendorAndSubaccount
): DropdownOptionWithIcon<VendorAndSubaccount> => ({
    label: createSubaccountLabel(account),
    value: account.name + '--' + account.subaccountId.toString(),
    icon: <BrandIcon brand={BRAND_ORCHARD} size={SIZE_16} />,
    data: account,
});

const VendorAndSubaccountSearchDropdown: FC<
    VendorAndSubaccountSearchDropdownProps
> = props => {
    const {
        disabled,
        menuWidth,
        onChange,
        placeholder,
        testId,
        selectedAccount,
    } = props;
    const { data: accountsData } = useVendorAndSubaccountsQuery();
    const [executeSearch] = useVendorAndSubaccountSearchQuery();

    const handleAccountGroupedOptions = useCallback(
        (
            accountsOptionsData: VendorAndSubaccount[]
        ): AccountDropdownGroupedOption<VendorAndSubaccount>[] => {
            const vendorData = accountsOptionsData.filter(
                account => account.type == 'Vendor'
            );
            const subaccountData = accountsOptionsData.filter(
                account => account.type == 'Subaccount'
            );
            return [
                {
                    label: 'Accounts',
                    options: vendorData.map(createOption),
                },
                {
                    label: 'Subaccounts',
                    options: subaccountData.map(createSubaccountsOption),
                },
            ];
        },
        []
    );

    const accountGroupedOptions = useMemo<
        AccountDropdownGroupedOption<VendorAndSubaccount>[]
    >(
        () =>
            accountsData?.length
                ? handleAccountGroupedOptions(accountsData)
                : [],
        [accountsData, handleAccountGroupedOptions]
    );

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

    const onLoadOptionsHandler = useCallback(
        async (term?: string) => {
            if (term) {
                const searchAccountsData = await executeSearch({
                    variables: { term },
                });
                return {
                    data: searchAccountsData?.length
                        ? handleAccountGroupedOptions(searchAccountsData)
                        : [],
                };
            }
            return {};
        },
        [executeSearch, handleAccountGroupedOptions]
    );

    return (
        <Select
            name="vendorAndSubaccountSearchDropdown"
            className={CLASSNAME}
            disabled={disabled}
            onChange={onChangeHandler}
            onLoadOptions={onLoadOptionsHandler}
            placeholder={placeholder}
            testId={testId}
            options={accountGroupedOptions}
            menuWidth={menuWidth}
            selectedValue={
                selectedAccount ? createLabel(selectedAccount) : undefined
            }
        />
    );
};

export default VendorAndSubaccountSearchDropdown;
