import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import reset from "@insite/client-framework/Store/Components/ProductSelector/Handlers/Reset";
import searchProducts from "@insite/client-framework/Store/Components/ProductSelector/Handlers/SearchProducts";
import setProduct from "@insite/client-framework/Store/Components/ProductSelector/Handlers/SetProduct";
import { getProductSelector } from "@insite/client-framework/Store/Components/ProductSelector/ProductSelectorSelectors";
import { getProductState } from "@insite/client-framework/Store/Data/Products/ProductsSelectors";
import updateSearchFields from "@insite/client-framework/Store/Pages/OrderHistory/Handlers/UpdateSearchFields";
import translate from "@insite/client-framework/Translate";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import SearchFieldWrapper, {
    SearchFieldWrapperStyles,
} from "@insite/content-library/Widgets/OrderHistory/SearchFieldWrapper";
import DynamicDropdown, { DynamicDropdownPresentationProps, OptionObject } from "@insite/mobius/DynamicDropdown";
import LazyImage, { LazyImageProps } from "@insite/mobius/LazyImage";
import Typography, { TypographyPresentationProps } from "@insite/mobius/Typography";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import debounce from "lodash/debounce";
import React, { ChangeEvent, useCallback, useEffect, useState } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const mapStateToProps = (state: ApplicationState) => {
    const { searchResults, selectedProductInfo } = getProductSelector(state);
    const product = getProductState(state, selectedProductInfo?.productId).value;

    return {
        getOrdersParameter: state.pages.orderHistory.getOrdersParameter,
        searchResults,
        product,
    };
};

const mapDispatchToProps = {
    updateSearchFields,
    searchProducts,
    setProduct,
    reset,
};

export interface OrderHistorySearchFieldProductErpNumber2Styles {
    wrapper?: SearchFieldWrapperStyles;
    searchDynamicDropdown?: DynamicDropdownPresentationProps;
    optionWrapper?: InjectableCss;
    imageWrapper?: InjectableCss;
    productImage?: LazyImageProps;
    infoWrapper?: InjectableCss;
    autocompleteTitleText?: TypographyPresentationProps;
    autocompleteErpText?: TypographyPresentationProps;
}

export const orderHistorySearchFieldProductErpNumber2Styles: OrderHistorySearchFieldProductErpNumber2Styles = {
    optionWrapper: {
        css: css`
            display: flex;
            cursor: pointer;
        `,
    },
    imageWrapper: {
        css: css`
            display: flex;
            width: 50px;
            height: 50px;
            margin-right: 10px;
        `,
    },
    productImage: {
        width: "50px",
        css: css`
            flex-shrink: 0;
            img {
                height: 100%;
            }
        `,
    },
    infoWrapper: {
        css: css`
            display: flex;
            flex-direction: column;
        `,
    },
    autocompleteTitleText: {
        size: 14,
    },
    autocompleteErpText: {
        size: 14,
        css: css`
            margin-top: 5px;
        `,
    },
};
const styles = orderHistorySearchFieldProductErpNumber2Styles;

type Props = WidgetProps & ReturnType<typeof mapStateToProps> & ResolveThunks<typeof mapDispatchToProps>;

const OrderHistorySearchFieldProductErpNumber2 = ({
    getOrdersParameter,
    updateSearchFields,
    searchResults,
    product,
    searchProducts,
    setProduct,
    reset,
}: Props) => {
    const [search, setSearch] = useState("");
    const [options, setOptions] = useState<OptionObject[]>([]);
    const [isLoading, setIsLoading] = useState(false);

    useEffect(() => {
        if (getOrdersParameter.productErpNumber === undefined) {
            setSearch("");
            setOptions([]);
            reset();
        }
    }, [getOrdersParameter]);

    useEffect(() => {
        setIsLoading(false);
        if (!searchResults) {
            return;
        }

        if (searchResults.length === 0) {
            const trimmedQuery = search.trim();
            setOptions([
                {
                    optionText: trimmedQuery,
                    optionValue: trimmedQuery,
                    rowChildren: <StyledWrapper {...styles.optionWrapper}>{trimmedQuery}</StyledWrapper>,
                },
            ]);
            return;
        }

        const newOptions = searchResults.map((product: any) => ({
            optionText: product.erpNumber,
            optionValue: product.id || undefined,
            rowChildren: (
                <StyledWrapper {...styles.optionWrapper}>
                    <StyledWrapper {...styles.imageWrapper}>
                        <LazyImage {...styles.productImage} src={product.image} />
                    </StyledWrapper>
                    <StyledWrapper {...styles.infoWrapper}>
                        <Typography {...styles.autocompleteTitleText}>{product.title}</Typography>
                        <Typography {...styles.autocompleteErpText}>{product.erpNumber}</Typography>
                    </StyledWrapper>
                </StyledWrapper>
            ),
        }));
        setOptions(newOptions);
    }, [searchResults]);

    useEffect(() => {
        if (product) {
            const erpNumber = product.productNumber;
            updateSearchFields({ productErpNumber: erpNumber });
        }
    }, [product]);

    const onSelectionChangeHandler = (value?: string) => {
        if (searchResults && searchResults.length > 0) {
            const variantParentId = searchResults.find(o => o.id === value)?.styleParentId;
            if (variantParentId) {
                setProduct({
                    productId: variantParentId,
                    variantId: value,
                    validateProduct: true,
                    skipInventoryValidation: true,
                });
            } else {
                setProduct({
                    productId: value,
                    validateProduct: true,
                    skipInventoryValidation: true,
                });
            }
        } else {
            updateSearchFields({ productErpNumber: value });
        }
    };

    const debouncedSearchProducts = useCallback(
        debounce((query: string) => {
            setSearch(query);
            searchProducts({ query, relevancy: false });
        }, 300),
        [],
    );

    const onInputChanged = (event: ChangeEvent<HTMLInputElement>) => {
        setIsLoading(true);
        debouncedSearchProducts(event.target.value);
    };

    return (
        <SearchFieldWrapper extendedStyles={styles.wrapper}>
            <DynamicDropdown
                {...styles.searchDynamicDropdown}
                label={translate("Product")}
                onSelectionChange={onSelectionChangeHandler}
                onInputChange={onInputChanged}
                filterOption={() => true}
                selected={product?.id || getOrdersParameter.productErpNumber}
                options={options}
                hideNoOptionsIfEmptySearch
                isLoading={isLoading}
                placeholder={translate("Enter keyword or item #")}
                search={search}
                data-test-selector="orderHistory_filterProduct"
            />
        </SearchFieldWrapper>
    );
};

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(OrderHistorySearchFieldProductErpNumber2),
    definition: {
        group: "Order History",
        displayName: "Product ERP Number",
        allowedContexts: ["OrderHistoryPage", "VmiOrderHistoryPage"],
    },
};

export default widgetModule;
