import parseQueryString from "@insite/client-framework/Common/Utilities/parseQueryString";
import { ExternalProviderLinkModel } from "@insite/client-framework/Services/IdentityService";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getLocation } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import { getPageLinkByPageType } from "@insite/client-framework/Store/Links/LinksSelectors";
import loadExternalProviders from "@insite/client-framework/Store/Pages/SignIn/Handlers/LoadExternalProviders";
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 Typography, { TypographyPresentationProps } from "@insite/mobius/Typography/Typography";
import { breakpointMediaQueries } from "@insite/mobius/utilities";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import React, { useEffect } from "react";
import { connect, ResolveThunks } from "react-redux";
import styled, { css } from "styled-components";

const enum fields {
    fullWidthButton = "fullWidthButton",
}

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

const mapStateToProps = (state: ApplicationState) => ({
    externalProviders: state.pages.signIn.externalProviders,
    signInUrl: getPageLinkByPageType(state, "SignInPage")?.url,
    location: getLocation(state),
});

const mapDispatchToProps = {
    loadExternalProviders,
};

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

export interface SignInExternalProvidersStyles {
    divider?: InjectableCss;
    titleText?: TypographyPresentationProps;
    providerButton?: ButtonPresentationProps;
}

export const signInExternalProvidersStyles: SignInExternalProvidersStyles = {
    divider: {
        css: css`
            margin: 30px 0 20px 0;
        `,
    },
    titleText: {
        weight: "bold",
    },
};

const styles = signInExternalProvidersStyles;

const SignInExternalProviders = ({ externalProviders, loadExternalProviders, signInUrl, location, fields }: Props) => {
    useEffect(() => {
        if (!externalProviders) {
            loadExternalProviders();
        }
    }, [externalProviders]);

    const providerButtonClickHandler = (externalProvider: ExternalProviderLinkModel) => {
        if (!externalProvider.url) {
            return;
        }

        let returnUrl = "/";
        if (signInUrl && location.pathname.toLowerCase() === signInUrl?.toLowerCase()) {
            returnUrl = parseQueryString<{ returnUrl?: string }>(location.search).returnUrl || "/";
        } else {
            returnUrl = `${location.pathname}${location.search}`;
        }

        returnUrl = `${returnUrl + (returnUrl.indexOf("?") > -1 ? "&" : "?")}forcereturnurl`;
        returnUrl = encodeURIComponent(returnUrl);

        window.location.href = externalProvider.url.replace("returnurl%3a%2f", `returnurl%3a${returnUrl}`);
    };

    if (!externalProviders || externalProviders.length === 0) {
        return null;
    }

    const providerButtonCss = css`
        margin: 20px 20px 0 0;
        ${({ theme }: { theme: BaseTheme }) =>
            breakpointMediaQueries(theme, [
                css`
                    width: 100%;
                `,
                css`
                    width: 100%;
                `,
                fields.fullWidthButton
                    ? css`
                          width: 100%;
                      `
                    : null,
                fields.fullWidthButton
                    ? css`
                          width: 100%;
                      `
                    : null,
                fields.fullWidthButton
                    ? css`
                          width: 100%;
                      `
                    : null,
            ])}
    `;

    return (
        <>
            <Divider />
            <Typography {...styles.titleText} as="h4">
                {translate("Use another service to log in.")}
            </Typography>
            {externalProviders.map(externalProvider => (
                <Button
                    {...styles.providerButton}
                    css={providerButtonCss}
                    key={externalProvider.caption}
                    onClick={() => providerButtonClickHandler(externalProvider)}
                >
                    {externalProvider.caption}
                </Button>
            ))}
        </>
    );
};

const Divider = styled.hr`
    ${styles.divider?.css}
`;

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(SignInExternalProviders),
    definition: {
        allowedContexts: ["SignInPage", "SignInOverlay"],
        group: "Sign In",
        displayName: "External Providers",
        fieldDefinitions: [
            {
                name: fields.fullWidthButton,
                displayName: "Full Width Button",
                editorTemplate: "CheckboxField",
                defaultValue: false,
                fieldType: "General",
                sortOrder: 0,
            },
        ],
    },
};

export default widgetModule;
