<template>
    <transition name="editor-help-slide-fade">
        <div v-show="value" :class="bem({active: this.articleId})">
            <MenuBar
                :unread="unread"
                :udeskConfig="udeskConfig"
                :list="list"
                v-model="articleId">
                <!-- 底部自定义 -->
                <slot name="footer"/>
            </MenuBar>
            <transition name="editor-help-fade">
                <Content
                    v-if="!loadContent && articleId"
                    :status="articleStatusMap[articleId].status"
                    :content="content"
                    :id="articleId"
                    @clickPraise="changeArticle('praise')"
                    @clickBlame="changeArticle('blame')"
                />
            </transition>
        </div>
    </transition>
</template>

<script>
import get from 'lodash/get';
import { createComponentName, componentMixin } from '../_utils/component';
import { clickOutside } from '../_utils/dom';
import MenuBar from './MenuBar';
import Tips from '../Tips';
import Content from './Content';
import request from '../request';
export default {
    name: createComponentName('editor-help'),
    components: {
        MenuBar,
        Content,
    },
    mixins: [componentMixin],
    model: {
        name: 'value',
        event: 'change',
    },
    props: {
        // 是否可以见,可以通过 v-model 绑定
        value: {
            type: Boolean,
            default: false,
        },
        // udesk 配置
        udeskConfig: {
            type: Object,
            default: () => ({}),
        },
        // 展示未读消息
        unread: {
            type: Boolean,
            default: true,
        },
        // 哪个位置的帮助内容
        position: {
            type: Number,
            // 2: 抠图编辑器
            default: 2
        }

    },
    data() {
        return {
            list: [],
            articleContentMap: {},
            articleStatusMap: {},
            articleId: null,
            loadContent: false,
        };
    },
    computed: {
        content() {
            if (!this.articleId) return null;

            if (this.articleContentMap[this.articleId]) {
                return this.articleContentMap[this.articleId].content;
            }

            return null;
        },
    },
    watch: {
        articleId(value) {
            if (!value) return;
            this.getArticle(value);
        },
        value(value) {
            if (value) {
                setTimeout(() => {
                    this.off = clickOutside(this.$el, this.onClose);
                });
            } else {
                if (this.off) this.off();
            }
        },
    },
    mounted() {
        this.getArticles();
        if (this.value) {
            this.off = clickOutside(this.$el, this.onClose);
        }
    },
    beforeDestroy() {
        if (this.off) this.off();
    },
    methods: {
        onClose() {
            if (this.value) {
                // value 变化触发
                // @arg (value: boolean)
                this.$emit('change', false);
            }
        },
        async getArticles() {
            try {
                const res = await request.get('/api/articles', { params: {
                    positions: this.position,
                    type: 'help',
                } });

                this.list = res.data;
            }
            catch (error) {
                Tips(error);
            }
        },
        async getArticle(id) {
            this.loadContent = true;
            await Promise.all([this.getArticleContent(id), this.getArticleLikeStatus(id)]);
            this.loadContent = false;
        },
        async getArticleContent(id) {
            if (this.articleContentMap[id]) {
                return this.articleContentMap[id];
            }
            else {
                this.$set(this.articleContentMap, id, null);
                const res = await request.get('/api/articles/' + id);
                this.articleContentMap[id] = res.data;
            }
        },
        async changeArticle(status) {
            let lastStatus = this.articleStatusMap[this.articleId].status;

            this.articleStatusMap[this.articleId].status = 'on' + status;

            try {
                if (lastStatus && lastStatus.indexOf(status) === 0) {
                    await this.deleteArticleStatus();
                }
                else {
                    const res = await request.post(`/api/articles/${this.articleId}/likes`, {
                        status: status === 'praise' ? 1 : 0
                    });
                    this.articleStatusMap[this.articleId] = { status, id: res.data.id };
                }
            }
            catch (error) {
                Tips(error);
                const id = get(this.articleStatusMap, `${this.articleId}.id`, null);
                this.articleStatusMap[this.articleId] = { status: lastStatus + 'error', id };
            }
        },
        async deleteArticleStatus() {
            await request.delete(`api/articles/${this.articleId}/likes/${this.articleStatusMap[this.articleId].id}`);

            this.articleStatusMap[this.articleId] = { status: null, id: null };
        },
        async getArticleLikeStatus(id) {
            const res = await request.get(`/api/articles/${id}/likes`);
            let status = get(res.data, '0.status', null);

            if (status === 0) {
                status = 'blame';
            }
            else if (status === 1) {
                status = 'praise';
            }
            this.$set(this.articleStatusMap, this.articleId, { status, id: get(res.data, '0.id', null) });
        }
    }
};
</script>

<style lang="less">
@import '../_styles/base.less';

.@{editor-help} {
    height:562px;
    width:244px;
    box-shadow:4px 6px 8px 0px rgba(98,100,109,0.12);
    display: inline-flex;
    background:rgba(245,245,245,1);
    transition: width 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
    overflow: hidden;
    position: absolute;
    left: 70px;
    bottom: 0;

    * {
        box-sizing: border-box;
    }

    &--active {
        width: 756px;

        .@{editor-help-menu-bar} {
            border-right: 1px solid rgba(232,236,242,1);
        }
    }

    .@{editor-help-content},
    .@{editor-help-menu-bar} {
        flex: 0 0 auto;
    }
}

.editor-help-slide-fade-leave-active,
.editor-help-slide-fade-enter-active {
    transform: translateX(0);
    transition: all 0.2s ease-out;
}
.editor-help-slide-fade-enter,
.editor-help-slide-fade-leave-to {
    opacity: 0;
    transform: translateX(-5%);
}

.editor-help-fade-leave-active,
.editor-help-fade-enter-active {
    transition: all 0.2s ease-out;
}
.editor-help-fade-enter,
.editor-help-fade-leave-to {
    opacity: 0;
}

</style>
