<!--
  - Copyright (c) 2022.
  - Author Peter Placzek (tada5hi)
  - For the full copyright and license information,
  - view the LICENSE file that was distributed with this source code.
  -->

<script>
    import linkifyHtml from 'linkifyjs/html';
    import sanitizeHtml from 'sanitize-html';

    import 'vue-context/dist/css/vue-context.css';
    import {dropMessage} from "@/domains/chat-message/api";
    import UserAvatar from "@/components/user/UserAvatar";
    import {ChatRoomType} from "@/domains/chat-room/utils";
    import {getters} from "@/modules/security/store";

    export default {
        components: {
            UserAvatar,
            VueContext: () => process.server ? undefined : import('vue-context')
        },
        props: {
            message: Object,
            room: Object,
            messageEditId: Number | undefined
        },
        data() {
            return {
                busy: false,

                content: undefined,
                contentLoading: false
            }
        },
        created() {
            this.decrypt();
        },
        watch: {
            messageContent(val, oldVal) {
                this.decrypt();
            },
            isEncryptionAvailable(val, oldVal) {
                this.decrypt();
            }
        },
        methods: {
            async decrypt() {
                this.contentLoading = true;

                if(this.message.encrypted) {
                    try {
                        this.content = sanitizeHtml(this.$chat.decodeMessage(this.message.roomId, this.message.content), {
                            allowedTags: [],
                            allowedAttributes: {}
                        });
                    } catch (e) {
                        this.content = 'Die Nachricht kann nicht mehr entschüsselt werden.';
                    }
                } else {
                    this.content = this.message.content;
                }

                this.contentLoading = false;
            },

            toggleEditState() {
                if (this.messageEditId === this.message.id) {
                    this.$emit('edit', undefined);
                } else {
                    this.$emit('edit', {id: this.message.id, content: this.content});
                }
            },

            async drop() {
                if (this.busy) return;

                this.busy = true;

                try {
                    await dropMessage(this.message.id);

                    this.$emit('dropped', this.message.id);

                    this.busy = false;
                } catch (e) {
                    this.$bvToast.toast(e.message);

                    this.busy = false;
                }
            },

            openMenu($event) {
                if(this.canEdit || this.canDrop) {
                    this.$refs.menu.open($event);
                }
            }
        },
        computed: {
            userId() {
                return this.$store.getters['auth/userId'];
            },

            messageContent() {
                return this.message.content;
            },
            contentFormatted() {
                return !!this.content ? linkifyHtml(this.content) : this.content;
            },

            isEncryptionAvailable() {
                switch (this.room.type) {
                    case ChatRoomType.PRIVATE:
                        return getters.isContactEncrypted(this.room.contactId);
                    default:
                        return getters.isRoomEncrypted(this.room.id);
                }
            },
            isEditing() {
                return typeof this.messageEditId !== 'undefined' && this.messageEditId === this.message.id;
            },
            isUserOnline() {
                return this.$store.getters['chat/roomMemberOnline'](this.message.roomId, this.message.userId).length === 1;
            },

            canEdit() {
                return this.userId !== 'undefined' && this.message.user !== 'undefined' && this.userId === this.message.user.id;
            },
            canDrop() {
                return this.userId !== 'undefined' && this.message.user !== 'undefined' && this.userId === this.message.user.id;
            }
        }
    }
</script>
<template>
    <div
        :class="{
                        'out': message.user && message.user.id === userId,
                        'in': message.user && message.user.id !== userId
                    }"
        class="chat-post clearfix"
    >
        <div class="position-relative">
            <user-avatar :email="message.user.email" :name="message.user.name" :avatar="message.user.avatar" size="30" class="avatar" />
            <div class="avatar-status" :class="{'online': isUserOnline, 'offline': !isUserOnline}"></div>
        </div>
        <div class="chat-container" @contextmenu.prevent="openMenu">
            <span class="arrow"></span>

            <div class="chat-meta d-flex flex-row flex-wrap">
                <div class="meta-title d-flex flex-row flex-wrap">
                    <nuxt-link class="meta-title-name" :to="'/user/'+message.user.id">
                        {{message.user.name}}
                        <i v-if="message.member && message.member.creator" class="fas fa-crown"></i>
                    </nuxt-link>
                    <span class="meta-title-time">
                        <span v-if="!message.updatedAt || message.updatedAt === message.createdAt">
                            <timeago class="ml-1" :datetime="message.createdAt" :auto-update="60"/>
                        </span>
                        <span v-else>
                            <timeago class="ml-1" :datetime="message.updatedAt" :auto-update="60"/> editiert
                        </span>
                    </span>
                </div>
                <div class="meta-actions d-flex">

                </div>
            </div>

            <div class="position-relative">
                <div class="chat-message" v-html="contentFormatted"></div>

                <client-only>
                    <vue-context v-if="canEdit || canDrop" ref="menu">
                        <li v-if="canEdit">
                            <a href="javascript:void(0)" class="mr-1" @click.prevent="toggleEditState">
                                <i class="fa" :class="{'fa-pencil-alt': !isEditing, 'fa-times': isEditing}"></i> Editieren
                            </a>
                        </li>
                        <li>
                            <a v-if="canDrop" href="javascript:void(0)" @click.prevent="drop">
                                <i class="fa fa-trash"></i> Löschen
                            </a>
                        </li>
                    </vue-context>
                </client-only>
            </div>
        </div>
    </div>
</template>
<style>
    .chat-post {
        transition: display .3s;
        padding: 5px 0;
        margin: 5px 10px;
        font-size: 13px
    }

    /*--------------------------------------------------------*/

    .chat-post .avatar {
        width: 30px;
        height: 30px;
        border-radius: 50%!important;
        box-shadow: 0 2px 4px 0 rgba(0,0,0,.1)!important;
    }

    .chat-post .avatar-status {
        height: 0.75rem;
        width: 0.75rem;
        border-radius: 100%;
        position: absolute;
        top: 1.4rem;
        border: 1px solid #dee2e6 !important;
        background: #CFD8DC;
    }

    .chat-post .avatar-status.online {
        background: #9CCC65;
    }

    .chat-post .avatar-status.offline {
        background: #FF5252;
    }

    .chat-post.in .avatar {
        float: left;
        margin-right: 10px
    }
    .chat-post.in .avatar-status {
        left:1.25rem;
    }

    .chat-post.out .avatar {
        float: right;
        margin-left: 10px
    }
    .chat-post.out .avatar-status {
        right:1.25rem;
    }

    /*--------------------------------------------------------*/

    .chat-post .chat-container {
        display: block;
        padding: 5px;
        position: relative;
        color: #90a1af;
        /* background: #36424c; */
        /* #EBECED */
        background: #EBECED;
        border-radius:3px;
        box-shadow: 0 4px 8px 0 rgba(0,0,0,.12), 0 2px 4px 0 rgba(0,0,0,.08);
    }

    .chat-post.in .chat-container {
        margin-left: 45px
    }

    .chat-post.out .chat-container {
        margin-right: 45px;
        /* green
        background: #ccf2cf;
        */
        background: #cc8181;
        color: #fff
    }

    .chat-post .chat-container > .arrow {
        display: block;
        position: absolute;
        border-top: 8px solid transparent;
        border-bottom: 8px solid transparent;
    }

    .chat-post.in .chat-container > .arrow {
        top: 9px;
        left: -10px;
        border-right: 10px solid #EBECED;
    }

    .chat-post.out .chat-container > .arrow {
        top: 9px;
        right: -10px;
        border-left: 10px solid #cc8181;
    }

    /*--------------------------------------------------------*/

    .chat-post .chat-meta {
        line-height: 1rem;
    }

    /*--------------------------------------------------------*/

    .chat-post.in .chat-meta .meta-title {
        order: 1
    }

    .chat-post.out .chat-meta .meta-title {
        order: 2
    }

    /*--------------------------------------------------------*/

    .chat-post .chat-meta .meta-title-name {
        color: #8496a7;
        font-weight: bold;
        font-size: 0.8rem;
        margin-right: 0.1rem;
        text-decoration: none;
    }

    .chat-post.in .chat-meta .meta-title-name {
        order: 1;
    }

    .chat-post.out .chat-meta .meta-title-name {
        order: 1;
        color: #6f2300;
    }

    /*--------------------------------------------------------*/

    .chat-post .chat-meta .meta-title-time {
        font-size:0.6rem;
        color: #aaa;
    }

    .chat-post.in .chat-meta .meta-title-time {
        order: 2;
    }

    .chat-post.out .chat-meta .meta-title-time {
        order: 2;
        color: #eee;
    }

    /*--------------------------------------------------------*/

    .chat-post.in .chat-meta .meta-actions {
        order: 2;
        margin-left: auto;
    }

    .chat-post.out .chat-meta .meta-actions {
        margin-right: auto;
        order: 1;
    }

    .chat-post.out .chat-meta .meta-actions a {
        color: #eee;
    }

    /*--------------------------------------------------------*/

    .chat-post.out .chat-message {
        text-align: right;
    }

    .chat-post.out .chat-message a {
        color: #6f2300;
    }
</style>
