import mergeToNew from "@insite/client-framework/Common/mergeToNew";
import { HasPagingParameters } from "@insite/client-framework/Services/ApiService";
import translate from "@insite/client-framework/Translate";
import { PaginationModel } from "@insite/client-framework/Types/ApiModels";
import {
    PdfBarcodeDataFieldOptions,
    PdfBarcodeFormatOptions,
    PdfLayoutOptions,
} from "@insite/client-framework/Types/PrintPdfModels";
import { TwoButtonModalStyles, twoButtonModalStyles } from "@insite/content-library/Components/TwoButtonModal";
import Button from "@insite/mobius/Button";
import Checkbox, { CheckboxProps } from "@insite/mobius/Checkbox";
import { CheckboxGroupProps } from "@insite/mobius/CheckboxGroup";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import LazyImage from "@insite/mobius/LazyImage";
import Modal from "@insite/mobius/Modal";
import Radio from "@insite/mobius/Radio";
import RadioGroup, { RadioGroupProps } from "@insite/mobius/RadioGroup";
import Select, { SelectProps } from "@insite/mobius/Select";
import { HasToasterContext, withToaster } from "@insite/mobius/Toast/ToasterContext";
import Typography from "@insite/mobius/Typography";
import React, { useEffect, useState } from "react";
import styled, { css } from "styled-components";

type OwnProps = {
    currentParameters: HasPagingParameters;
    lineCollection: { pagination: Pick<PaginationModel, "totalItemCount" | "numberOfPages"> | null };
    isOpen: boolean;
    handleClose(): void;
    styles?: ProductListPrintModalStyles;
    selectedIds?: string[];
    handleSubmit(parameters: ProductListPrintParameters): void;
    handleCancelClick(): void;
    variant: "WishList" | "VMI";
};

type Props = OwnProps & HasToasterContext;

export interface ProductListPrintModalStyles extends TwoButtonModalStyles {
    productsToPrintGridItem?: GridItemProps;
    productsToPrintRadioGroup?: RadioGroupProps;
    layoutGridItem?: GridItemProps;
    layoutSelect?: SelectProps;
    barcodeTypeGridItem?: GridItemProps;
    barcodeTypeRadioGroup?: RadioGroupProps;
    barcodeDataGridItem?: GridItemProps;
    barcodeDataSelect?: SelectProps;
    productPropertiesGridItem?: GridItemProps;
    productPropertiesCheckboxGroup?: CheckboxGroupProps;
    productPropertiesCheckboxGridContainer?: GridContainerProps;
    productPropertiesCheckboxGridItem?: GridItemProps;
    productPropertyCheckbox?: CheckboxProps;
}
export const productListPrintModalStyles: ProductListPrintModalStyles = {
    ...twoButtonModalStyles,
    productsToPrintGridItem: {
        width: 12,
    },
    productsToPrintRadioGroup: {
        horizontal: true,
    },
    layoutGridItem: {
        width: 12,
    },
    barcodeTypeGridItem: {
        width: 12,
    },
    barcodeTypeRadioGroup: {
        horizontal: true,
    },
    barcodeDataGridItem: {
        width: 12,
    },
    productPropertiesGridItem: {
        width: 12,
    },
    productPropertiesCheckboxGridItem: {
        width: 12,
        css: css`
            gap: 15px;
        `,
    },
    productPropertyCheckbox: {
        css: css`
            min-width: 165px;
        `,
    },
};

const BarcodeTypeRadioWrapper = styled.div`
    display: inline-block;
    margin-top: 5px;
    margin-right: 20px;
`;

export interface ProductListPrintParameters {
    layout: PdfLayoutOptions;
    productsToPrint: "current" | "selected" | "all";
    barcodeType: PdfBarcodeFormatOptions;
    barcodeData: PdfBarcodeDataFieldOptions;
    productPropertiesToPrint: string[];
}

const ProductListPrintModal: React.FC<Props> = ({
    lineCollection,
    isOpen,
    handleClose,
    styles,
    selectedIds,
    handleSubmit,
    handleCancelClick,
    variant,
}) => {
    const [productsToPrint, setProductsToPrint] = useState<"current" | "selected" | "all">("current");
    const [layout, setLayout] = useState<PdfLayoutOptions>(PdfLayoutOptions.Standard);
    const [barcodeType, setBarcodeType] = useState<PdfBarcodeFormatOptions>(PdfBarcodeFormatOptions.QRCode);
    const [barcodeData, setBarcodeData] = useState<PdfBarcodeDataFieldOptions>(PdfBarcodeDataFieldOptions.URL);
    const [productPropertiesToPrint, setPropductPropertiesToPrint] = useState<string[]>([
        "ShortDescription",
        "SmallImagePath",
        "ErpNumber",
        "ManufacturerItem",
        "CustomerName",
    ]);

    useEffect(() => {
        if (variant === "VMI") {
            setLayout(PdfLayoutOptions.Avery94224);
        }
        if (variant === "WishList") {
            setLayout(PdfLayoutOptions.Standard);
        }
    }, [variant]);

    const onProductsToPrintChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const value = event.currentTarget.value;
        if (value === "current" || value === "selected" || value === "all") {
            setProductsToPrint(value);
        }
    };

    const onLayoutChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
        const value = event.currentTarget.value;
        if (value in PdfLayoutOptions) {
            setLayout(value as PdfLayoutOptions);
            if (value === PdfLayoutOptions.Standard && productsToPrint === "selected") {
                setProductsToPrint("current");
            }
        }
    };

    const onBarcodeTypeChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const value = event.currentTarget.value;
        if (value in PdfBarcodeFormatOptions) {
            setBarcodeType(value as PdfBarcodeFormatOptions);
            if (value === PdfBarcodeFormatOptions.Code39 && barcodeData === PdfBarcodeDataFieldOptions.URL) {
                setBarcodeData(PdfBarcodeDataFieldOptions.ErpNumber);
            }
        }
    };

    const onBarcodeDataChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
        const value = event.currentTarget.value;
        if (value in PdfBarcodeDataFieldOptions) {
            setBarcodeData(value as PdfBarcodeDataFieldOptions);
        }
    };

    const onPropertiesToPrintCheckboxChange = (include: boolean, property: string) => {
        if (include && !productPropertiesToPrint.includes(property)) {
            setPropductPropertiesToPrint([...productPropertiesToPrint, property]);
        }

        if (!include) {
            setPropductPropertiesToPrint(productPropertiesToPrint.filter(value => value !== property));
        }
    };

    const mergeStyles = mergeToNew(productListPrintModalStyles, styles);

    const handlePrintClick = () => {
        handleSubmit({
            layout,
            barcodeData,
            barcodeType,
            productsToPrint,
            productPropertiesToPrint,
        });
    };

    return (
        <Modal
            headline={translate("Print Options")}
            {...styles}
            handleClose={handleClose}
            isOpen={isOpen}
            data-test-selector="productListPrintModal"
        >
            <GridContainer {...mergeStyles?.container}>
                <GridItem {...mergeStyles?.productsToPrintGridItem}>
                    <RadioGroup
                        {...mergeStyles?.barcodeTypeRadioGroup}
                        label={translate("Products To Print")}
                        value={productsToPrint}
                        onChangeHandler={onProductsToPrintChange}
                    >
                        <Radio value="current" data-test-selector="ProductsToPrintRadio_Current">
                            {translate("Current page")}
                        </Radio>
                        {layout !== PdfLayoutOptions.Standard && (selectedIds?.length ?? 0) > 0 && (
                            <Radio value="selected" data-test-selector="ProductsToPrintRadio_Selected">
                                {translate("Selected")}
                            </Radio>
                        )}
                        {lineCollection.pagination?.totalItemCount && lineCollection.pagination.numberOfPages > 1 && (
                            <Radio value="all" data-test-selector="ProductsToPrintRadio_All">
                                {translate("All {0} Items", lineCollection.pagination.totalItemCount.toString())}
                            </Radio>
                        )}
                    </RadioGroup>
                </GridItem>
                <GridItem {...mergeStyles?.layoutGridItem}>
                    <Select
                        value={layout}
                        onChange={onLayoutChange}
                        {...mergeStyles?.layoutSelect}
                        label={translate("Layout")}
                        data-test-selector="productListPrintLayoutSelect"
                    >
                        {variant === "WishList" && (
                            <option value={PdfLayoutOptions.Standard}>{translate("Standard")}</option>
                        )}
                        <option value={PdfLayoutOptions.Avery94224}>
                            {translate(`Printable Label - 1" x 3" - 2 Column (Avery 94224)`)}
                        </option>
                        <option value={PdfLayoutOptions.Avery22806}>
                            {translate(`Printable Label - 2" x 2" - 3 Column (Avery 22806)`)}
                        </option>
                    </Select>
                </GridItem>
                {layout !== PdfLayoutOptions.Standard && (
                    <>
                        <GridItem {...mergeStyles?.barcodeTypeGridItem}>
                            <RadioGroup
                                value={PdfBarcodeFormatOptions[barcodeType]}
                                onChangeHandler={onBarcodeTypeChange}
                                {...mergeStyles?.barcodeTypeRadioGroup}
                                label={translate("Barcode Type")}
                                data-test-selector="productListPrintBarcodeTypeSelect"
                            >
                                <BarcodeTypeRadioWrapper>
                                    <LazyImage src="/images/qr-code.png" height="94px" width="94px" />
                                    <Radio value={PdfBarcodeFormatOptions.QRCode}>{translate("QR Code")}</Radio>
                                </BarcodeTypeRadioWrapper>
                                <BarcodeTypeRadioWrapper>
                                    <LazyImage src="/images/code-39.png" height="94px" width="132px" />
                                    <Radio value={PdfBarcodeFormatOptions.Code39}>{translate("1-Dimensional")}</Radio>
                                </BarcodeTypeRadioWrapper>
                                <Radio value={PdfBarcodeFormatOptions.None}>{translate("None")}</Radio>
                            </RadioGroup>
                        </GridItem>
                        <GridItem {...mergeStyles?.barcodeDataGridItem}>
                            <Select
                                value={barcodeData}
                                onChange={onBarcodeDataChange}
                                disabled={barcodeType === PdfBarcodeFormatOptions.None}
                                {...mergeStyles?.barcodeDataSelect}
                                label={translate("Barcode Data")}
                                data-test-selector="productListPrintBarcodeDataSelect"
                            >
                                {barcodeType === PdfBarcodeFormatOptions.QRCode && (
                                    <option value={PdfBarcodeDataFieldOptions.URL}>
                                        {variant === "VMI" ? translate(`VMI URL`) : translate(`URL`)}
                                    </option>
                                )}
                                {variant === "VMI" && (
                                    <option value={PdfBarcodeDataFieldOptions.BinNumber}>
                                        {translate("Product Bin #")}
                                    </option>
                                )}
                                <option value={PdfBarcodeDataFieldOptions.ErpNumber}>
                                    {translate(`Property - Part Number`)}
                                </option>
                                <option value={PdfBarcodeDataFieldOptions.CustomerName}>
                                    {translate(`Property - My Part Number`)}
                                </option>
                                <option value={PdfBarcodeDataFieldOptions.ManufacturerItem}>
                                    {translate(`Property - Manufacturer Number`)}
                                </option>
                            </Select>
                        </GridItem>
                        <GridItem {...mergeStyles?.productPropertiesGridItem}>
                            <GridContainer {...mergeStyles?.productPropertiesCheckboxGridContainer}>
                                <GridItem {...mergeStyles?.productPropertiesCheckboxGridItem}>
                                    <Typography as="label" weight={600}>
                                        {translate("Product Properties to Print")}
                                    </Typography>
                                </GridItem>
                                <GridItem {...mergeStyles?.productPropertiesCheckboxGridItem}>
                                    <Checkbox
                                        onChange={(_, checked) =>
                                            onPropertiesToPrintCheckboxChange(checked, "ShortDescription")
                                        }
                                        checked={productPropertiesToPrint.includes("ShortDescription")}
                                        {...mergeStyles?.productPropertyCheckbox}
                                    >
                                        {translate("Product Name")}
                                    </Checkbox>
                                    <Checkbox
                                        onChange={(_, checked) =>
                                            onPropertiesToPrintCheckboxChange(checked, "SmallImagePath")
                                        }
                                        checked={productPropertiesToPrint.includes("SmallImagePath")}
                                        {...mergeStyles?.productPropertyCheckbox}
                                    >
                                        {translate("Product Image")}
                                    </Checkbox>
                                    <Checkbox
                                        onChange={(_, checked) =>
                                            onPropertiesToPrintCheckboxChange(checked, "ErpNumber")
                                        }
                                        checked={productPropertiesToPrint.includes("ErpNumber")}
                                        {...mergeStyles?.productPropertyCheckbox}
                                    >
                                        {translate("Part Number")}
                                    </Checkbox>
                                </GridItem>
                                <GridItem {...mergeStyles?.productPropertiesCheckboxGridItem}>
                                    <Checkbox
                                        onChange={(_, checked) =>
                                            onPropertiesToPrintCheckboxChange(checked, "ManufacturerItem")
                                        }
                                        checked={productPropertiesToPrint.includes("ManufacturerItem")}
                                        {...mergeStyles?.productPropertyCheckbox}
                                    >
                                        {translate("Manufacturer Number")}
                                    </Checkbox>
                                    <Checkbox
                                        onChange={(_, checked) =>
                                            onPropertiesToPrintCheckboxChange(checked, "CustomerName")
                                        }
                                        checked={productPropertiesToPrint.includes("CustomerName")}
                                        {...mergeStyles?.productPropertyCheckbox}
                                    >
                                        {translate("My Part Number")}
                                    </Checkbox>
                                </GridItem>
                            </GridContainer>
                        </GridItem>
                    </>
                )}
                <GridItem {...mergeStyles?.buttonsGridItem}>
                    <Button
                        {...mergeStyles?.cancelButton}
                        onClick={() => {
                            handleCancelClick();
                        }}
                    >
                        {translate("Cancel")}
                    </Button>
                    <Button
                        {...mergeStyles?.submitButton}
                        onClick={handlePrintClick}
                        data-test-selector="productListPrintModal_print_btn"
                    >
                        {translate("Print")}
                    </Button>
                </GridItem>
            </GridContainer>
        </Modal>
    );
};

export default withToaster(ProductListPrintModal);
