import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import loadShipTos from "@insite/client-framework/Store/Data/ShipTos/Handlers/LoadShipTos";
import { getShipTosDataView } from "@insite/client-framework/Store/Data/ShipTos/ShipTosSelectors";
import { isShipToAddressSelectDisabled } from "@insite/client-framework/Store/Pages/BudgetManagement/BudgetManagementSelectors";
import updateShipTosSearchFields from "@insite/client-framework/Store/Pages/BudgetManagement/Handlers/UpdateShipTosSearchFields";
import translate from "@insite/client-framework/Translate";
import DynamicDropdown, { DynamicDropdownPresentationProps, OptionObject } from "@insite/mobius/DynamicDropdown";
import debounce from "lodash/debounce";
import React, { useEffect, useState } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

interface ShipToDropdownProps {
    selected?: string;
    isShipToAddressSelectDisabled?: boolean;
    onSelectionChange: (id?: string) => void;
    getShipTosParameter?: any;
    testSelector: string;
}

export interface componentStyles {
    Dropdown?: DynamicDropdownPresentationProps;
}

export const budgetShipToStyles: componentStyles = {
    Dropdown: {
        cssOverrides: {
            dropdownWrapper: css`
                width: 360px;
            `,
        },
    },
};

const mapStateToProps = (state: ApplicationState) => {
    const { getShipTosParameter } = state.pages.budgetManagement;
    return {
        isShipToAddressSelectDisabled: isShipToAddressSelectDisabled(state),
        shipTosDataView: getShipTosParameter && getShipTosDataView(state, getShipTosParameter),
        getShipTosParameter,
    };
};

const mapDispatchToProps = {
    updateShipTosSearchFields,
    loadShipTos,
};

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

const EMPTY_ID = "EMPTY_ID";

const BudgetShipToDropdown = ({
    selected,
    onSelectionChange,
    isShipToAddressSelectDisabled,
    shipTosDataView,
    getShipTosParameter,
    updateShipTosSearchFields,
    loadShipTos,
    testSelector,
}: Props) => {
    const [shipToOptions, setShipToOptions] = useState<OptionObject[]>([]);
    const [firstInit, setFirstInit] = useState<boolean>(true);

    const changeShipTosSearchTextHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
        if (event.type === "change") {
            const value = event.currentTarget.value;
            debouncedUpdateSearchFields(value);
        }
    };

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

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

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

    // Reset search filter on page navigations
    useEffect(() => {
        if (firstInit) {
            onSelect("");
            setFirstInit(false);
        }
    }, [firstInit]);

    useEffect(() => {
        if (shipTosDataView?.value) {
            const options: OptionObject[] = shipTosDataView.value
                .filter(o => o.customerSequence !== "-1")
                .map(shipTo => ({
                    optionText: shipTo.label,
                    optionValue: shipTo.id,
                }));
            options.unshift({ optionText: translate("Select Ship To"), optionValue: EMPTY_ID });

            setShipToOptions(options);
        }
    }, [shipTosDataView, selected]);

    const onSelect = (option: any) => {
        onSelectionChange(option);
        debouncedUpdateSearchFields("");
    };

    return (
        <DynamicDropdown
            label={translate("Select Ship To Address")}
            onSelectionChange={onSelect}
            onInputChange={changeShipTosSearchTextHandler}
            selected={selected || EMPTY_ID}
            disabled={isShipToAddressSelectDisabled}
            isLoading={shipTosDataView?.isLoading}
            options={shipToOptions}
            filterOption={() => true}
            data-test-selector={testSelector}
            {...budgetShipToStyles.Dropdown}
        />
    );
};

export default connect(mapStateToProps, mapDispatchToProps)(BudgetShipToDropdown);
