import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import parseQueryString from "@insite/client-framework/Common/Utilities/parseQueryString";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import getAutocompleteModel from "@insite/client-framework/Store/CommonHandlers/GetAutocompleteModel";
import { getLocation } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import { getPageLinkByPageType } from "@insite/client-framework/Store/Links/LinksSelectors";
import updateSearchFields from "@insite/client-framework/Store/Pages/VmiReporting/Handlers/UpdateSearchFields";
import translate from "@insite/client-framework/Translate";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import Link, { LinkPresentationProps } from "@insite/mobius/Link";
import Select, { SelectProps } from "@insite/mobius/Select";
import TextField, { TextFieldPresentationProps } from "@insite/mobius/TextField";
import Typography, { TypographyPresentationProps } from "@insite/mobius/Typography";
import { HasHistory, withHistory } from "@insite/mobius/utilities/HistoryContext";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import React from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const metricOptions: { id: string; name: string }[] = [
    { id: "allproducts", name: translate("All Products") },
    { id: "belowminimum", name: translate("Below Minimum") },
    { id: "slowmoving", name: translate("Slow Moving") },
    { id: "fastmoving", name: translate("Fast Moving") },
];

interface State {
    numberOfPreviousOrders: number | undefined;
    numberOfTimesMinQtyReached: number | undefined;
    numberOfVisits: number | undefined;
}

const mapStateToProps = (state: ApplicationState) => {
    const location = getLocation(state);
    const parsedQuery = parseQueryString<{ locationid?: string; metric?: string }>(location.search?.toLowerCase());
    const { metric, numberOfPreviousOrders, numberOfTimesMinQtyReached, numberOfVisits } =
        state.pages.vmiReporting.getVmiBinsParameter;

    return {
        getVmiBinsParameter: state.pages.vmiReporting.getVmiBinsParameter,
        vmiReportingPageUrl: getPageLinkByPageType(state, "VmiReportingPage")?.url,
        parsedQuery,
        metric,
        numberOfPreviousOrders,
        numberOfTimesMinQtyReached,
        numberOfVisits,
    };
};

const mapDispatchToProps = {
    getAutocompleteModel,
    updateSearchFields,
};

export interface VmiBinsMetricFilterStyles {
    container?: GridContainerProps;
    metricSelectGridItem?: GridItemProps;
    select?: SelectProps;
    filtersGridItem?: GridItemProps;
    labelWrapper?: InjectableCss;
    labelText?: TypographyPresentationProps;
    resetLink?: LinkPresentationProps;
    filterWrapper?: InjectableCss;
    filterTextField?: TextFieldPresentationProps;
}

export const vmiBinsMetricFilterStyles: VmiBinsMetricFilterStyles = {
    metricSelectGridItem: { width: [6, 6, 5, 3, 3] },
    filtersGridItem: {
        width: [12, 12, 12, 9, 9],
        css: css`
            flex-direction: column;
        `,
    },
    labelWrapper: {
        css: css`
            display: flex;
        `,
    },
    labelText: {
        variant: "h6",
        css: css`
            margin-bottom: 0.5rem;
        `,
    },
    resetLink: {
        css: css`
            margin-left: 100px;
        `,
    },
    filterWrapper: {
        css: css`
            display: flex;
        `,
    },
    filterTextField: {
        labelProps: {
            variant: "p",
            size: 14,
            css: css`
                white-space: break-spaces;
                padding: 0 10px 0 0;
                text-align: left;
                width: fit-content;
            `,
        },
        cssOverrides: {
            inputSelect: css`
                width: 65px;
            `,
            formInputWrapper: css`
                margin-right: 10px;
                width: auto;
            `,
            formField: css`
                width: auto;
                align-items: center;
            `,
        },
    },
};
const styles = vmiBinsMetricFilterStyles;

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

class VmiBinsMetricFilter extends React.Component<Props, State> {
    setMetric = (metric: string) => {
        if (this.props.vmiReportingPageUrl) {
            const params = new URLSearchParams();

            const locationId = this.props.parsedQuery?.locationid?.toLowerCase();
            if (locationId) {
                params.append("locationId", locationId);
            }

            if (metric) {
                params.append("metric", metric);
            }

            const newLocation = params.toString();
            if (newLocation) {
                this.props.history.push(`${this.props.vmiReportingPageUrl}?${newLocation}`);
            }
        }
    };

    metricChangeHandler = (event: React.FormEvent<HTMLSelectElement>) => {
        this.props.updateSearchFields({ page: 1 });
        this.setMetric(event.currentTarget.value);
    };

    resetFilter = () => {
        this.setState(
            {
                numberOfPreviousOrders: 0,
                numberOfTimesMinQtyReached: 2,
                numberOfVisits: this.props.metric === "slowmoving" ? 2 : 4,
            },
            this.updateParameter,
        );
    };

    numberOfPreviousOrdersChangeHandler = (event: React.FormEvent<HTMLInputElement>): void => {
        this.setState({ numberOfPreviousOrders: Number(event.currentTarget.value) }, this.updateParameter);
    };

    numberOfTimesMinQtyReachedChangeHandler = (event: React.FormEvent<HTMLInputElement>): void => {
        this.setState({ numberOfTimesMinQtyReached: Number(event.currentTarget.value) }, this.updateParameter);
    };

    numberOfVisitsChangeHandler = (event: React.FormEvent<HTMLInputElement>): void => {
        this.setState({ numberOfVisits: Number(event.currentTarget.value) }, this.updateParameter);
    };

    updateParameter = () => {
        const { numberOfPreviousOrders, numberOfTimesMinQtyReached, numberOfVisits } = this.state;
        this.props.updateSearchFields({
            isBelowMinimum: this.props.metric === "belowminimum",
            numberOfPreviousOrders: this.props.metric === "slowmoving" ? numberOfPreviousOrders : undefined,
            numberOfTimesMinQtyReached: this.props.metric === "fastmoving" ? numberOfTimesMinQtyReached : undefined,
            numberOfVisits:
                this.props.metric === "fastmoving" || this.props.metric === "slowmoving" ? numberOfVisits : undefined,
        });
    };

    render() {
        const metric = this.props.metric;

        return (
            <GridContainer {...styles.container}>
                <GridItem {...styles.metricSelectGridItem}>
                    <Select
                        label={translate("Metric")}
                        {...styles.select}
                        value={metric}
                        onChange={this.metricChangeHandler}
                    >
                        {metricOptions.map(option => (
                            <option key={option.id} value={option.id}>
                                {/* eslint-disable-next-line spire/avoid-dynamic-translate */}
                                {option.name}
                            </option>
                        ))}
                    </Select>
                </GridItem>
                {(metric === "slowmoving" || metric === "fastmoving") && (
                    <GridItem {...styles.filtersGridItem}>
                        <StyledWrapper {...styles.labelWrapper}>
                            <Typography as="h5" {...styles.labelText}>
                                {metric === "slowmoving"
                                    ? translate("Filter Slow Moving Products")
                                    : translate("Filter Fast Moving Products")}
                            </Typography>
                            <Link {...styles.resetLink} onClick={this.resetFilter}>
                                {translate("Reset to defaults")}
                            </Link>
                        </StyledWrapper>
                        <StyledWrapper {...styles.filterWrapper}>
                            {metric === "slowmoving" && (
                                <TextField
                                    label={translate("# of previous orders")}
                                    value={this.props.numberOfPreviousOrders}
                                    type="number"
                                    labelPosition="left"
                                    onChange={this.numberOfPreviousOrdersChangeHandler}
                                    {...styles.filterTextField}
                                ></TextField>
                            )}
                            {metric === "fastmoving" && (
                                <TextField
                                    label={translate("# of times min. QTY reached")}
                                    value={this.props.numberOfTimesMinQtyReached}
                                    type="number"
                                    labelPosition="left"
                                    onChange={this.numberOfTimesMinQtyReachedChangeHandler}
                                    {...styles.filterTextField}
                                ></TextField>
                            )}
                            <TextField
                                label={translate("# of visits")}
                                value={this.props.numberOfVisits}
                                type="number"
                                labelPosition="left"
                                onChange={this.numberOfVisitsChangeHandler}
                                {...styles.filterTextField}
                            ></TextField>
                        </StyledWrapper>
                    </GridItem>
                )}
            </GridContainer>
        );
    }
}

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(withHistory(VmiBinsMetricFilter)),
    definition: {
        group: "VMI Reporting",
        allowedContexts: ["VmiReportingPage"],
    },
};

export default widgetModule;
