import React, { useCallback, useEffect, useState } from 'react';
import { useContractSearchQuery } from 'src/apollo/queries/contract';
import SearchableSelectList from 'src/components/shared/searchable-select-list';
import type { DropdownOption } from '@theorchard/suite-components';
import type { AbacusContractType } from 'src/apollo/definitions/globalTypes';

const CONTRACT_SEARCH_PLACEHOLDER = 'Search for contract';

export interface ContractSearchPropType {
    className?: string;
    clearable?: boolean;
    contractSearchResults?: any;
    contractType: AbacusContractType | null;
    disabled?: boolean;
    placeholder?: string;
    selectedOption?: any;
    contractIdPreselected?: string;
}

const useContractSearch = ({
    className = '',
    clearable = true,
    contractSearchResults = [],
    contractType,
    disabled = false,
    placeholder = CONTRACT_SEARCH_PLACEHOLDER,
    selectedOption,
    contractIdPreselected,
}: ContractSearchPropType) => {
    const [searchTerm, setSearchTerm] = useState<string>('');
    const [selectedContract, setSelectedContract] = useState<DropdownOption>();
    const [searchResults, setSearchResults] = useState<DropdownOption[]>([]);

    const getPromisedContractSearch = useContractSearchQuery();

    const clearSelect = () => {
        if (!clearable) return;

        setSelectedContract(undefined);
        setSearchResults([]);
        setSearchTerm('');
    };

    const handleSelectChange = (e: any) => {
        if (e) setSelectedContract({ label: e.label, value: e.value });
        else {
            setSelectedContract(undefined);
            setSearchTerm('');
            setSearchResults([]);
        }
    };

    const performSearch = useCallback(
        async (term: string) => {
            const trimmedTerm = term.trim();
            if (trimmedTerm) {
                setSearchTerm(trimmedTerm);

                const data = await getPromisedContractSearch(
                    trimmedTerm,
                    contractType,
                    100,
                    0
                );
                const searchResults =
                    data?.map((row: any) => ({
                        label: `${row.contractName} - ${row.contractId}`,
                        value: row.contractId,
                    })) || [];

                if (contractIdPreselected) {
                    const contractById = searchResults.find(
                        el => el.value === contractIdPreselected
                    );
                    contractById && setSearchResults([contractById]);
                    setSelectedContract(contractById);
                } else {
                    setSearchResults(searchResults);
                }
                return searchResults;
            }
        },
        [contractIdPreselected, contractType]
    );

    const renderDefaultOption = () => {
        setSearchTerm('');
        setSelectedContract(selectedOption);
        setSearchResults(contractSearchResults);
    };

    useEffect(() => {
        if (contractIdPreselected) {
            void performSearch(contractIdPreselected);
        }
    }, [contractIdPreselected, performSearch]);

    const renderContractSearch = () => (
        <SearchableSelectList
            className={className}
            clearable={clearable}
            defaultOptions={searchResults || contractSearchResults}
            disabled={disabled}
            id="contractSearch"
            isLoading={false}
            onChange={handleSelectChange}
            onLoadOptionsHandler={performSearch}
            placeholder={placeholder}
            searchTerm={searchTerm}
            value={selectedContract || undefined}
        />
    );

    return {
        contractId: selectedContract?.value,
        contractName: selectedContract?.label,
        clearSelect,
        renderContractSearch,
        renderDefaultOption,
    };
};

export default useContractSearch;
