import _ from 'lodash';
import React from 'react';
import classSet from 'classnames';
import Scrollable from 'ui/Scrollable';
import StoreMixin from 'lib/StoreMixin';
import Url from 'lib/Url';
import Metrika from 'lib/metrika';
import ApplicationStore from 'stores/Application';
import OrganizationStore from 'stores/Organizations';
import AuthStore from 'stores/Auth';
import PermissionStore from 'stores/Permissions';
import { getName } from 'records/util';

import Link from 'ui/Link';
import FlatButton from 'ui/FlatButton';
import Icon from 'ui/Icon';

import MENU_SECTIONS from './sections.admin';
import './sidebar.css';

const ACTION_MAP = {
    add: 'Плюс',
};

function matchesStateTypesById(types, id) {
    const displayedObject = ApplicationStore.getObjectChain()[0];

    return types.indexOf(ApplicationStore.getStateType()) !== -1 &&
        displayedObject && displayedObject.id === String(id);
}

function toSectionDepartmentItem(dept) {
    return {
        text: getName(dept),
        metrika: 'Структура организации',
        icon: 'orgstructure',
        url: () => Url.getContextPath('departments', dept.id),
        matches: () => matchesStateTypesById(['', 'users', 'departments'], dept.id),
    };
}

function available(item) {
    return item.available === undefined || item.available();
}

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

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

const Sidebar = React.createClass({

    mixins: [StoreMixin],

    getStoreState() {
        return {};
    },

    componentDidMount() {
        this.subscribe([ApplicationStore, OrganizationStore, PermissionStore]);
    },

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

    _renderSections() {
        const org = AuthStore.getOrganization();
        const rootDepartments = org.getRootDepartments();
        const disabledRoot = () => !PermissionStore.allowsDepartmentsAdd();
        const availableRoot = () => !AuthStore.isIncompleteOrganization() ||
            PermissionStore.allowsOrganizationStructureEditing() ||
            PermissionStore.allowsDepartmentsAdd();

        const sections = rootDepartments.map(dept => ({
            index: _.assign({
                disabled: disabledRoot,
                available: availableRoot,
            }, toSectionDepartmentItem(dept)),
        }));

        return sections.concat(MENU_SECTIONS).map(section => {
            const { index: indexSection, subsections } = section;

            if (!available(indexSection)) {
                return null;
            }

            return (
                <div className="sidebar__section" key={indexSection.text}>
                    {this._renderSection(indexSection)}
                    <div className="sidebar__menu">
                        {subsections ? subsections.map(this._renderSection) : null}
                    </div>
                </div>
            );
        });
    },

    _isActiveSubsection(subsection) {
        const url = getUrl(subsection);

        return Url.isCurrentPath(url) ||
            (subsection.matches !== undefined && subsection.matches());
    },

    _renderSection(item, index = 0) {
        if (!available(item)) {
            return null;
        }

        let icon = null;
        const url = getUrl(item);

        const active = this._isActiveSubsection(item);

        const className = classSet({
            'sidebar__menu-item': true,
            'sidebar__menu-item_main': Boolean(item.icon),
            'sidebar__menu-item_active': active,
            'sidebar__menu-item_disabled': disabled(item),
        });

        if (item.icon) {
            icon = <Icon type={item.icon} size="m" />;
        }

        return (
            <div className={className} key={index}>
                {icon}
                <Link to={url} metrika={['Левая колонка', item.metrika]}>
                    {item.text}
                </Link>
                {this._renderActions(item)}
            </div>
        );
    },

    _renderActions(item) {
        if (!item || !item.actions || disabled(item)) {
            return null;
        }

        const actions = [];

        if (item.actions.add) {
            actions.push(
                <FlatButton
                    className="plus-button"
                    key="add"
                    onClick={() => this._applyAction(item, 'add')}
                    ariaLabel={item.actions.add.description}
                >
                    <Icon type="plus-dark-solid-circle" />
                </FlatButton>
            );
        }

        return (
            <div className="sidebar__menu-item-actions">
                {actions}
            </div>
        );
    },

    _applyAction(item, actionType) {
        const callback = _.get(item, ['actions', actionType, 'callback']);

        if (!callback) {
            return;
        }

        if (ACTION_MAP[actionType]) {
            Metrika.send('Левая колонка', item.metrika, ACTION_MAP[actionType]);
        }

        callback();
    },

    render() {
        return (
            <Scrollable
                className="sidebar__scrollpane"
                contentClassName="sidebar"
            >

                {this._renderSections()}

            </Scrollable>
        );
    },

});

export default Sidebar;
