import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getCurrentUserIsGuest, getSettingsCollection } from "@insite/client-framework/Store/Context/ContextSelectors";
import { getLocation, getReturnUrl } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import { getPageLinkByPageType } from "@insite/client-framework/Store/Links/LinksSelectors";
import signInAsGuest from "@insite/client-framework/Store/Pages/SignIn/Handlers/SignInAsGuest";
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, { ButtonPresentationProps } from "@insite/mobius/Button";
import { BaseTheme } from "@insite/mobius/globals/baseTheme";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import Typography, { TypographyProps } from "@insite/mobius/Typography/Typography";
import breakpointMediaQueries from "@insite/mobius/utilities/breakpointMediaQueries";
import { HasHistory, withHistory } from "@insite/mobius/utilities/HistoryContext";
import React, { FC } from "react";
import { connect, ResolveThunks } from "react-redux";
import { css } from "styled-components";

const enum fields {
    text = "text",
    fullWidthButton = "fullWidthButton",
}

const mapStateToProps = (state: ApplicationState) => {
    let { search } = getLocation(state);
    const { allowCreateAccount, allowGuestCheckout } = getSettingsCollection(state).accountSettings;
    let returnUrl = getReturnUrl(state);
    if (!returnUrl && state.components.signInOverlay.isOpen) {
        returnUrl = getLocation(state).pathname;
        if (!search) {
            search = `?returnUrl=${returnUrl}`;
        }
    }

    const shippingPageUrl = getPageLinkByPageType(state, "CheckoutShippingPage")?.url;
    const referredFromShipping = returnUrl === shippingPageUrl;
    const onePageCheckoutPageUrl = getPageLinkByPageType(state, "OnePageCheckoutPage")?.url;
    const referredFromOnePageCheckout = returnUrl === onePageCheckoutPageUrl;
    const createAccountPageLink = getPageLinkByPageType(state, "CreateAccountPage");
    return {
        allowCreateAccount,
        allowGuestCheckout:
            allowGuestCheckout &&
            !getCurrentUserIsGuest(state) &&
            (referredFromShipping || referredFromOnePageCheckout),
        returnUrl,
        createAccountUrl: createAccountPageLink ? `${createAccountPageLink.url}${search}` : undefined,
    };
};

const mapDispatchToProps = {
    signInAsGuest,
};

interface OwnProps extends WidgetProps {
    fields: {
        [fields.text]: string;
        [fields.fullWidthButton]: boolean;
    };
}

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

export interface SignInCreateNewAccountStyles {
    signInCreateNewAccountGridContainer?: GridContainerProps;
    signInCreateNewAccountTitleGridItem?: GridItemProps;
    signInCreateNewAccountTextGridItem?: GridItemProps;
    signInCreateNewAccountButtonGridItem?: GridItemProps;
    signInCreateNewAccountTitle?: TypographyProps;
    signInCreateNewAccountText?: TypographyProps;
    checkoutAsGuestButton?: ButtonPresentationProps;
    createNewAccountButton?: ButtonPresentationProps;
}

export const signInCreateNewAccountStyles: SignInCreateNewAccountStyles = {
    signInCreateNewAccountGridContainer: {
        gap: 20,
    },
    signInCreateNewAccountTitle: {
        variant: "h4",
        css: css`
            margin-bottom: 0;
        `,
    },
    signInCreateNewAccountTitleGridItem: {
        width: 12,
    },
    signInCreateNewAccountTextGridItem: {
        width: 12,
    },
    signInCreateNewAccountButtonGridItem: {
        width: 12,
        css: css`
            ${({ theme }: { theme: BaseTheme }) =>
                breakpointMediaQueries(
                    theme,
                    [
                        css`
                            flex-direction: column;
                        `,
                        null,
                        css`
                            flex-direction: row;
                        `,
                        css`
                            flex-direction: column;
                        `,
                        css`
                            flex-direction: row;
                            justify-content: space-between;
                        `,
                    ],
                    "min",
                )}
        `,
    },
    checkoutAsGuestButton: {
        variant: "tertiary",
        css: css`
            ${({ theme }: { theme: BaseTheme }) =>
                breakpointMediaQueries(
                    theme,
                    [
                        css`
                            margin-bottom: 1rem;
                        `,
                        null,
                        css`
                            margin-right: 1rem;
                        `,
                        css`
                            margin-bottom: 1rem;
                        `,
                        css`
                            margin-right: 1rem;
                        `,
                    ],
                    "min",
                )}
        `,
    },
    createNewAccountButton: { variant: "secondary" },
};

/**
 * @deprecated Use signInCreateNewAccountStyles instead.
 */
export const signInCreateNewAccount = signInCreateNewAccountStyles;
const styles = signInCreateNewAccountStyles;

const SignInCreateNewAccount: FC<Props> = ({
    history,
    fields,
    allowCreateAccount,
    allowGuestCheckout,
    returnUrl,
    createAccountUrl,
    signInAsGuest,
}) => {
    if (!allowCreateAccount) {
        return null;
    }

    const handleCheckoutAsGuest = () => {
        if (!returnUrl) {
            return;
        }

        signInAsGuest({ returnUrl });
    };

    const handleCreateNewAccount = () => {
        if (!createAccountUrl) {
            return;
        }

        history.push(createAccountUrl);
    };

    const createButtonCss = fields.fullWidthButton
        ? css`
              width: 100%;
          `
        : undefined;

    return (
        <GridContainer {...styles.signInCreateNewAccountGridContainer}>
            <GridItem {...styles.signInCreateNewAccountTitleGridItem}>
                <Typography {...styles.signInCreateNewAccountTitle}>{translate("Create New Account")}</Typography>
            </GridItem>
            <GridItem {...styles.signInCreateNewAccountTextGridItem}>
                <Typography {...styles.signInCreateNewAccountText}>{fields.text}</Typography>
            </GridItem>
            <GridItem {...styles.signInCreateNewAccountButtonGridItem}>
                {allowGuestCheckout && (
                    <Button
                        {...styles.checkoutAsGuestButton}
                        onClick={handleCheckoutAsGuest}
                        data-test-selector="signInCreateNewAccount_checkoutAsGuest"
                    >
                        {translate("Checkout as Guest")}
                    </Button>
                )}
                {createAccountUrl && (
                    <Button
                        {...styles.createNewAccountButton}
                        css={createButtonCss}
                        onClick={handleCreateNewAccount}
                        data-test-selector="signInCreateNewAccount_createNewAccount"
                    >
                        {translate("Create Account")}
                    </Button>
                )}
            </GridItem>
        </GridContainer>
    );
};

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(withHistory(SignInCreateNewAccount)),
    definition: {
        allowedContexts: ["SignInPage", "SignInOverlay"],
        group: "Sign In",
        icon: "User",
        fieldDefinitions: [
            {
                name: fields.text,
                displayName: "Main Text",
                editorTemplate: "MultilineTextField",
                defaultValue: "Create an account to checkout faster, view order history, save product lists, and more!",
                fieldType: "Translatable",
                sortOrder: 0,
            },
            {
                name: fields.fullWidthButton,
                displayName: "Full Width Button",
                editorTemplate: "CheckboxField",
                defaultValue: false,
                fieldType: "General",
                sortOrder: 1,
            },
        ],
    },
};

export default widgetModule;
