import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import loadShipTos from "@insite/client-framework/Store/Data/ShipTos/Handlers/LoadShipTos";
import {
    getCurrentShipTosDataView,
    getShipTosDataView,
} from "@insite/client-framework/Store/Data/ShipTos/ShipTosSelectors";
import updateSearchFields from "@insite/client-framework/Store/Pages/OrderHistory/Handlers/UpdateSearchFields";
import updateShipTosSearchFields from "@insite/client-framework/Store/Pages/OrderHistory/Handlers/UpdateShipTosSearchFields";
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 { SelectProps } from "@insite/mobius/Select";
import debounce from "lodash/debounce";
import * as React from "react";
import { useEffect, useState } from "react";
import { connect, ResolveThunks } from "react-redux";

const mapStateToProps = (state: ApplicationState) => {
    const { getShipTosParameter, getOrdersParameter } = state.pages.orderHistory;
    return {
        currentShipTosDataView: getCurrentShipTosDataView(state),
        shipTosDataView: getShipTosParameter && getShipTosDataView(state, getShipTosParameter),
        getShipTosParameter,
        getOrdersParameter,
    };
};

const mapDispatchToProps = {
    updateShipTosSearchFields,
    updateSearchFields,
    loadShipTos,
};

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

export interface OrderHistorySearchFieldShipToStyles {
    /** @deprecated Use the `dropdown` property instead. */
    select?: SelectProps;
    dropdown?: DynamicDropdownPresentationProps;
    wrapper?: SearchFieldWrapperStyles;
}

export const shipToStyles: OrderHistorySearchFieldShipToStyles = {};
const styles = shipToStyles;

const OrderHistorySearchFieldShipTos = ({
    shipTosDataView,
    getShipTosParameter,
    getOrdersParameter,
    updateShipTosSearchFields,
    updateSearchFields,
    loadShipTos,
}: Props) => {
    const [options, setOptions] = useState<OptionObject[]>([]);
    const [selectedShipToId, setSelectedShipToId] = useState("");
    const [search, setSearch] = useState("");

    useEffect(() => {
        if (shipTosDataView && !shipTosDataView.value && !shipTosDataView.isLoading) {
            loadShipTos(getShipTosParameter);
        }
    }, []);

    useEffect(() => {
        if (shipTosDataView?.value) {
            const options: OptionObject[] = shipTosDataView.value.map(shipTo => ({
                optionText: shipTo.label,
                optionValue: shipTo.id,
            }));
            setOptions(options);
            selectShipTo();
        }
    }, [shipTosDataView]);

    useEffect(() => {
        if (!shipTosDataView?.isLoading) {
            loadShipTos(getShipTosParameter);
        }
    }, [getShipTosParameter]);

    useEffect(() => {
        setSearch("");
        debouncedUpdateSearchFields("");
        selectShipTo();
    }, [getOrdersParameter]);

    const selectShipTo = () => {
        const id = shipTosDataView?.value?.find(
            o => o.customerSequence === (getOrdersParameter.customerSequence || ""),
        )?.id;
        id && setSelectedShipToId(id);
    };

    const selectCustomerHandler = (id?: string) => {
        id && setSelectedShipToId(id);
        const customerSequence = shipTosDataView?.value?.find(o => o.id === id)?.customerSequence;
        updateSearchFields({ customerSequence });
    };

    const changeSearchTextHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
        const value = event.currentTarget.value;
        setSearch(value);
        debouncedUpdateSearchFields(value);
    };

    const debouncedUpdateSearchFields = debounce((value: string) => {
        updateShipTosSearchFields({ ...getShipTosParameter, filter: value || undefined });
    }, 200);

    return (
        <SearchFieldWrapper extendedStyles={styles.wrapper}>
            <DynamicDropdown
                {...styles.dropdown}
                label={translate("Ship To")}
                onSelectionChange={selectCustomerHandler}
                onInputChange={changeSearchTextHandler}
                selected={selectedShipToId}
                isLoading={shipTosDataView?.isLoading}
                options={options}
                search={search}
                data-test-selector="orderHistory_filterShipTo"
                filterOption={() => true}
            />
        </SearchFieldWrapper>
    );
};

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(OrderHistorySearchFieldShipTos),
    definition: {
        group: "Order History",
        displayName: "Ship To",
        allowedContexts: ["OrderHistoryPage", "VmiOrderHistoryPage"],
    },
};

export default widgetModule;
