import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import { COLORPICKER, GROUP_HEADER, SLIDER, TABS_LIST } from '../../constants/schemaComponentTypes';
import { UNIVERSAL_HEADER_ELEMENT_ID } from '../../constants/environment';
import { buildCustomizedPageTabs, isFeaturesTabVisible } from '../../tools/pageTabsParser';
import { createNamespace } from '../../tools/namingTools';
import Button from '../../atoms/button/Button';
import Icon from '../../atoms/icon/Icon';
import './styles/TabsMenu.scss'; // eslint-disable-line import/no-duplicates
// import { topNavMinHeight } from './styles/TabsMenu.scss'; // eslint-disable-line import/no-duplicates
import { CTA_BUY, CTA_DOMAIN_BUY_NOW, CTA_DOMAIN_ADD_TO_CART } from '../../constants/actions';
import { NAMESPACES } from '../../constants/namespaces';
import { ORDERABLE_COMPONENTS } from '../page-orderable-container/PageOrderableContainer';
import { useResponsive } from '../../tools/widths/useResponsive';
import { filterProductActions } from '../../tools/callToActions';
import { domainAppDataStore } from '../../store/domainApp';
import { PROFILE_TABS } from '../../constants/profileTabs';
import { profilePageDataStore } from '../../store/profilePageData';

import withListener from '../withListener';

const n = createNamespace('TabsMenu');

/*
    Mapping between IDs and anchors. This mapping is required for the
    scroll to section functionality in Overview to work.
*/
export const anchorToIdMapping = (() => {
    const anchorToIdMap = {};
    Object.values(ORDERABLE_COMPONENTS).forEach(value => {
        const schema = value.schema();
        if (schema.anchor && schema.name) {
            anchorToIdMap[schema.anchor] = schema.name;
        }
    });
    return anchorToIdMap;
})();

const handleTabClick = (e, item, isMobile, setCollapseMenuState, isMenuCollapsed) => {
    e.preventDefault();
    isMobile && setCollapseMenuState(!isMenuCollapsed);
    // const domID = anchorToIdMapping[item.anchor];
    // const foundSection = domID && document.querySelector(`div[id^='${domID}']`);
    // removed scroll to until decision from product on best behavior
    // const foundSection = false;
    // if (foundSection) {
    //     const mobileOffset = isMobile ? parseInt(topNavMinHeight, 10) : 0;
    //     window.scrollTo(0, foundSection.offsetTop - mobileOffset);
    // } else { document.location.href = item.href; }
    document.location.href = item.href;
};

export const TabsMenuComponent = ({
    data: {
        items,
        callToActions,
        summary
    },
    settings,
    i18n
}) => {
    const settingsWithDefaults = { ...TabsMenuComponent.defaultProps.settings, ...settings };
    const {
        pageTabs: settingsPageTabs,
        textColor,
        textActiveColor,
        backgroundColor,
        borderColor,
        height,
        linkSpacing
    } = settingsWithDefaults;

    const cssVars = {
        textColor,
        textActiveColor,
        backgroundColor,
        borderColor,
        height: height ? `${height}px` : '',
        linkSpacing: linkSpacing ? `${linkSpacing}px` : ''
    };
    const { largeDown } = useResponsive();
    const [isMobileMenu, setMobileMenuState] = useState(false);
    const [isMenuCollapsed, setCollapseMenuState] = useState(true);
    const [portal, setPortal] = useState(null);
    const [contentTabs, setContentTabs] = useState(items);
    const { setIsFeaturesLinkEnabled } = profilePageDataStore();

    const hasNav = Boolean(contentTabs && contentTabs.length);

    useEffect(() => {
        if (settingsPageTabs && settingsPageTabs.length) {
            setContentTabs(buildCustomizedPageTabs(items, settingsPageTabs));
            setIsFeaturesLinkEnabled(isFeaturesTabVisible(settingsPageTabs));
        }
    }, [settingsPageTabs, items]);

    useEffect(() => {
        setMobileMenuState(largeDown);
    }, [largeDown]);

    // on mobile, create a sticky portal to move element in the DOM, under universal header
    useEffect(() => {
        if (!portal) {
            const universalHeader = document.querySelector(`#${UNIVERSAL_HEADER_ELEMENT_ID}`);
            if (!universalHeader) {
                return;
            }
            const domNode = document.createElement('div');
            domNode.classList.add(n('stickyContainer').props.className);
            universalHeader.after(domNode);
            setPortal(domNode);
        }
    }, [largeDown, portal]);

    const { callToActions: domainsCallToActions, handleBuyNowDomains, handleAddToCartDomains } = domainAppDataStore();

    const renderTopNavButton = item => {
        const icon = item.icon || (item.actionType === CTA_BUY && 'cart');

        const modifiers = icon ? 'with-icon' : '';
        let action;
        switch (item.actionType) {
            case CTA_DOMAIN_BUY_NOW:
                action = handleBuyNowDomains;
                break;
            case CTA_DOMAIN_ADD_TO_CART:
                action = handleAddToCartDomains;
                break;
            default:
        }

        const buttonProps = {
            type: item.type || 'emphasis',
            size: 'small',
            onClick: action,
            url: !action ? item.url || item.leadPageUrl : null,
            disabled: item.disabled
        };
        return (
            <div {...n('topNavButton', modifiers).props} key={item.url || item.label}>
                <Button {...buttonProps}>
                    {item.label}
                    {icon && <Icon type={icon} />}
                </Button>
            </div>
        );
    };

    const renderLogo = () => {
        if (!summary || !summary.title) {
            return null;
        }
        const { title, logoSrc } = summary;

        return (<img src={logoSrc} alt={title} {...n('topNavThumbnail').props} />);
    };

    const renderCtas = () => {
        const finalCtas = domainsCallToActions || (callToActions && callToActions.items);

        if (!finalCtas) {
            return null;
        }

        return (
            <div {...n('btnContainer').props}>
                {finalCtas.filter(filterProductActions).map(renderTopNavButton)}
            </div>
        );
    };

    const content = (
        <div {...n('container').withVariables(cssVars).withTestId().withE2EId().props}>
            <nav {...n('nav', [hasNav && 'with-nav', isMobileMenu && 'mobile']).props} aria-label="Product Navigation">
                {isMobileMenu && (
                    <div {...n('topNav', hasNav && 'with-nav').props}>
                        {hasNav ? (
                            <div {...n('btnMenu', !isMenuCollapsed ? 'is-opened' : '').props}>
                                <Button type="white" onClick={() => setCollapseMenuState(!isMenuCollapsed)}>
                                    {i18n.buttonLabel}
                                    <Icon type="caretUp" />
                                </Button>
                            </div>
                        ) : null}
                        {renderLogo()}
                        {renderCtas()}
                    </div>
                )}
                {hasNav ? (
                    <div {...n('menu').props}>
                        <ul {...n('list', !isMenuCollapsed ? 'is-opened' : '').props}>
                            {contentTabs.filter(item => item.isVisible).map(item => (
                                <li {...n('item').props} key={item.value}>
                                    <button
                                        {...n('link', item.selected ? 'selected' : null).withClass(`tab-${item.value}`).withTestId().withE2EId().props}
                                        type="button"
                                        onClick={e => {
                                            handleTabClick(e, item, largeDown, setCollapseMenuState, isMenuCollapsed);
                                        }}
                                    >
                                        {item.label}
                                    </button>
                                </li>
                            ))}
                        </ul>
                    </div>
                ) : null}
            </nav>
        </div>
    );

    // on desktop, element is placed normally in the flow
    if (!largeDown || !portal) {
        return content;
    }

    // on mobile, element needs to be right after universal header in the DOM
    return ReactDOM.createPortal(
        content,
        portal
    );
};

TabsMenuComponent.schema = () => ({
    name: 'ProductTabMenu',
    title: 'uieditor.sfbComponent.tabsMenu.title',
    orderableSection: [NAMESPACES.profile],
    iconName: 'pageTabs',
    form: {
        pageTabs: {
            type: TABS_LIST,
            defaultValue: [
                PROFILE_TABS.overview, PROFILE_TABS.features, PROFILE_TABS.reviews,
                PROFILE_TABS.questions, PROFILE_TABS.policies, PROFILE_TABS.resources,
                PROFILE_TABS.editions
            ]
        },
        headingSpacer: {
            type: GROUP_HEADER,
            title: 'uieditor.sfbComponent.tabsMenu.settings.title',
            symbol: 'style'
        },
        linkSpacing: {
            title: 'uieditor.sfbComponent.tabsMenu.linkSpacing.title',
            type: SLIDER,
            required: true,
            defaultValue: 30,
            options: {
                step: 1,
                min: 4,
                max: 150
            },
            validation: {
                availableOptions: {
                    step: 1,
                    min: 4,
                    max: 150
                },
                message: 'uieditor.sfbComponent.slider.validation.message'
            }
        },
        height: {
            title: 'uieditor.sfbComponent.tabsMenu.height.title',
            type: SLIDER,
            required: true,
            defaultValue: 50,
            options: {
                step: 1,
                min: 16,
                max: 100
            },
            validation: {
                availableOptions: {
                    step: 1,
                    min: 16,
                    max: 100
                },
                message: 'uieditor.sfbComponent.slider.validation.message'
            }
        },
        headingSpacerText: {
            type: GROUP_HEADER,
            title: 'uieditor.sfbComponent.tabsMenu.color.title',
            symbol: 'style'
        },
        textColor: {
            title: 'uieditor.sfbComponent.tabsMenu.textColor.title',
            defaultValue: '#9C9C9C',
            type: COLORPICKER
        },
        textActiveColor: {
            title: 'uieditor.sfbComponent.tabsMenu.textActiveColor.title',
            type: COLORPICKER
        },
        headingSpacerBg: {
            type: GROUP_HEADER,
            title: 'uieditor.sfbComponent.tabsMenu.background.title',
            symbol: 'style'
        },
        borderColor: {
            title: 'uieditor.sfbComponent.tabsMenu.borderColor.title',
            defaultValue: '#CBCBCB',
            type: COLORPICKER
        },
        backgroundColor: {
            title: 'uieditor.sfbComponent.tabsMenu.backgroundColor.title',
            defaultValue: '#fff',
            type: COLORPICKER
        }
    },
    marketplaceData: {
        summary: 'application.summary',
        callToActions: 'application.callToActions',
        items: 'application.navigation.items'
    }
});

TabsMenuComponent.propTypes = {
    data: PropTypes.shape({
        items: PropTypes.arrayOf(
            PropTypes.shape({
                label: PropTypes.string,
                href: PropTypes.string,
                value: PropTypes.string,
                selected: PropTypes.bool
            })
        ),
        summary: PropTypes.shape({
            logoSrc: PropTypes.string,
            title: PropTypes.string
        }),
        callToActions: PropTypes.shape({
            items: PropTypes.arrayOf(
                PropTypes.shape({
                    label: PropTypes.string,
                    tooltip: PropTypes.string,
                    isPrimary: PropTypes.bool,
                    disabled: PropTypes.bool,
                    url: PropTypes.string,
                    actionType: PropTypes.string
                })
            )
        })
    }),
    settings: PropTypes.shape({
        height: PropTypes.number,
        linkSpacing: PropTypes.number,
        textColor: PropTypes.string,
        textActiveColor: PropTypes.string,
        backgroundColor: PropTypes.string,
        borderColor: PropTypes.string
    }),
    i18n: PropTypes.shape({
        buttonLabel: PropTypes.string
    })
};

const SETTINGS = TabsMenuComponent.schema().form;

TabsMenuComponent.defaultProps = {
    data: {
        items: [],
        callToActions: {},
        summary: {}
    },
    settings: Object.keys(SETTINGS).reduce((defaults, settingKey) => (
        {
            ...defaults,
            [settingKey]: SETTINGS[settingKey].defaultValue
        }
    ), {}),
    i18n: {
        buttonLabel: 'More'
    }
};

export default withListener(TabsMenuComponent);
