import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import MenuItem from './atoms/menu-item/MenuItem';
import './styles/Menu.scss';
import { COLORPICKER } from '../../constants/schemaComponentTypes';
import { createNamespace } from '../../tools/namingTools';
import withListener from '../withListener';

const n = createNamespace('menu');
const BASE_LISTING_KEY = 'listing';

const secondaryNavSelector = (secondaryNav = []) => {
    const productLines = secondaryNav
        .filter(({ key }) => key !== 'listing' && key !== 'home')
        .map(item => ({
            ...item,
            text: item.label
        }));

    return productLines;
};

const navSelector = (primaryNav = [], secondaryNav = []) => {
    const categories = primaryNav.map(({ name, hrefListing, subCategories }) => ({
        label: name,
        href: hrefListing,
        items: subCategories.map(subCategory => ({
            label: subCategory.name,
            href: subCategory.hrefListing || subCategory.href
        }))
    }));

    const browseApps = secondaryNav.find(({ key }) => key === BASE_LISTING_KEY);

    const menu = {
        items: [
            {
                label: browseApps.alternateLabel,
                href: browseApps.href,
                items: categories
            },
            ...secondaryNavSelector(secondaryNav)
        ]
    };
    return menu;
};

const SecondaryNavComponent = ({ data: { primaryNav = [], secondaryNav = {} }, settings }) => {
    const settingsWithDefaults = { ...SecondaryNavComponent.defaultProps.settings, ...settings };
    const { backgroundColor } = settingsWithDefaults;
    const cssVars = {
        backgroundColor
    };
    const rawRootMenu = navSelector(primaryNav, secondaryNav.items);
    const defaultLevel = 0;
    // remove special character entities (e.g. &amp; => &)
    const rootMenu = useMemo(() => {
        const parser = new DOMParser();
        const parseItem = item => {
            // eslint-disable-next-line no-use-before-define
            const items = parseMenu(item.items);
            const label = parser.parseFromString(`<!doctype html><body>${item.label}`, 'text/html').body.textContent;
            return {
                ...item,
                items,
                label
            };
        };
        const parseMenu = items => items && items.map(parseItem);
        return parseMenu(rawRootMenu.items);
    }, [rawRootMenu]);

    const renderMainMenu = items => {
        if (!items || !items.length) {
            return null;
        }

        return (
            <ul {...n('list', `level-${defaultLevel}`).withTestId().props}>
                {items.map(item => (
                    <MenuItem menuItem={item} menuLevel={defaultLevel} key={item.label} />
                ))}
            </ul>
        );
    };

    return (
        <nav {...n('nav').withVariables(cssVars).withTestId().props}>
            <div {...n('backgroundWrapper').withVariables(cssVars).withTestId().props} />
            {renderMainMenu(rootMenu)}
        </nav>
    );
};

SecondaryNavComponent.schema = () => ({
    name: 'SecondaryNav',
    title: 'uieditor.sfbComponent.menu.title',
    iconName: 'menu',
    editable: false,
    form: {
        backgroundColor: {
            title: 'uieditor.sfbComponent.menu.backgroundColor.title',
            defaultValue: '#ffff',
            type: COLORPICKER
        }
    },
    marketplaceData: {
        primaryNav: 'nav.primary.categories',
        secondaryNav: 'nav.secondary'
    }
});

const SETTINGS = SecondaryNavComponent.schema().form;

SecondaryNavComponent.propTypes = {
    data: PropTypes.shape({
        primaryNav: PropTypes.array,
        secondaryNav: PropTypes.object
    }),
    settings: PropTypes.shape({
        backgroundColor: PropTypes.string
    })
};

SecondaryNavComponent.defaultProps = {
    data: {
        primaryNav: [],
        secondaryNav: {}
    },
    settings: {
        backgroundColor: SETTINGS.backgroundColor.defaultValue
    }
};

export default withListener(SecondaryNavComponent);
