<template>
    <ul :class="classes" :style="styles">
        <slot></slot>
    </ul>
</template>
<script>
import {
    oneOf,
    findComponentsDownward,
    findComponentsUpward
} from '../../utils/assist';
import Emitter from '../../mixins/emitter';

const prefixCls = 'ivu-menu';

export default {
    name: 'Menu',
    mixins: [Emitter],
    props: {
        mode: {
            validator(value) {
                return oneOf(value, ['horizontal', 'vertical']);
            },
            default: 'vertical'
        },
        theme: {
            validator(value) {
                return oneOf(value, [
                    'light',
                    'dark',
                    'primary'
                ]);
            },
            default: 'light'
        },
        activeName: {
            type: [String, Number]
        },
        openNames: {
            type: Array,
            default() {
                return [];
            }
        },
        accordion: {
            type: Boolean,
            default: false
        },
        width: {
            type: String,
            default: '240px'
        }
    },
    data() {
        return {
            currentActiveName: this.activeName,
            openedNames: []
        };
    },
    computed: {
        classes() {
            let theme = this.theme;
            if (
                this.mode === 'vertical' &&
                this.theme === 'primary'
            )
                theme = 'light';

            return [
                `${prefixCls}`,
                `${prefixCls}-${theme}`,
                {
                    [`${prefixCls}-${this.mode}`]: this.mode
                }
            ];
        },
        styles() {
            let style = {};

            if (this.mode === 'vertical')
                style.width = this.width;

            return style;
        }
    },
    methods: {
        updateActiveName() {
            if (this.currentActiveName === undefined) {
                this.currentActiveName = -1;
            }
            this.broadcast(
                'Submenu',
                'on-update-active-name',
                false
            );
            this.broadcast(
                'MenuItem',
                'on-update-active-name',
                this.currentActiveName
            );
        },
        updateOpenKeys(name) {
            let names = [...this.openedNames];
            const index = names.indexOf(name);
            if (this.accordion)
                findComponentsDownward(this, 'Submenu').forEach(
                    item => {
                        item.opened = false;
                    }
                );
            if (index >= 0) {
                let currentSubmenu = null;
                findComponentsDownward(this, 'Submenu').forEach(
                    item => {
                        if (item.name === name) {
                            currentSubmenu = item;
                            item.opened = false;
                        }
                    }
                );
                findComponentsUpward(
                    currentSubmenu,
                    'Submenu'
                ).forEach(item => {
                    item.opened = true;
                });
                findComponentsDownward(
                    currentSubmenu,
                    'Submenu'
                ).forEach(item => {
                    item.opened = false;
                });
            } else {
                if (this.accordion) {
                    let currentSubmenu = null;
                    findComponentsDownward(
                        this,
                        'Submenu'
                    ).forEach(item => {
                        if (item.name === name) {
                            currentSubmenu = item;
                            item.opened = true;
                        }
                    });
                    findComponentsUpward(
                        currentSubmenu,
                        'Submenu'
                    ).forEach(item => {
                        item.opened = true;
                    });
                } else {
                    findComponentsDownward(
                        this,
                        'Submenu'
                    ).forEach(item => {
                        if (item.name === name)
                            item.opened = true;
                    });
                }
            }
            let openedNames = findComponentsDownward(
                this,
                'Submenu'
            )
                .filter(item => item.opened)
                .map(item => item.name);
            this.openedNames = [...openedNames];
            this.$emit('on-open-change', openedNames);
        },
        updateOpened() {
            const items = findComponentsDownward(
                this,
                'Submenu'
            );

            if (items.length) {
                items.forEach(item => {
                    if (this.openedNames.indexOf(item.name) > -1)
                        item.opened = true;
                    else item.opened = false;
                });
            }
        },
        handleEmitSelectEvent(name) {
            this.$emit('on-select', name);
        }
    },
    mounted() {
        this.openedNames = [...this.openNames];
        this.updateOpened();
        this.$nextTick(() => this.updateActiveName());
        this.$on('on-menu-item-select', name => {
            // this.currentActiveName = name
            this.$emit('on-select', name);
        });
    },
    watch: {
        openNames(names) {
            this.openedNames = names;
        },
        activeName(val) {
            this.currentActiveName = val;
        },
        currentActiveName() {
            this.updateActiveName();
        }
    }
};
</script>
