import parseQueryStringCaseInsensitive from "@insite/client-framework/Common/Utilities/parseQueryStringCaseInsensitive";
import Zone from "@insite/client-framework/Components/Zone";
import siteMessage from "@insite/client-framework/SiteMessage";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getOrderState, OrderStateContext } from "@insite/client-framework/Store/Data/Orders/OrdersSelectors";
import loadOrderStatusMappings from "@insite/client-framework/Store/Data/OrderStatusMappings/Handlers/LoadOrderStatusMappings";
import { getOrderStatusMappingDataView } from "@insite/client-framework/Store/Data/OrderStatusMappings/OrderStatusMappingsSelectors";
import { getLocation } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import displayOrder from "@insite/client-framework/Store/Pages/OrderDetails/Handlers/DisplayOrder";
import resetOrderNumber from "@insite/client-framework/Store/Pages/OrderDetails/Handlers/ResetOrderNumber";
import setVmiOrderDetailsPage from "@insite/client-framework/Store/Pages/OrderDetails/Handlers/SetVmiOrderDetailsPage";
import PageModule from "@insite/client-framework/Types/PageModule";
import PageProps from "@insite/client-framework/Types/PageProps";
import Modals from "@insite/content-library/Components/Modals";
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 { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const mapStateToProps = (state: ApplicationState) => {
    const location = getLocation(state);
    let orderNumber;
    let isVmiOrder = false;
    if (location && location.search) {
        const parsedQuery = parseQueryStringCaseInsensitive(location.search, {
            orderNumber: "",
            isVmiOrder: false,
        });
        orderNumber = parsedQuery.orderNumber;
        isVmiOrder = parsedQuery.isVmiOrder;
    }

    const orderState = getOrderState(state, orderNumber);
    const orderStatusMappingDataView = getOrderStatusMappingDataView(state);
    const isOrderNumberStoredInState = state.pages.orderDetails.orderNumber === orderNumber;

    return {
        orderNumber,
        orderState,
        shouldDisplayOrder: !isOrderNumberStoredInState,
        shouldLoadOrderStatusMappings: !orderStatusMappingDataView.value && !orderStatusMappingDataView.isLoading,
        isVmiOrder,
        isVmiOrderDetailsPage: state.pages.orderDetails.isVmiOrderDetailsPage,
    };
};

const mapDispatchToProps = {
    displayOrder,
    loadOrderStatusMappings,
    setVmiOrderDetailsPage,
    resetOrderNumber,
};

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

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

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

class OrderDetailsPage extends React.Component<Props> {
    UNSAFE_componentWillMount() {
        // The share entity (for orders) functionality can use this page
        // to render HTML for PDF generation, so we need to leave this SSR
        // ability so that functionality works.
        if (this.props.shouldLoadOrderStatusMappings) {
            this.props.loadOrderStatusMappings();
        }
        if (this.props.orderNumber && this.props.shouldDisplayOrder) {
            this.props.displayOrder({
                orderNumber: this.props.orderNumber,
                expand: this.props.isVmiOrder ? ["orderLines", "shipments", "vmidetails"] : ["orderLines", "shipments"],
            });
        }
        if (this.props.isVmiOrderDetailsPage) {
            this.props.setVmiOrderDetailsPage(false);
        }
    }

    componentWillUnmount() {
        this.props.resetOrderNumber();
    }

    render() {
        return (
            <Page>
                <PageErrorWrapper
                    value={this.props.orderState}
                    badRequestMessage={siteMessage("Order_BadRequest")}
                    notAuthorizedMessage={siteMessage("Order_NotAuthorized")}
                    notFoundMessage={siteMessage("Order_NotFound")}
                    extendedStyles={orderDetailsPageStyles}
                    loadFailedTextTestSelector="orderDetails_pageNotFound"
                >
                    <OrderStateContext.Provider value={this.props.orderState}>
                        <Zone contentId={this.props.id} zoneName="Content" />
                    </OrderStateContext.Provider>
                </PageErrorWrapper>
                <Modals />
            </Page>
        );
    }
}

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

export default pageModule;

/**
 * @deprecated Use string literal "OrderDetailsPage" instead of this constant.
 */
export const OrderDetailsPageContext = "OrderDetailsPage";
