import getBoldedText from "@insite/client-framework/Common/Utilities/getPatternBolded";
import { trackSearchResultEvent } from "@insite/client-framework/Common/Utilities/tracking";
import {
    createHandlerChainRunner,
    Handler,
    HasOnSuccess,
    markSkipOnCompleteIfOnSuccessIsSet,
} from "@insite/client-framework/HandlerCreator";
import { AutocompleteApiParameter, autocompleteSearch } from "@insite/client-framework/Services/AutocompleteService";
import { getSettingsCollection } from "@insite/client-framework/Store/Context/ContextSelectors";
import {
    AutocompleteItemModel,
    AutocompleteModel,
    BrandAutocompleteModel,
} from "@insite/client-framework/Types/ApiModels";

type Parameter = AutocompleteApiParameter & HasOnSuccess<AutocompleteModel>;
type Props = {
    apiParameter: AutocompleteApiParameter;
    apiResult: AutocompleteModel;
};

type HandlerType = Handler<Parameter, Props>;

export const PopulateApiParameter: HandlerType = props => {
    props.apiParameter = props.parameter;
};

export const RequestDataFromApi: HandlerType = async props => {
    const isSearchV3 = getSettingsCollection(props.getState()).searchSettings.searchProvider === "Commerce Search v3";
    const minLength = isSearchV3 ? 2 : 3;

    if (props.apiParameter.searchOnTyping || props.apiParameter.query.length >= minLength) {
        props.apiResult = await autocompleteSearch(props.apiParameter);
    }
};

export const ProcessCommerceSearchCompletionResults: HandlerType = props => {
    if (!props.apiResult || !props.apiResult.isRetailSearchCompletionResults) {
        return;
    }

    props.apiResult.suggestions = [] as AutocompleteItemModel[];
    props.apiResult.categories = [] as AutocompleteItemModel[];
    props.apiResult.brands = [] as BrandAutocompleteModel[];
    props.apiResult.popularCategories = [] as AutocompleteItemModel[];
    props.apiResult.popularBrands = [] as BrandAutocompleteModel[];

    if (props.apiResult.completionResults && props.apiResult.completionResults.length > 0) {
        const {
            searchSettings: { searchPath },
        } = getSettingsCollection(props.getState());
        props.apiResult.completionResults.forEach(completionResult => {
            props.apiResult.suggestions?.push({
                title: completionResult.suggestion,
                url: `/${searchPath}?query=${encodeURIComponent(completionResult.suggestion)}`,
            } as AutocompleteItemModel);
            if (completionResult.attributeResults) {
                completionResult.attributeResults.brands?.forEach(brand => {
                    props.apiResult.brands?.push(brand);
                });
                completionResult.attributeResults.categories?.forEach(category => {
                    props.apiResult.categories?.push(category);
                });
            }
        });
    }

    if (props.apiResult.attributeResults) {
        props.apiResult.attributeResults.brands?.forEach(brand => {
            props.apiResult.popularBrands?.push(brand);
        });
        props.apiResult.attributeResults.categories?.forEach(category => {
            props.apiResult.popularCategories?.push(category);
        });
    }
};

export const SetDisplayTitles: HandlerType = props => {
    if (props.apiResult) {
        if (props.apiResult.products) {
            props.apiResult.products.forEach(product => {
                product.displayTitle = getBoldedText(product.title, props.apiParameter.query);
                product.displayErpNumber = getBoldedText(product.erpNumber, props.apiParameter.query);
                product.displayName = getBoldedText(product.name, props.apiParameter.query);
                product.displayManufacturerItemNumber = getBoldedText(
                    product.manufacturerItemNumber,
                    props.apiParameter.query,
                );
            });
        }
        if (props.apiResult.suggestions) {
            props.apiResult.suggestions.forEach(suggestion => {
                suggestion.displayTitle = getBoldedText(suggestion.title, props.apiParameter.query);
            });
        }
        if (props.apiResult.brands) {
            props.apiResult.brands.forEach(brand => {
                brand.displayTitle = getBoldedText(brand.title, props.apiParameter.query);
                if (brand.productLineName) {
                    brand.displayProductLineName = getBoldedText(brand.productLineName, props.apiParameter.query);
                }
            });
        }
        if (props.apiResult.popularBrands) {
            props.apiResult.popularBrands.forEach(brand => {
                brand.displayTitle = getBoldedText(brand.title, props.apiParameter.query);
                if (brand.productLineName) {
                    brand.displayProductLineName = getBoldedText(brand.productLineName, props.apiParameter.query);
                }
            });
        }
        if (props.apiResult.content) {
            props.apiResult.content.forEach(content => {
                content.displayTitle = getBoldedText(content.title, props.apiParameter.query);
            });
        }
        if (props.apiResult.categories) {
            props.apiResult.categories.forEach(category => {
                category.displayTitle = getBoldedText(category.title, props.apiParameter.query);
                if (category.subtitle) {
                    category.displaySubtitle = getBoldedText(category.subtitle, props.apiParameter.query);
                }
            });
        }
        if (props.apiResult.popularCategories) {
            props.apiResult.popularCategories.forEach(category => {
                category.displayTitle = getBoldedText(category.title, props.apiParameter.query);
                if (category.subtitle) {
                    category.displaySubtitle = getBoldedText(category.subtitle, props.apiParameter.query);
                }
            });
        }
    }
};

export const SendTracking: HandlerType = props => {
    if (props.apiResult?.products?.length === 1) {
        trackSearchResultEvent(props.apiParameter.query, 1);
    }
};

export const ExecuteOnSuccessCallback: HandlerType = props => {
    markSkipOnCompleteIfOnSuccessIsSet(props);
    props.parameter.onSuccess?.(props.apiResult);
};

export const chain = [
    PopulateApiParameter,
    RequestDataFromApi,
    ProcessCommerceSearchCompletionResults,
    SetDisplayTitles,
    SendTracking,
    ExecuteOnSuccessCallback,
];

const getAutocompleteModel = createHandlerChainRunner(chain, "GetAutocompleteModel");
export default getAutocompleteModel;
