import { getCookie } from "@insite/client-framework/Common/Cookies";
import parseQueryString from "@insite/client-framework/Common/Utilities/parseQueryString";
import Zone from "@insite/client-framework/Components/Zone";
import { GetVmiLocationsApiParameter } from "@insite/client-framework/Services/VmiLocationService";
import siteMessage from "@insite/client-framework/SiteMessage";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getLocation } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import loadVmiBins from "@insite/client-framework/Store/Data/VmiBins/Handlers/LoadVmiBins";
import {
    getVmiBinsDataView,
    VmiBinsDataViewContext,
} from "@insite/client-framework/Store/Data/VmiBins/VmiBinsSelectors";
import loadVmiLocations from "@insite/client-framework/Store/Data/VmiLocations/Handlers/LoadVmiLocations";
import {
    getVmiLocationsDataView,
    getVmiLocationState,
} from "@insite/client-framework/Store/Data/VmiLocations/VmiLocationsSelectors";
import updateSearchFields from "@insite/client-framework/Store/Pages/VmiReporting/Handlers/UpdateSearchFields";
import PageModule from "@insite/client-framework/Types/PageModule";
import PageProps from "@insite/client-framework/Types/PageProps";
import { PageErrorWrapper } from "@insite/content-library/Components/PageErrorWrapper";
import Page from "@insite/mobius/Page";
import { TypographyPresentationProps } from "@insite/mobius/Typography";
import getColor from "@insite/mobius/utilities/getColor";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import * as React from "react";
import { useEffect } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const mapStateToProps = (state: ApplicationState) => {
    const location = getLocation(state);
    const parsedQuery = parseQueryString<{ locationId?: string; metric?: string }>(location.search);
    const vmiLocationState = getVmiLocationState(state, parsedQuery.locationId);
    const getVmiLocationsParameter = {
        filter: "",
        sort: "Name",
        expand: ["customerlabel"],
        page: 1,
        pageSize: 9999, // need to get all locations
    } as GetVmiLocationsApiParameter;
    return {
        vmiLocationState,
        vmiBinsDataView: getVmiBinsDataView(state, state.pages.vmiReporting.getVmiBinsParameter),
        getVmiBinsParameter: state.pages.vmiReporting.getVmiBinsParameter,
        vmiLocationsDataView: getVmiLocationsDataView(state, getVmiLocationsParameter),
        getVmiLocationsParameter,
        parsedQuery,
    };
};

const mapDispatchToProps = {
    loadVmiBins,
    loadVmiLocations,
    updateSearchFields,
};

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

export interface VmiReportingPageStyles {
    loadFailedWrapper?: InjectableCss;
    loadFailedText?: TypographyPresentationProps;
}

export const vmiReportingPageStyles: VmiReportingPageStyles = {
    loadFailedWrapper: {
        css: css`
            display: flex;
            height: 200px;
            justify-content: center;
            align-items: center;
            background-color: ${getColor("common.accent")};
        `,
    },
    loadFailedText: { weight: "bold" },
};
const styles = vmiReportingPageStyles;

const VmiReportingPage = ({
    id,
    vmiLocationState,
    vmiBinsDataView,
    loadVmiBins,
    vmiLocationsDataView,
    loadVmiLocations,
    updateSearchFields,
    getVmiBinsParameter,
    getVmiLocationsParameter,
    parsedQuery,
}: Props) => {
    useEffect(() => {
        const pageSizeCookie = getCookie("VmiReporting-PageSize");
        const pageSize = pageSizeCookie ? parseInt(pageSizeCookie, 10) : undefined;
        if (pageSize && pageSize !== getVmiBinsParameter.pageSize) {
            updateSearchFields({ pageSize });
            return;
        }

        if (parsedQuery.locationId && parsedQuery.locationId !== getVmiBinsParameter.vmiLocationId) {
            updateSearchFields({ vmiLocationId: parsedQuery.locationId });
            return;
        }

        if (parsedQuery.metric && parsedQuery.metric !== getVmiBinsParameter.metric) {
            updateSearchFields({
                metric: parsedQuery.metric,
                isBelowMinimum: parsedQuery.metric === "belowminimum",
                numberOfPreviousOrders: parsedQuery.metric === "slowmoving" ? 0 : undefined,
                numberOfTimesMinQtyReached: parsedQuery.metric === "fastmoving" ? 2 : undefined,
                numberOfVisits:
                    parsedQuery.metric === "allproducts" || parsedQuery.metric === "belowminimum"
                        ? undefined
                        : parsedQuery.metric === "slowmoving"
                        ? 2
                        : 4,
            });
            return;
        }

        if (!parsedQuery?.locationId && getVmiBinsParameter.vmiLocationId) {
            updateSearchFields({ vmiLocationId: undefined });
            return;
        }

        if (
            !vmiBinsDataView.value &&
            !vmiBinsDataView.isLoading &&
            getVmiBinsParameter.vmiLocationId &&
            getVmiBinsParameter.vmiLocationId !== "0" &&
            getVmiBinsParameter.metric
        ) {
            loadVmiBins(getVmiBinsParameter);
        }

        if (!vmiLocationsDataView.value && !vmiLocationsDataView.isLoading) {
            loadVmiLocations(getVmiLocationsParameter);
        }

        document.body.style.overflowX = "hidden";
        return () => {
            document.body.style.overflowX = "auto";
        };
    });

    return (
        <Page>
            <PageErrorWrapper
                value={vmiLocationState}
                extendedStyles={styles}
                notFoundMessage={siteMessage("Vmi_VmiLocationNotFound")}
            >
                <VmiBinsDataViewContext.Provider value={vmiBinsDataView}>
                    <Zone contentId={id} zoneName="Content" />
                </VmiBinsDataViewContext.Provider>
            </PageErrorWrapper>
        </Page>
    );
};

const pageModule: PageModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(VmiReportingPage),
    definition: {
        hasEditableUrlSegment: true,
        hasEditableTitle: true,
        pageType: "System",
    },
};

export default pageModule;
