import { convertDateToDateOnlyString } from "@insite/client-framework/Common/Utilities/DateUtilities";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import getAutocompleteModel from "@insite/client-framework/Store/CommonHandlers/GetAutocompleteModel";
import loadWishListsData from "@insite/client-framework/Store/Data/WishLists/Handlers/LoadWishLists";
import clearSearch from "@insite/client-framework/Store/Pages/MyLists/Handlers/ClearSearch";
import updateLoadParameter from "@insite/client-framework/Store/Pages/MyLists/Handlers/UpdateLoadParameter";
import translate from "@insite/client-framework/Translate";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import MyListsSearchFieldBrand from "@insite/content-library/Widgets/MyLists/MyListsSearchFieldBrand";
import MyListsSearchFieldProductNumber from "@insite/content-library/Widgets/MyLists/MyListsSearchFieldProductNumber";
import MyListsSearchFieldSharedBy from "@insite/content-library/Widgets/MyLists/MyListsSearchFieldSharedBy";
import { SearchFieldWrapperStyles } from "@insite/content-library/Widgets/MyLists/SearchFieldWrapper";
import Button, { ButtonProps } from "@insite/mobius/Button";
import DatePicker, { DatePickerPresentationProps, DatePickerState } from "@insite/mobius/DatePicker";
import { DynamicDropdownPresentationProps } from "@insite/mobius/DynamicDropdown";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import Typography, { TypographyPresentationProps } from "@insite/mobius/Typography";
import * as React from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const enum fields {
    showCreatedDate = "showCreatedDate",
    showUpdatedOn = "showUpdatedOn",
    showProduct = "showProduct",
    showBrand = "showBrand",
    showSharedBy = "showSharedBy",
}

interface OwnProps extends WidgetProps {
    fields: {
        [fields.showCreatedDate]: boolean;
        [fields.showUpdatedOn]: boolean;
        [fields.showProduct]: boolean;
        [fields.showBrand]: boolean;
        [fields.showSharedBy]: boolean;
    };
}

const mapStateToProps = (state: ApplicationState) => ({
    filtersOpen: state.pages.myLists.filtersOpen,
    getWishListsParameter: state.pages.myLists.getWishListsParameter,
});

const mapDispatchToProps = {
    updateLoadParameter,
    loadWishListsData,
    clearSearch,
    getAutocompleteModel,
};

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

export interface MyListsFilterStyles {
    container?: GridContainerProps;
    heading?: TypographyPresentationProps;
    headingItem?: GridItemProps;
    wrapper?: SearchFieldWrapperStyles;
    searchDynamicDropdown?: DynamicDropdownPresentationProps;
    autocompleteGridItem?: GridItemProps;
    fromGridItem?: GridItemProps;
    fromDate?: DatePickerPresentationProps;
    toDate?: DatePickerPresentationProps;
    toGridItem?: GridItemProps;
    buttonsItem?: GridItemProps;
    clearFilterGrid?: GridItemProps;
    clearFiltersButton?: ButtonProps;
}

export const filterStyles: MyListsFilterStyles = {
    container: {
        css: css`
            padding-bottom: 15px;
        `,
    },
    headingItem: {
        width: 12,
        css: css`
            padding-bottom: 0;
        `,
    },
    heading: {
        variant: "h5",
        css: css`
            margin: 0;
        `,
    },
    autocompleteGridItem: {
        width: [12, 12, 3, 3, 4],
        css: css`
            padding: 2px 10px 10px 5px;
        `,
    },
    fromGridItem: { width: [6, 6, 3, 3, 2] },
    toGridItem: {
        width: [6, 6, 3, 3, 2],
        css: css`
            padding-left: 0;
        `,
    },
    clearFilterGrid: {
        width: 12,
        css: css`
            justify-content: flex-end;
        `,
    },
    fromDate: {
        cssOverrides: {
            formField: css`
                width: 100%;
            `,
        },
    },
    toDate: {
        cssOverrides: {
            formField: css`
                width: 100%;
                margin-top: 32px;
            `,
        },
    },
    clearFiltersButton: {
        variant: "secondary",
        css: css`
            float: right;
        `,
    },
};

const styles = filterStyles;

const MyListsFilter = ({
    fields,
    getWishListsParameter,
    filtersOpen,
    updateLoadParameter,
    loadWishListsData,
    clearSearch,
    getAutocompleteModel,
}: Props) => {
    const fromCreatedDateChangeHandler = ({ selectedDay }: Pick<DatePickerState, "selectedDay">) => {
        updateLoadParameter({
            fromCreatedDate: convertDateToDateOnlyString(selectedDay),
        });
    };

    const toCreatedDateChangeHandler = ({ selectedDay }: Pick<DatePickerState, "selectedDay">) => {
        updateLoadParameter({
            toCreatedDate: convertDateToDateOnlyString(selectedDay),
        });
    };

    const fromUpdatedOnChangeHandler = ({ selectedDay }: Pick<DatePickerState, "selectedDay">) => {
        updateLoadParameter({
            fromUpdatedOn: convertDateToDateOnlyString(selectedDay),
        });
    };

    const toUpdatedOnChangeHandler = ({ selectedDay }: Pick<DatePickerState, "selectedDay">) => {
        updateLoadParameter({
            toUpdatedOn: convertDateToDateOnlyString(selectedDay),
        });
    };

    const clearFiltersClickHandler = () => {
        clearSearch();
    };

    if (!filtersOpen) {
        return null;
    }

    const fromCreatedDate = getWishListsParameter.fromCreatedDate
        ? new Date(getWishListsParameter.fromCreatedDate.replace(/-/g, "/"))
        : undefined;
    const toCreatedDate = getWishListsParameter.toCreatedDate
        ? new Date(getWishListsParameter.toCreatedDate.replace(/-/g, "/"))
        : undefined;

    const fromUpdatedOn = getWishListsParameter.fromUpdatedOn
        ? new Date(getWishListsParameter.fromUpdatedOn.replace(/-/g, "/"))
        : undefined;
    const toUpdatedOn = getWishListsParameter.toUpdatedOn
        ? new Date(getWishListsParameter.toUpdatedOn.replace(/-/g, "/"))
        : undefined;

    return (
        <GridContainer {...styles.container} data-test-selector="myLists_filter">
            <GridItem {...styles.headingItem} data-test-selector="myLists_filterHeader">
                <Typography as="h2" {...styles.heading}>
                    {translate("Filter")}
                </Typography>
            </GridItem>
            {fields.showCreatedDate !== false && (
                <>
                    <GridItem {...styles.fromGridItem} data-test-selector="myLists_fromCreatedDate">
                        <DatePicker
                            {...styles.fromDate}
                            label={translate("Date Created")}
                            selectedDay={fromCreatedDate}
                            onDayChange={fromCreatedDateChangeHandler}
                            dateTimePickerProps={{
                                clearIcon: null,
                                maxDate: toCreatedDate,
                                ...styles.fromDate?.dateTimePickerProps,
                            }}
                        />
                    </GridItem>
                    <GridItem {...styles.toGridItem} data-test-selector="myLists_toCreatedDate">
                        <DatePicker
                            {...styles.toDate}
                            selectedDay={toCreatedDate}
                            onDayChange={toCreatedDateChangeHandler}
                            dateTimePickerProps={{
                                clearIcon: null,
                                minDate: fromCreatedDate,
                                ...styles.toDate?.dateTimePickerProps,
                            }}
                        />
                    </GridItem>
                </>
            )}
            {fields.showUpdatedOn !== false && (
                <>
                    <GridItem {...styles.fromGridItem} data-test-selector="myLists_fromUpdatedOn">
                        <DatePicker
                            {...styles.fromDate}
                            label={translate("Updated On")}
                            selectedDay={fromUpdatedOn}
                            onDayChange={fromUpdatedOnChangeHandler}
                            dateTimePickerProps={{
                                clearIcon: null,
                                maxDate: toUpdatedOn,
                                ...styles.fromDate?.dateTimePickerProps,
                            }}
                        />
                    </GridItem>
                    <GridItem {...styles.toGridItem} data-test-selector="myLists_toUpdatedOn">
                        <DatePicker
                            {...styles.toDate}
                            selectedDay={toUpdatedOn}
                            onDayChange={toUpdatedOnChangeHandler}
                            dateTimePickerProps={{
                                clearIcon: null,
                                minDate: fromUpdatedOn,
                                ...styles.toDate?.dateTimePickerProps,
                            }}
                        />
                    </GridItem>
                </>
            )}
            {fields.showSharedBy !== false && (
                <GridItem {...styles.autocompleteGridItem} data-test-selector="myLists_sharedBy">
                    <MyListsSearchFieldSharedBy
                        getWishListsParameter={getWishListsParameter}
                        updateLoadParameter={updateLoadParameter}
                        loadWishListsData={loadWishListsData}
                    />
                </GridItem>
            )}
            {fields.showProduct !== false && (
                <GridItem {...styles.autocompleteGridItem} data-test-selector="myLists_product">
                    <MyListsSearchFieldProductNumber
                        getWishListsParameter={getWishListsParameter}
                        updateLoadParameter={updateLoadParameter}
                    />
                </GridItem>
            )}
            {fields.showBrand !== false && (
                <GridItem {...styles.autocompleteGridItem} data-test-selector="myLists_brand">
                    <MyListsSearchFieldBrand
                        getWishListsParameter={getWishListsParameter}
                        updateLoadParameter={updateLoadParameter}
                        getAutocompleteModel={getAutocompleteModel}
                    />
                </GridItem>
            )}
            <GridItem {...styles.clearFilterGrid}>
                <Button
                    {...styles.clearFiltersButton}
                    onClick={clearFiltersClickHandler}
                    data-test-selector="myLists_clearFiltersButton"
                >
                    {translate("Clear Filters")}
                </Button>
            </GridItem>
        </GridContainer>
    );
};

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(MyListsFilter),
    definition: {
        group: "My Lists",
        displayName: "My Lists Filter",
        allowedContexts: ["MyListsPage"],
        fieldDefinitions: [
            {
                name: fields.showCreatedDate,
                displayName: "Date Created",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "General",
                sortOrder: 1,
            },
            {
                name: fields.showUpdatedOn,
                displayName: "Updated On",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "General",
                sortOrder: 2,
            },
            {
                name: fields.showSharedBy,
                displayName: "Shared By",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "General",
                sortOrder: 3,
            },
            {
                name: fields.showProduct,
                displayName: "Product",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "General",
                sortOrder: 4,
            },
            {
                name: fields.showBrand,
                displayName: "Brand",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "General",
                sortOrder: 5,
            },
        ],
    },
};

export default widgetModule;
