import React, { useState } from 'react';
import {
    useAccountList,
    useAccountSearchQuery,
} from 'src/apollo/queries/account';
import {
    useAppSettingsWriteQuery,
    useAppSettingsReadQuery,
} from 'src/apollo/queries/app-settings';
import SearchableSelectList from 'src/components/shared/searchable-select-list';
import { getAccountDropdownOptions } from 'src/utils/account';
import type { GetAccountsListQuery } from 'src/apollo/queries/account/__generated__/get-accounts-list';
import type { WriteAppSettingsQuery } from 'src/apollo/queries/app-settings/__generated__/write-app-settings';

type RecentAccount = NonNullable<
    WriteAppSettingsQuery['appSettings']['recentlySearchedAccounts']
>[0];
type AbacusAccount = GetAccountsListQuery['abacusAccounts']['items'][0];

interface Props {
    selectedAccount: any;
    setSelectedAccount: any;
    changeHandler: (params: object) => void;
}
const AccountSelect: React.FC<Props> = ({
    selectedAccount,
    setSelectedAccount,
    changeHandler,
}) => {
    const [searchTerm, setSearchTerm] = useState('');
    const { data, loading, error } = useAccountList(
        { limit: 300, offset: 0, searchTerm: '' },
        true
    );
    const getPromisedAccountSearch = useAccountSearchQuery();
    const searchResults = getAccountDropdownOptions(
        data?.abacusAccounts?.items
    );

    const setAccountData = useAppSettingsWriteQuery();
    const { data: appSettings } = useAppSettingsReadQuery();
    const recentAccounts =
        appSettings?.recentlySearchedAccounts?.map(
            (row: Partial<AbacusAccount>, i: number) => ({
                label: `${row.accountName} - ${row.accountId}`,
                value: row.accountId || '',
                isRecent: true,
                isLastRecent:
                    i ===
                    (appSettings?.recentlySearchedAccounts?.length || 0) - 1,
            })
        ) || [];

    const performSearch = async (term: string) => {
        const trimmedTerm = term.trim();
        setSearchTerm(trimmedTerm);
        const data = await getPromisedAccountSearch(trimmedTerm, 100, 0);
        const searchResults = getAccountDropdownOptions(data);
        return searchResults;
    };

    const onChange = (e: { label: string; value: string }) => {
        let value: any = null;
        if (e) value = e.value;

        changeHandler({
            target: {
                name: 'accountIds',
                value: value ? [parseInt(value, 10)] : null,
            },
        });
        setSelectedAccount(
            value ? { label: e.label, value: e.value } : undefined
        );

        if (value) {
            const oldRecentAccounts = appSettings?.recentlySearchedAccounts
                ?.map(acc => ({
                    accountId: acc.accountId,
                    __typename: 'AbacusAccount',
                }))
                .filter(acc => acc.accountId !== value) as RecentAccount[];
            const newRecentAccounts = [
                { accountId: value, __typename: 'AbacusAccount' },
                ...oldRecentAccounts,
            ] as RecentAccount[];
            setAccountData({
                recentlySearchedAccounts: newRecentAccounts.slice(0, 3),
            });
        }
    };

    return (
        <SearchableSelectList
            clearable={true}
            disabled={!!error}
            id="accountSearch"
            placeholder="All Accounts"
            isLoading={loading}
            defaultOptions={[...recentAccounts, ...searchResults]}
            searchTerm={searchTerm}
            onChange={onChange}
            onLoadOptionsHandler={performSearch}
            value={selectedAccount || ''}
        />
    );
};
export default AccountSelect;
