import _ from 'lodash';
import React from 'react';
import classSet from 'classnames';
import Menu from 'react-bem-components/lib/Menu';
import StoreMixin from 'lib/StoreMixin';
import Url from 'lib/Url';
import Metrika from 'lib/metrika';
import ApplicationStore from 'stores/Application';

import Link from 'ui/Link';
import Popup from 'ui/Popup';

import MENU_SECTIONS from './sections.common';
import './header.css';

function getUrl(item) {
    return typeof item.url === 'function' ? item.url() : item.url;
}

const HeaderNavigation = React.createClass({

    mixins: [StoreMixin],

    getStoreState() {
        return {};
    },

    componentWillMount() {
        this._deepSections = [];
        this._menuItemMap = {};
    },

    componentDidMount() {
        this.subscribe(ApplicationStore);
    },

    shouldComponentUpdate() {
        return !ApplicationStore.isBusy();
    },

    _toggleMenu(ids, values) {
        if (!(ids instanceof Array)) {
            ids = [ids];
        }

        const nextState = {};

        ids.forEach((id, index) => {
            const key = `section_${id}_active`;
            let value = values instanceof Array ? values[index] : values;

            if (value === undefined) {
                value = !this.state[key];
            }

            nextState[key] = value;
        });

        this.setState(nextState);
    },

    _isMenuOpen(id) {
        return this.state[`section_${id}_active`];
    },

    _handleMenuSelect(payload) {
        if (payload.value) {
            const item = this._menuItemMap[payload.value] || {};

            if (item.metrika) {
                Metrika.send('Пользовательская навигация', item.metrika);
            }

            Url.open(item.url);
        }

        // закрываем меню после выбора
        this._toggleMenu(this._deepSections, false);
    },

    _getMenuOptions(subsections) {
        if (!(subsections instanceof Array)) {
            return [];
        }

        return subsections.map(subsection => {
            if (subsection.available !== undefined && !subsection.available()) {
                return null;
            }

            if (!subsection.val) {
                subsection.val = _.uniqueId();
            }

            this._menuItemMap[subsection.val] = {
                url: getUrl(subsection),
                metrika: subsection.metrika,
            };

            return subsection;
        }).filter(Boolean);
    },

    _renderSections() {
        return MENU_SECTIONS.map((item, index) => {
            if (item.available !== undefined && !item.available()) {
                return null;
            }

            const menuOptions = this._getMenuOptions(item.subsections);
            const section = {
                id: `section_${index}`,
                url: getUrl(item),
            };

            section.current = Url.isCurrentPath(item.url) ||
                (item.matches !== undefined && item.matches());

            section.active = this._isMenuOpen(section.id);

            const className = classSet({
                'header-navigation__menu': menuOptions.length > 1,
                'header-navigation__section': true,
                'header-navigation__section_current': section.current,
                'header-navigation__section_active': section.active,
                'header-navigation__section_disabled': item.disabled,
            });

            if (menuOptions.length === 1) {
                section.url = getUrl(menuOptions[0]);
            }

            if (menuOptions.length > 1) {
                section.menu = (
                    <Popup className="header-navigation__subsections">
                        <Menu options={menuOptions} onSelect={this._handleMenuSelect} />
                    </Popup>
                );

                section.handleMouseEnter = () => {
                    if (section.metrika) {
                        Metrika.send('Пользовательская навигация', section.metrika);
                    }

                    this._toggleMenu(section.id, true);
                };

                section.handleMouseLeave = () => {
                    this._toggleMenu(section.id, false);
                };

                section.title = (
                    <div
                        className="header-navigation__section-title"
                        onMouseEnter={section.handleMouseEnter}
                    >
                        {item.text}
                    </div>
                );

                this._deepSections.push(section.id);
            } else if (section.current) {
                section.title = (
                    <div className="header-navigation__section-title">
                        {item.text}
                    </div>
                );
            } else {
                section.title = (
                    <Link
                        className="header-navigation__section-title header-navigation__link"
                        to={section.url}
                        metrika={['Пользовательская навигация', section.metrika]}
                    >
                        {item.text}
                    </Link>
                );
            }

            return (
                <div
                    className={className}
                    onMouseLeave={section.handleMouseLeave}
                    key={index}
                >
                    {section.title}
                    {section.menu}
                </div>
            );
        });
    },

    render() {
        return (
            <div className="header-navigation">
                {this._renderSections()}
            </div>
        );
    },

});

export default HeaderNavigation;
