import mergeToNew from "@insite/client-framework/Common/mergeToNew";
import openPrintDialog from "@insite/client-framework/Common/Utilities/openPrintDialog";
import { HasPagingParameters } from "@insite/client-framework/Services/ApiService";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import sendWishListPdf from "@insite/client-framework/Store/Pages/MyListDetails/Handlers/SendWishListPdf";
import translate from "@insite/client-framework/Translate";
import { PaginationModel } from "@insite/client-framework/Types/ApiModels";
import { PdfLayoutOptions } from "@insite/client-framework/Types/PrintPdfModels";
import ProductListPrintModal, {
    productListPrintModalStyles,
    ProductListPrintModalStyles,
    ProductListPrintParameters,
} from "@insite/content-library/Components/ProductListPrintModal";
import { HasToasterContext, withToaster } from "@insite/mobius/Toast/ToasterContext";
import React from "react";
import { connect, ResolveThunks } from "react-redux";

// copied into here because we got rid of the handler that used this. We will eventually bring this back.
interface LoadOrderLinesParameter extends HasPagingParameters {
    orderId: string;
}

const mapStateToProps = (state: ApplicationState) => {
    return { currentParameters: state.pages.myListDetails.loadWishListLinesParameter };
};

const mapDispatchToProps = {
    sendWishListPdf,
};

type OwnProps = {
    updateParameterFunction?: (pageSize: number) => void;
    awaitableLoader(parameter?: any): Promise<any>;
    generateParameter?: (pageSize: number) => LoadOrderLinesParameter;
    lineCollection: { pagination: Pick<PaginationModel, "totalItemCount" | "numberOfPages"> | null };
    reloading: boolean;
    isOpen: boolean;
    initialPageSize: number;
    handleClose(): void;
    styles?: WishListPrintModalStyles;
    selectedIds?: string[];
};

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

export interface WishListPrintModalStyles extends ProductListPrintModalStyles {}
export const wishListPrintModalStyles: WishListPrintModalStyles = {
    ...productListPrintModalStyles,
};

const WishListPrintModal: React.FC<Props> = ({
    updateParameterFunction,
    awaitableLoader,
    initialPageSize,
    lineCollection,
    generateParameter,
    reloading,
    isOpen,
    handleClose,
    styles,
    sendWishListPdf,
    currentParameters,
    toaster,
    selectedIds,
}) => {
    const onAfterPrint = (queryEvent: MediaQueryListEvent) => {
        if (!queryEvent.matches) {
            runQuery(initialPageSize);
        }
    };

    React.useEffect(() => {
        const mediaQueryList = window.matchMedia("print");
        mediaQueryList.addListener(onAfterPrint);

        return () => {
            mediaQueryList.removeListener(onAfterPrint);
        };
    }, []);

    const totalItemCount = lineCollection?.pagination?.totalItemCount || 999;
    const mergeStyles = mergeToNew(wishListPrintModalStyles, styles);

    const handlePrintClick = (parameter: ProductListPrintParameters) => {
        const { layout, productsToPrint, barcodeType, barcodeData, productPropertiesToPrint } = parameter;
        if (layout === PdfLayoutOptions.Standard) {
            if (productsToPrint === "current" || totalItemCount === initialPageSize) {
                printFirstPage();
                return;
            }
            printAllPages();
        } else {
            const baseParameter = {
                ...currentParameters,
                page: productsToPrint === "all" || productsToPrint === "selected" ? 1 : currentParameters.page,
                pageSize:
                    productsToPrint === "all" || productsToPrint === "selected"
                        ? totalItemCount
                        : currentParameters.pageSize ?? currentParameters.defaultPageSize,
            };
            const parameter = {
                layout,
                barcodeFormat: barcodeType,
                barcodeField: barcodeData,
                displayFields: productPropertiesToPrint,
                lineIds: productsToPrint === "selected" ? selectedIds : undefined,
                baseParameter,
                onSuccess: () => {
                    toaster.addToast({
                        body: translate(
                            "Your request has been received. Your list will be sent to the email address on your account.",
                        ),
                        messageType: "success",
                        timeoutLength: 6000,
                    });
                    handleClose();
                },
                onError: () => {
                    toaster.addToast({
                        body: translate(
                            "Something went wrong during the request to generate your PDF. Please try again or contact us.",
                        ),
                        messageType: "danger",
                        timeoutLength: 6000,
                    });
                },
            };
            sendWishListPdf(parameter);
        }
    };

    const printFirstPage = () => {
        if (isOpen) {
            handleClose();
            setTimeout(openPrintDialog, 300);
        }
    };

    const runQuery = async (itemCount: number) => {
        if (typeof updateParameterFunction === "function") {
            updateParameterFunction(itemCount);
            await awaitableLoader();
            return;
        }
        if (typeof generateParameter === "function") {
            await awaitableLoader(generateParameter(itemCount));
        }
    };

    const printAllPages = async () => {
        await runQuery(totalItemCount);
        printFirstPage();
    };

    const cancelPrintAllPages = () => {
        handleClose();
        runQuery(initialPageSize);
    };

    return (
        <ProductListPrintModal
            currentParameters={currentParameters}
            lineCollection={lineCollection}
            isOpen={isOpen}
            handleClose={handleClose}
            handleSubmit={handlePrintClick}
            handleCancelClick={cancelPrintAllPages}
            variant="WishList"
            styles={mergeStyles}
            selectedIds={selectedIds}
        />
    );
};

export default connect(mapStateToProps, mapDispatchToProps)(withToaster(WishListPrintModal));
