import { getCookie } from "@insite/client-framework/Common/Cookies";
import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import Zone from "@insite/client-framework/Components/Zone";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import { getSettingsCollection } from "@insite/client-framework/Store/Context/ContextSelectors";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import { useMergeStyles } from "@insite/content-library/additionalStyles";
import NavigationModeMenu, {
    NavigationModeCookieName,
    NavigationModeMenuStyles,
} from "@insite/content-library/Components/NavigationModeMenu";
import ShowInventoryToggle, { ShowInventoryToggleStyles } from "@insite/content-library/Components/ShowInventoryToggle";
import ShowPricingToggle, { ShowPricingToggleStyles } from "@insite/content-library/Components/ShowPricingToggle";
import Hidden from "@insite/mobius/Hidden";
import getColor from "@insite/mobius/utilities/getColor";
import getContrastColor from "@insite/mobius/utilities/getContrastColor";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import injectCss from "@insite/mobius/utilities/injectCss";
import * as cssLinter from "css";
import React, { FC } from "react";
import { connect } from "react-redux";
import styled, { css } from "styled-components";

const enum fields {
    customCSS = "customCSS",
    showPricingToggle = "showPricingToggle",
    showInventoryToggle = "showInventoryToggle",
}

interface OwnProps extends WidgetProps {
    fields: {
        [fields.customCSS]: string;
        [fields.showPricingToggle]: boolean;
        [fields.showInventoryToggle]: boolean;
    };
}

const mapStateToProps = (state: ApplicationState) => ({
    enableWarehousePickup: getSettingsCollection(state).accountSettings.enableWarehousePickup,
    displayPricingAndInventory: state.context.session?.displayPricingAndInventory || false,
    currentMode: getCookie(NavigationModeCookieName) || "Storefront",
});

type Props = OwnProps & ReturnType<typeof mapStateToProps>;

const Navigation = styled.div`
    color: ${getContrastColor("common.accent")};
    font-size: 15px;
    background-color: ${getColor("common.accent")};
    padding: 0 45px 0 45px;
    height: 50px;
    text-transform: uppercase;
    display: flex;
    justify-content: flex-end;
    align-items: center;
`;

const NavItem = styled.span<InjectableCss>`
    display: inline-flex;

    > span,
    > a {
        margin-left: 10px;
    }
    ${injectCss}
`;

export interface SecondaryNavigationStyles {
    wrapper?: InjectableCss;
    navigationModeMenu?: NavigationModeMenuStyles;
    showInventoryLink?: InjectableCss;
    showInventoryToggle?: ShowInventoryToggleStyles;
    showPricingLink?: InjectableCss;
    showPricingToggle?: ShowPricingToggleStyles;
    currencyLink?: InjectableCss;
    languageLink?: InjectableCss;
    warehousePickupLink?: InjectableCss;
    signInLink?: InjectableCss;
}

export const secondaryNavigationStyles: SecondaryNavigationStyles = {
    showInventoryLink: {
        css: css`
            margin-left: 10px;
        `,
    },
    showPricingLink: {
        css: css`
            margin-left: 10px;
        `,
    },
    currencyLink: {
        css: css`
            margin-left: 16px;
        `,
    },
    languageLink: {
        css: css`
            flex: 0 0 auto;
            margin-left: 16px;
        `,
    },
    warehousePickupLink: {
        css: css`
            flex: 0 1 auto;
            margin-left: 6px;
            min-width: 30px;
        `,
    },
    signInLink: {
        css: css`
            flex: 0 0 auto;
            margin-left: 6px;
        `,
    },
};

const defaultCustomCss = `.wrapper {
}

.navigation-mode-menu {
}

.currency-menu {
}

.language-menu {
}

.ship-to-address-menu {
}

.sign-in-link {
}`;

const SecondaryNavigation: FC<Props> = ({
    id,
    enableWarehousePickup,
    displayPricingAndInventory,
    currentMode,
    fields,
}) => {
    const styles = useMergeStyles("secondaryNavigation", secondaryNavigationStyles);

    const customCssWrapper = {
        css: css`
            ${fields.customCSS}
        `,
    };

    return (
        <StyledWrapper {...customCssWrapper}>
            <Hidden below="lg">
                <Navigation className="wrapper" {...styles.wrapper}>
                    <NavItem className="navigation-mode-menu">
                        <NavigationModeMenu extendedStyles={styles.navigationModeMenu} />
                    </NavItem>
                    {fields.showInventoryToggle && displayPricingAndInventory && currentMode === "Storefront" && (
                        <NavItem
                            className="show-inventory-toggle"
                            data-test-selector="showInventoryToggle"
                            {...styles.showInventoryLink}
                        >
                            <ShowInventoryToggle extendedStyles={styles.showInventoryToggle} />
                        </NavItem>
                    )}
                    {fields.showPricingToggle && displayPricingAndInventory && currentMode === "Storefront" && (
                        <NavItem
                            className="show-pricing-toggle"
                            data-test-selector="showPricingToggle"
                            {...styles.showPricingLink}
                        >
                            <ShowPricingToggle extendedStyles={styles.showPricingToggle} />
                        </NavItem>
                    )}
                    <NavItem className="currency-menu" {...styles.currencyLink}>
                        <Zone zoneName="Currency" contentId={id} fixed />
                    </NavItem>
                    <NavItem className="language-menu" {...styles.languageLink}>
                        <Zone zoneName="Language" contentId={id} fixed />
                    </NavItem>
                    {enableWarehousePickup && (
                        <NavItem className="ship-to-address-menu" {...styles.warehousePickupLink}>
                            <Zone zoneName="ShipToAddress" contentId={id} fixed />
                        </NavItem>
                    )}
                    <NavItem className="sign-in-link" {...styles.signInLink}>
                        <Zone zoneName="SignIn" contentId={id} fixed />
                    </NavItem>
                </Navigation>
            </Hidden>
        </StyledWrapper>
    );
};

const secondaryNavigation: WidgetModule = {
    component: connect(mapStateToProps)(SecondaryNavigation),
    definition: {
        group: "Common",
        icon: "link-simple",
        fieldDefinitions: [
            {
                name: fields.customCSS,
                displayName: "Custom CSS",
                editorTemplate: "CodeField",
                fieldType: "General",
                defaultValue: defaultCustomCss,
                isVisible: (item, shouldDisplayAdvancedFeatures) => !!shouldDisplayAdvancedFeatures,
                validate: value => {
                    if (value === undefined || value === null) {
                        return "";
                    }

                    const result = cssLinter.parse(value, { silent: true });
                    if (result?.stylesheet?.parsingErrors) {
                        // the error output at this time only has room for one line so we just show the first error
                        return result.stylesheet.parsingErrors.length <= 0
                            ? ""
                            : result.stylesheet.parsingErrors.map(error => `${error.reason} on line ${error.line}`)[0];
                    }

                    return "Unable to parse Css";
                },
                options: {
                    mode: "css",
                    lint: true,
                    autoRefresh: true,
                },
            },
            {
                name: fields.showPricingToggle,
                displayName: "Show/Hide Pricing Toggle",
                editorTemplate: "CheckboxField",
                defaultValue: false,
                fieldType: "General",
            },
            {
                name: fields.showInventoryToggle,
                displayName: "Show/Hide Inventory Toggle",
                editorTemplate: "CheckboxField",
                defaultValue: false,
                fieldType: "General",
            },
        ],
    },
};

export default secondaryNavigation;
