import useAppDispatch from "@insite/client-framework/Common/Hooks/useAppDispatch";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import DeferredApisModel from "@insite/client-framework/Types/DeferredApisModel";
import * as React from "react";
import { connect } from "react-redux";

export interface HasDeferredApiContext {
    callDeferredApis: (deferredApiHandlers: DeferredApiHandlers) => void;
    deferredApiCalls: DeferredApisModel;
}

export interface DeferredApiHandlers {
    catalogHandler?: () => void;
    pricingHandler?: () => void;
    inventoryHandler?: () => void;
}
export const DeferredApiContext = React.createContext<HasDeferredApiContext>({} as any);

export function withCallDeferredApi<P extends HasDeferredApiContext>(Component: React.ComponentType<P>) {
    const mapStateToProps = (state: ApplicationState) => {
        return {
            deferredApiCalls: state.context.deferredApiCalls,
        };
    };
    function DeferredApiComponent(props: ReturnType<typeof mapStateToProps>) {
        const { deferredApiCalls, ...baseProps } = props;
        const dispatch = useAppDispatch();
        const decrementDeferredApi = (type: "catalog" | "pricing" | "inventory") => {
            dispatch({
                type: "Context/RemoveDeferredApiCall",
                deferredCallType: type,
            });
        };
        return (
            <DeferredApiContext.Consumer>
                {_ => (
                    <Component
                        {...(baseProps as P)}
                        deferredApiCalls={deferredApiCalls}
                        callDeferredApis={(callsToMake: DeferredApiHandlers) => {
                            if (IS_SERVER_SIDE) {
                                return;
                            }

                            if (deferredApiCalls.catalog > 0) {
                                callsToMake.catalogHandler?.();
                                decrementDeferredApi("catalog");
                            }

                            if (deferredApiCalls.pricing > 0) {
                                callsToMake.pricingHandler?.();
                                decrementDeferredApi("pricing");
                            }

                            if (deferredApiCalls.inventory) {
                                callsToMake.inventoryHandler?.();
                                decrementDeferredApi("inventory");
                            }
                        }}
                    />
                )}
            </DeferredApiContext.Consumer>
        );
    }

    return connect(mapStateToProps)(DeferredApiComponent);
}
