import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import parseQueryString from "@insite/client-framework/Common/Utilities/parseQueryString";
import { GetVmiLocationsApiParameter } from "@insite/client-framework/Services/VmiLocationService";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getLocation } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import { getVmiLocationsDataView } from "@insite/client-framework/Store/Data/VmiLocations/VmiLocationsSelectors";
import { getPageLinkByPageType } from "@insite/client-framework/Store/Links/LinksSelectors";
import toggleFiltersOpen from "@insite/client-framework/Store/Pages/VmiReporting/Handlers/ToggleFiltersOpen";
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 Button, { ButtonIcon, ButtonIconPresentationProps, ButtonPresentationProps } from "@insite/mobius/Button";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import { IconProps } from "@insite/mobius/Icon";
import Filter from "@insite/mobius/Icons/Filter";
import LoadingSpinner, { LoadingSpinnerProps } from "@insite/mobius/LoadingSpinner";
import Select, { SelectPresentationProps } from "@insite/mobius/Select";
import Typography, { TypographyPresentationProps } from "@insite/mobius/Typography";
import { HasHistory, withHistory } from "@insite/mobius/utilities/HistoryContext";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import React, { useEffect, useState } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const mapStateToProps = (state: ApplicationState) => {
    const getVmiLocationsParameter = {
        filter: "",
        sort: "Name",
        expand: ["customerlabel"],
        page: 1,
        pageSize: 9999, // need to get all locations
    } as GetVmiLocationsApiParameter;

    const location = getLocation(state);
    const parsedQuery = parseQueryString<{ locationid?: string; metric?: string }>(location.search?.toLowerCase());

    return {
        vmiLocationsDataView: getVmiLocationsDataView(state, getVmiLocationsParameter),
        vmiReportingPageUrl: getPageLinkByPageType(state, "VmiReportingPage")?.url,
        vmiLocationId: state.pages.vmiReporting.getVmiBinsParameter.vmiLocationId,
        parsedQuery,
    };
};

const mapDispatchToProps = {
    toggleFiltersOpen,
    updateSearchFields,
};

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

export interface VmiLocationsHeaderStyles {
    centeringWrapper?: InjectableCss;
    spinner?: LoadingSpinnerProps;
    gridContainer?: GridContainerProps;
    titleGridItem?: GridItemProps;
    titleText?: TypographyPresentationProps;
    container?: GridContainerProps;
    locationSwitcherGridItem?: GridItemProps;
    locationSwitcherGridItem2?: GridItemProps;
    locationSelect?: SelectPresentationProps;
    toggleFilterGridItem?: GridItemProps;
    /** @deprecated Use toggleFilterButtonIcon instead. */
    toggleFilterIcon?: IconProps;
    toggleFilterButton?: ButtonPresentationProps;
    toggleFilterButtonIcon?: ButtonIconPresentationProps;
}

export const headerStyles: VmiLocationsHeaderStyles = {
    centeringWrapper: {
        css: css`
            height: 100px;
            display: flex;
            align-items: center;
        `,
    },
    spinner: {
        css: css`
            margin: auto;
        `,
    },
    titleGridItem: {
        width: [10, 10, 8, 9, 9],
    },
    titleText: {
        variant: "h2",
    },
    container: {
        gap: 8,
        css: css`
            padding-bottom: 10px;
        `,
        style: { flexDirection: "row-reverse" },
    },
    locationSwitcherGridItem: {
        css: css`
            justify-content: flex-end;
        `,
        width: [2, 2, 4, 3, 3],
    },
    locationSelect: {
        cssOverrides: {
            formInputWrapper: css`
                width: 200px;
                align-self: end;
            `,
            inputSelect: css`
                text-transform: uppercase;
            `,
        },
    },
    toggleFilterGridItem: {
        width: [12, 12, 12, 12, 12],
        style: { marginTop: "8px", justifyContent: "flex-end", alignSelf: "center" },
    },
    toggleFilterButton: {
        color: "common.background",
        shape: "pill",
        buttonType: "solid",
        shadow: false,
        css: css`
            width: 40px;
            padding: 0;
        `,
    },
    toggleFilterButtonIcon: {
        src: Filter,
        size: 24,
    },
};

const styles = headerStyles;

const VmiReportingHeader = ({
    vmiLocationsDataView,
    vmiLocationId,
    parsedQuery,
    vmiReportingPageUrl,
    toggleFiltersOpen,
    history,
}: Props) => {
    useEffect(() => {
        if (!vmiLocationsDataView || !vmiLocationsDataView.value || vmiLocationsDataView.isLoading) {
            return;
        }
        if (vmiLocations?.value && vmiLocations.value.length > 0 && !parsedQuery?.locationid) {
            setLocation(vmiLocations.value[0].id, true);
        }
    });

    const setLocation = (locationId: string, replace = false) => {
        const params = new URLSearchParams();
        params.append("locationId", locationId);

        const metric = parsedQuery?.metric;
        if (metric) {
            params.append("metric", metric);
        } else {
            params.append("metric", "allproducts");
        }

        const newLocation = params.toString();
        if (!replace) {
            history.push(`${vmiReportingPageUrl}?${newLocation}`);
        } else {
            history.replace(`${vmiReportingPageUrl}?${newLocation}`);
        }
    };

    if (!vmiLocationsDataView.value || vmiLocationsDataView.isLoading) {
        return (
            <StyledWrapper {...styles.centeringWrapper}>
                <LoadingSpinner {...styles.spinner} />
            </StyledWrapper>
        );
    }

    const vmiLocations = vmiLocationsDataView;
    let currentLocation = null;
    if (vmiLocations?.value && vmiLocations.value.length > 0) {
        const locationId = parsedQuery?.locationid?.toLowerCase() || vmiLocationId;
        currentLocation = locationId
            ? vmiLocations.value.find((location: any) => location.id?.toLowerCase() === locationId)
            : null;
    }

    return (
        <>
            <GridContainer {...styles.gridContainer}>
                <GridItem {...styles.titleGridItem}>
                    <Typography as="h2" {...styles.titleText}>
                        {translate("Reporting")}
                    </Typography>
                </GridItem>
                {vmiLocationsDataView && vmiLocationsDataView.value && (
                    <GridItem {...styles.locationSwitcherGridItem}>
                        <Select
                            {...styles.locationSelect}
                            data-test-selector="locationSelector"
                            onChange={event => {
                                setLocation(event.currentTarget.value);
                            }}
                            value={currentLocation?.id ?? ""}
                            hasLabel
                        >
                            <option value="0">{translate("Select Location")}</option>
                            {vmiLocationsDataView.value.map(c => (
                                <option value={c.id} key={c.id}>
                                    {c.name}
                                </option>
                            ))}
                        </Select>
                    </GridItem>
                )}
            </GridContainer>
            <GridContainer {...styles.container}>
                <GridItem {...styles.toggleFilterGridItem}>
                    <Button {...styles.toggleFilterButton} onClick={() => toggleFiltersOpen()}>
                        <ButtonIcon {...styles.toggleFilterButtonIcon} />
                    </Button>
                </GridItem>
            </GridContainer>
        </>
    );
};

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

export default widgetModule;
