<template>
    <safe-dialog
        ref="avatarDialogRef"
        class="x-dialog x-avatar-dialog"
        :visible.sync="avatarDialog.visible"
        :show-close="false"
        width="700px">
        <div v-loading="avatarDialog.loading">
            <div style="display: flex">
                <el-popover placement="right" width="500px" trigger="click">
                    <img
                        slot="reference"
                        v-lazy="avatarDialog.ref.thumbnailImageUrl"
                        class="x-link"
                        style="flex: none; width: 160px; height: 120px; border-radius: 12px" />
                    <img
                        v-lazy="avatarDialog.ref.imageUrl"
                        class="x-link"
                        style="width: 500px; height: 375px"
                        @click="showFullscreenImageDialog(avatarDialog.ref.imageUrl)" />
                </el-popover>
                <div style="flex: 1; display: flex; align-items: center; margin-left: 15px">
                    <div style="flex: 1">
                        <div>
                            <span class="dialog-title" v-text="avatarDialog.ref.name"></span>
                        </div>
                        <div style="margin-top: 5px">
                            <span
                                class="x-link x-grey"
                                style="font-family: monospace"
                                @click="showUserDialog(avatarDialog.ref.authorId)"
                                v-text="avatarDialog.ref.authorName"></span>
                        </div>
                        <div>
                            <el-tag
                                v-if="avatarDialog.ref.releaseStatus === 'public'"
                                type="success"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                >{{ t('dialog.avatar.tags.public') }}</el-tag
                            >
                            <el-tag
                                v-else
                                type="danger"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                >{{ t('dialog.avatar.tags.private') }}</el-tag
                            >
                            <el-tag
                                v-if="avatarDialog.isPC"
                                class="x-tag-platform-pc"
                                type="info"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                >PC
                                <span
                                    v-if="avatarDialog.platformInfo.pc"
                                    class="x-grey"
                                    style="margin-left: 5px; border-left: inherit; padding-left: 5px"
                                    >{{ avatarDialog.platformInfo.pc.performanceRating }}</span
                                >
                                <span
                                    v-if="avatarDialog.bundleSizes['standalonewindows']"
                                    class="x-grey"
                                    style="margin-left: 5px; border-left: inherit; padding-left: 5px"
                                    >{{ avatarDialog.bundleSizes['standalonewindows'].fileSize }}</span
                                >
                            </el-tag>
                            <el-tag
                                v-if="avatarDialog.isQuest"
                                class="x-tag-platform-quest"
                                type="info"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                >Android
                                <span
                                    v-if="avatarDialog.platformInfo.android"
                                    class="x-grey"
                                    style="margin-left: 5px; border-left: inherit; padding-left: 5px"
                                    >{{ avatarDialog.platformInfo.android.performanceRating }}</span
                                >
                                <span
                                    v-if="avatarDialog.bundleSizes['android']"
                                    class="x-grey"
                                    style="margin-left: 5px; border-left: inherit; padding-left: 5px"
                                    >{{ avatarDialog.bundleSizes['android'].fileSize }}</span
                                >
                            </el-tag>
                            <el-tag
                                v-if="avatarDialog.isIos"
                                class="x-tag-platform-ios"
                                type="info"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                >iOS
                                <span
                                    v-if="avatarDialog.platformInfo.ios"
                                    class="x-grey"
                                    style="margin-left: 5px; border-left: inherit; padding-left: 5px"
                                    >{{ avatarDialog.platformInfo.ios.performanceRating }}</span
                                >
                                <span
                                    v-if="avatarDialog.bundleSizes['ios']"
                                    class="x-grey"
                                    style="margin-left: 5px; border-left: inherit; padding-left: 5px"
                                    >{{ avatarDialog.bundleSizes['ios'].fileSize }}</span
                                >
                            </el-tag>
                            <el-tag
                                v-if="avatarDialog.inCache"
                                class="x-link"
                                type="info"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                @click="openFolderGeneric(avatarDialog.cachePath)">
                                <span v-text="avatarDialog.cacheSize"></span>
                                &nbsp;{{ t('dialog.avatar.tags.cache') }}
                            </el-tag>
                            <el-tag
                                v-if="avatarDialog.ref.styles?.primary || avatarDialog.ref.styles?.secondary"
                                type="info"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                >Styles
                                <span
                                    v-if="avatarDialog.ref.styles.primary"
                                    class="x-grey"
                                    style="margin-left: 5px; border-left: inherit; padding-left: 5px"
                                    >{{ avatarDialog.ref.styles.primary }}</span
                                >
                                <span
                                    v-if="avatarDialog.ref.styles.secondary"
                                    class="x-grey"
                                    style="margin-left: 5px; border-left: inherit; padding-left: 5px"
                                    >{{ avatarDialog.ref.styles.secondary }}</span
                                >
                            </el-tag>
                            <el-tag
                                v-if="avatarDialog.isQuestFallback"
                                type="info"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                >{{ t('dialog.avatar.tags.fallback') }}</el-tag
                            >
                            <el-tag
                                v-if="avatarDialog.hasImposter"
                                type="info"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                >{{ t('dialog.avatar.tags.impostor') }}
                                <span
                                    v-if="avatarDialog.imposterVersion"
                                    class="x-grey"
                                    style="margin-left: 5px; border-left: inherit; padding-left: 5px"
                                    >v{{ avatarDialog.imposterVersion }}</span
                                >
                            </el-tag>
                            <el-tag
                                v-if="avatarDialog.ref.unityPackageUrl"
                                type="success"
                                effect="plain"
                                size="mini"
                                style="margin-right: 5px; margin-top: 5px"
                                >{{ t('dialog.avatar.tags.future_proofing') }}</el-tag
                            >
                            <div>
                                <template v-for="tag in avatarDialog.ref.tags">
                                    <el-tag
                                        v-if="tag.startsWith('content_')"
                                        :key="tag"
                                        effect="plain"
                                        size="mini"
                                        style="margin-right: 5px; margin-top: 5px">
                                        <template v-if="tag === 'content_horror'">{{
                                            t('dialog.avatar.tags.content_horror')
                                        }}</template>
                                        <template v-else-if="tag === 'content_gore'">{{
                                            t('dialog.avatar.tags.content_gore')
                                        }}</template>
                                        <template v-else-if="tag === 'content_violence'">{{
                                            t('dialog.avatar.tags.content_violence')
                                        }}</template>
                                        <template v-else-if="tag === 'content_adult'">{{
                                            t('dialog.avatar.tags.content_adult')
                                        }}</template>
                                        <template v-else-if="tag === 'content_sex'">{{
                                            t('dialog.avatar.tags.content_sex')
                                        }}</template>
                                        <template v-else>{{ tag.replace('content_', '') }}</template>
                                    </el-tag>
                                    <el-tag
                                        v-if="tag.startsWith('author_tag_')"
                                        :key="tag"
                                        effect="plain"
                                        size="mini"
                                        style="margin-right: 5px; margin-top: 5px">
                                        <template>
                                            {{ tag.replace('author_tag_', '') }}
                                        </template>
                                    </el-tag>
                                </template>
                            </div>
                        </div>
                        <div style="margin-top: 5px">
                            <span
                                v-show="avatarDialog.ref.name !== avatarDialog.ref.description"
                                style="font-size: 12px"
                                v-text="avatarDialog.ref.description"></span>
                        </div>
                    </div>
                    <div style="flex: none; margin-left: 10px">
                        <el-tooltip
                            v-if="avatarDialog.inCache"
                            placement="top"
                            :content="t('dialog.avatar.actions.delete_cache_tooltip')"
                            :disabled="hideTooltips">
                            <el-button
                                icon="el-icon-delete"
                                circle
                                :disabled="isGameRunning && avatarDialog.cacheLocked"
                                @click="deleteVRChatCache(avatarDialog.ref)"></el-button>
                        </el-tooltip>
                        <el-tooltip
                            v-if="avatarDialog.isFavorite"
                            placement="top"
                            :content="t('dialog.avatar.actions.favorite_tooltip')"
                            :disabled="hideTooltips">
                            <el-button
                                type="warning"
                                icon="el-icon-star-on"
                                circle
                                style="margin-left: 5px"
                                @click="avatarDialogCommand('Add Favorite')"></el-button>
                        </el-tooltip>
                        <el-tooltip
                            v-else
                            placement="top"
                            :content="t('dialog.avatar.actions.favorite_tooltip')"
                            :disabled="hideTooltips">
                            <el-button
                                type="default"
                                icon="el-icon-star-off"
                                circle
                                style="margin-left: 5px"
                                @click="avatarDialogCommand('Add Favorite')"></el-button>
                        </el-tooltip>
                        <el-tooltip
                            placement="top"
                            :content="t('dialog.avatar.actions.select')"
                            :disabled="hideTooltips">
                            <el-button
                                type="default"
                                icon="el-icon-check"
                                circle
                                :disabled="currentUser.currentAvatar === avatarDialog.id"
                                style="margin-left: 5px"
                                @click="selectAvatarWithoutConfirmation(avatarDialog.id)"></el-button>
                        </el-tooltip>
                        <el-dropdown
                            trigger="click"
                            size="small"
                            style="margin-left: 5px"
                            @command="avatarDialogCommand">
                            <el-button
                                :type="avatarDialog.isBlocked ? 'danger' : 'default'"
                                icon="el-icon-more"
                                circle></el-button>
                            <el-dropdown-menu>
                                <el-dropdown-item icon="el-icon-refresh" command="Refresh">{{
                                    t('dialog.avatar.actions.refresh')
                                }}</el-dropdown-item>
                                <el-dropdown-item icon="el-icon-share" command="Share">{{
                                    t('dialog.avatar.actions.share')
                                }}</el-dropdown-item>
                                <el-dropdown-item
                                    v-if="avatarDialog.isBlocked"
                                    icon="el-icon-circle-check"
                                    command="Unblock Avatar"
                                    style="color: #f56c6c"
                                    divided
                                    >{{ t('dialog.avatar.actions.unblock') }}</el-dropdown-item
                                >
                                <el-dropdown-item v-else icon="el-icon-circle-close" command="Block Avatar" divided>{{
                                    t('dialog.avatar.actions.block')
                                }}</el-dropdown-item>
                                <el-dropdown-item
                                    v-if="/quest/.test(avatarDialog.ref.tags)"
                                    icon="el-icon-check"
                                    command="Select Fallback Avatar"
                                    >{{ t('dialog.avatar.actions.select_fallback') }}</el-dropdown-item
                                >
                                <el-dropdown-item
                                    v-if="avatarDialog.ref.authorId !== currentUser.id"
                                    icon="el-icon-picture-outline"
                                    command="Previous Images"
                                    >{{ t('dialog.avatar.actions.show_previous_images') }}</el-dropdown-item
                                >
                                <template v-if="avatarDialog.ref.authorId === currentUser.id">
                                    <el-dropdown-item
                                        v-if="avatarDialog.ref.releaseStatus === 'public'"
                                        icon="el-icon-user-solid"
                                        command="Make Private"
                                        divided
                                        >{{ t('dialog.avatar.actions.make_private') }}</el-dropdown-item
                                    >
                                    <el-dropdown-item v-else icon="el-icon-user" command="Make Public" divided>{{
                                        t('dialog.avatar.actions.make_public')
                                    }}</el-dropdown-item>
                                    <el-dropdown-item icon="el-icon-edit" command="Rename">{{
                                        t('dialog.avatar.actions.rename')
                                    }}</el-dropdown-item>
                                    <el-dropdown-item icon="el-icon-edit" command="Change Description">{{
                                        t('dialog.avatar.actions.change_description')
                                    }}</el-dropdown-item>
                                    <el-dropdown-item icon="el-icon-edit" command="Change Content Tags">{{
                                        t('dialog.avatar.actions.change_content_tags')
                                    }}</el-dropdown-item>
                                    <el-dropdown-item icon="el-icon-edit" command="Change Styles and Author Tags">{{
                                        t('dialog.avatar.actions.change_styles_author_tags')
                                    }}</el-dropdown-item>
                                    <el-dropdown-item icon="el-icon-picture-outline" command="Change Image">{{
                                        t('dialog.avatar.actions.change_image')
                                    }}</el-dropdown-item>
                                    <el-dropdown-item
                                        v-if="avatarDialog.ref.unityPackageUrl"
                                        icon="el-icon-download"
                                        command="Download Unity Package"
                                        >{{ t('dialog.avatar.actions.download_package') }}</el-dropdown-item
                                    >
                                    <el-dropdown-item
                                        v-if="avatarDialog.hasImposter"
                                        icon="el-icon-refresh"
                                        command="Regenerate Imposter"
                                        style="color: #f56c6c"
                                        divided
                                        >{{ t('dialog.avatar.actions.regenerate_impostor') }}</el-dropdown-item
                                    >
                                    <el-dropdown-item
                                        v-if="avatarDialog.hasImposter"
                                        icon="el-icon-delete"
                                        command="Delete Imposter"
                                        style="color: #f56c6c"
                                        >{{ t('dialog.avatar.actions.delete_impostor') }}</el-dropdown-item
                                    >
                                    <el-dropdown-item v-else icon="el-icon-user" command="Create Imposter" divided>{{
                                        t('dialog.avatar.actions.create_impostor')
                                    }}</el-dropdown-item>
                                    <el-dropdown-item icon="el-icon-delete" command="Delete" style="color: #f56c6c">{{
                                        t('dialog.avatar.actions.delete')
                                    }}</el-dropdown-item>
                                </template>
                            </el-dropdown-menu>
                        </el-dropdown>
                    </div>
                </div>
            </div>
            <el-tabs>
                <el-tab-pane :label="t('dialog.avatar.info.header')">
                    <div class="x-friend-list" style="max-height: unset">
                        <div
                            v-if="avatarDialog.galleryImages.length || avatarDialog.ref.authorId === currentUser.id"
                            style="width: 100%">
                            <span class="name">{{ t('dialog.avatar.info.gallery') }}</span>
                            <input
                                id="AvatarGalleryUploadButton"
                                type="file"
                                accept="image/*"
                                style="display: none"
                                @change="onFileChangeAvatarGallery" />
                            <el-button
                                v-if="avatarDialog.ref.authorId === currentUser.id"
                                :disabled="!!avatarDialog.galleryLoading"
                                size="small"
                                icon="el-icon-upload2"
                                style="margin-left: 5px"
                                @click="displayAvatarGalleryUpload"
                                >{{ t('dialog.screenshot_metadata.upload') }}</el-button
                            >
                            <el-carousel
                                v-if="avatarDialog.galleryImages.length"
                                type="card"
                                :autoplay="false"
                                height="200px">
                                <el-carousel-item v-for="imageUrl in avatarDialog.galleryImages" :key="imageUrl">
                                    <img
                                        :src="imageUrl"
                                        style="width: 100%; height: 100%; object-fit: contain"
                                        @click="showFullscreenImageDialog(imageUrl)" />
                                    <div
                                        v-if="avatarDialog.ref.authorId === currentUser.id"
                                        style="position: absolute; bottom: 5px; left: 33.3%">
                                        <el-button
                                            size="mini"
                                            icon="el-icon-back"
                                            circle
                                            class="x-link"
                                            style="margin-left: 0"
                                            @click.stop="reorderAvatarGalleryImage(imageUrl, -1)"></el-button>
                                        <el-button
                                            size="mini"
                                            icon="el-icon-right"
                                            circle
                                            class="x-link"
                                            style="margin-left: 0"
                                            @click.stop="reorderAvatarGalleryImage(imageUrl, 1)"></el-button>
                                        <el-button
                                            size="mini"
                                            icon="el-icon-delete"
                                            circle
                                            class="x-link"
                                            style="margin-left: 0"
                                            @click.stop="deleteAvatarGalleryImage(imageUrl)"></el-button>
                                    </div>
                                </el-carousel-item>
                            </el-carousel>
                        </div>
                        <div v-if="avatarDialog.ref.publishedListings?.length">
                            <span class="name">{{ t('dialog.avatar.info.listings') }}</span>
                            <div
                                v-for="listing in avatarDialog.ref.publishedListings"
                                :key="listing.id"
                                class="x-friend-item"
                                style="width: 100%; cursor: default">
                                <div class="avatar">
                                    <img
                                        :src="getImageUrlFromImageId(listing.imageId)"
                                        @click="showFullscreenImageDialog(getImageUrlFromImageId(listing.imageId))" />
                                </div>
                                <div class="detail">
                                    <span class="name">{{ listing.displayName }}</span>
                                    <span class="extra" style="text-decoration: underline; font-style: italic"
                                        >${{ commaNumber(listing.priceTokens) }}V</span
                                    >
                                    <span
                                        class="extra"
                                        style="text-overflow: ellipsis; text-wrap: auto"
                                        v-text="listing.description"></span>
                                </div>
                            </div>
                        </div>
                        <div class="x-friend-item" style="width: 100%; cursor: default">
                            <div class="detail">
                                <span class="name" style="margin-bottom: 5px">{{ t('dialog.avatar.info.memo') }}</span>
                                <el-input
                                    v-model="memo"
                                    class="extra"
                                    size="mini"
                                    type="textarea"
                                    :rows="2"
                                    :autosize="{ minRows: 1, maxRows: 20 }"
                                    :placeholder="t('dialog.avatar.info.memo_placeholder')"
                                    resize="none"
                                    @change="onAvatarMemoChange"></el-input>
                            </div>
                        </div>
                        <div class="x-friend-item" style="width: 100%; cursor: default">
                            <div class="detail">
                                <span class="name">{{ t('dialog.avatar.info.id') }}</span>
                                <span class="extra"
                                    >{{ avatarDialog.id
                                    }}<el-tooltip
                                        placement="top"
                                        :content="t('dialog.avatar.info.id_tooltip')"
                                        :disabled="hideTooltips">
                                        <el-dropdown
                                            trigger="click"
                                            size="mini"
                                            style="margin-left: 5px"
                                            @click.native.stop>
                                            <el-button
                                                type="default"
                                                icon="el-icon-s-order"
                                                size="mini"
                                                circle></el-button>
                                            <el-dropdown-menu>
                                                <el-dropdown-item @click.native="copyAvatarId(avatarDialog.id)">{{
                                                    t('dialog.avatar.info.copy_id')
                                                }}</el-dropdown-item>
                                                <el-dropdown-item @click.native="copyAvatarUrl(avatarDialog.id)">{{
                                                    t('dialog.avatar.info.copy_url')
                                                }}</el-dropdown-item>
                                            </el-dropdown-menu>
                                        </el-dropdown>
                                    </el-tooltip></span
                                >
                            </div>
                        </div>
                        <div class="x-friend-item" style="cursor: default">
                            <div class="detail">
                                <span class="name">{{ t('dialog.avatar.info.created_at') }}</span>
                                <span class="extra">{{ formatDateFilter(avatarDialog.ref.created_at, 'long') }}</span>
                            </div>
                        </div>
                        <div class="x-friend-item" style="cursor: default">
                            <div class="detail">
                                <span class="name">{{ t('dialog.avatar.info.last_updated') }}</span>
                                <span v-if="avatarDialog.lastUpdated" class="extra">{{
                                    formatDateFilter(avatarDialog.lastUpdated, 'long')
                                }}</span>
                                <span v-else class="extra">{{
                                    formatDateFilter(avatarDialog.ref.updated_at, 'long')
                                }}</span>
                            </div>
                        </div>
                        <div class="x-friend-item" style="cursor: default">
                            <div class="detail">
                                <span class="name">{{ t('dialog.avatar.info.version') }}</span>
                                <span
                                    v-if="avatarDialog.ref.version !== 0"
                                    class="extra"
                                    v-text="avatarDialog.ref.version"></span>
                                <span v-else class="extra">-</span>
                            </div>
                        </div>
                        <div class="x-friend-item" style="cursor: default">
                            <div class="detail">
                                <span class="name"
                                    >{{ t('dialog.avatar.info.time_spent')
                                    }}<el-tooltip
                                        v-if="!hideTooltips"
                                        placement="top"
                                        style="margin-left: 5px"
                                        :content="t('dialog.world.info.accuracy_notice')">
                                        <i class="el-icon-warning"></i> </el-tooltip
                                ></span>

                                <span v-if="timeSpent === 0" class="extra">-</span>
                                <span v-else class="extra">{{ timeToText(timeSpent) }}</span>
                            </div>
                        </div>
                        <div class="x-friend-item" style="width: 100%; cursor: default">
                            <div class="detail">
                                <span class="name">{{ t('dialog.avatar.info.platform') }}</span>
                                <span v-if="avatarDialogPlatform" class="extra" v-text="avatarDialogPlatform"></span>
                                <span v-else class="extra">-</span>
                            </div>
                        </div>
                    </div>
                </el-tab-pane>
                <el-tab-pane :label="t('dialog.avatar.json.header')">
                    <el-button
                        type="default"
                        size="mini"
                        icon="el-icon-refresh"
                        circle
                        @click="refreshAvatarDialogTreeData"></el-button>
                    <el-button
                        type="default"
                        size="mini"
                        icon="el-icon-download"
                        circle
                        style="margin-left: 5px"
                        @click="downloadAndSaveJson(avatarDialog.id, avatarDialog.ref)"></el-button>
                    <el-tree
                        v-if="Object.keys(avatarDialog.fileAnalysis).length > 0"
                        :data="avatarDialog.fileAnalysis"
                        style="margin-top: 5px; font-size: 12px">
                        <template #default="scope">
                            <span>
                                <span style="font-weight: bold; margin-right: 5px" v-text="scope.data.key"></span>
                                <span v-if="!scope.data.children" v-text="scope.data.value"></span>
                            </span>
                        </template>
                    </el-tree>
                    <el-tree :data="treeData" style="margin-top: 5px; font-size: 12px">
                        <template #default="scope">
                            <span>
                                <span style="font-weight: bold; margin-right: 5px" v-text="scope.data.key"></span>
                                <span v-if="!scope.data.children" v-text="scope.data.value"></span>
                            </span>
                        </template>
                    </el-tree>
                </el-tab-pane>
            </el-tabs>
        </div>
        <SetAvatarTagsDialog :set-avatar-tags-dialog="setAvatarTagsDialog" />
        <SetAvatarStylesDialog :set-avatar-styles-dialog="setAvatarStylesDialog" />
        <ChangeAvatarImageDialog
            :change-avatar-image-dialog-visible.sync="changeAvatarImageDialogVisible"
            :previous-images-file-id="previousImagesFileId"
            @refresh="displayPreviousImages" />
        <PreviousImagesDialog />
    </safe-dialog>
</template>

<script setup>
    import { storeToRefs } from 'pinia';
    import { computed, getCurrentInstance, nextTick, reactive, ref, watch } from 'vue';
    import { useI18n } from 'vue-i18n-bridge';
    import { avatarModerationRequest, avatarRequest, favoriteRequest, imageRequest, miscRequest } from '../../../api';
    import { database } from '../../../service/database';
    import {
        adjustDialogZ,
        buildTreeData,
        commaNumber,
        compareUnityVersion,
        copyToClipboard,
        downloadAndSaveJson,
        extractFileId,
        extractFileVersion,
        openExternalLink,
        openFolderGeneric,
        replaceVrcPackageUrl,
        storeAvatarImage,
        timeToText,
        moveArrayItem,
        formatDateFilter
    } from '../../../shared/utils';
    import {
        useAppearanceSettingsStore,
        useAvatarStore,
        useFavoriteStore,
        useGalleryStore,
        useGameStore,
        useUserStore
    } from '../../../stores';
    import PreviousImagesDialog from '../PreviousImagesDialog.vue';
    import ChangeAvatarImageDialog from './ChangeAvatarImageDialog.vue';
    import SetAvatarStylesDialog from './SetAvatarStylesDialog.vue';
    import SetAvatarTagsDialog from './SetAvatarTagsDialog.vue';

    const { hideTooltips } = storeToRefs(useAppearanceSettingsStore());
    const { showUserDialog, sortUserDialogAvatars } = useUserStore();
    const { userDialog, currentUser } = storeToRefs(useUserStore());
    const { avatarDialog, cachedAvatarModerations, cachedAvatars, cachedAvatarNames } = storeToRefs(useAvatarStore());
    const { showAvatarDialog, getAvatarGallery, applyAvatarModeration, applyAvatar, selectAvatarWithoutConfirmation } =
        useAvatarStore();
    const { showFavoriteDialog } = useFavoriteStore();
    const { isGameRunning } = storeToRefs(useGameStore());
    const { deleteVRChatCache } = useGameStore();
    const { previousImagesDialogVisible, previousImagesTable } = storeToRefs(useGalleryStore());
    const { showFullscreenImageDialog, checkPreviousImageAvailable } = useGalleryStore();

    const { t } = useI18n();
    const instance = getCurrentInstance();
    const { $message, $confirm, $prompt } = instance.proxy;

    defineEmits(['openPreviousImagesDialog']);

    const avatarDialogRef = ref(null);
    const changeAvatarImageDialogVisible = ref(false);
    const previousImagesFileId = ref('');

    const treeData = ref([]);
    const timeSpent = ref(0);
    const memo = ref('');
    const setAvatarTagsDialog = reactive({
        visible: false,
        loading: false,
        ownAvatars: [],
        selectedCount: 0,
        forceUpdate: 0,
        selectedTags: [],
        selectedTagsCsv: '',
        contentHorror: false,
        contentGore: false,
        contentViolence: false,
        contentAdult: false,
        contentSex: false
    });
    const setAvatarStylesDialog = reactive({
        visible: false,
        loading: false,
        avatarId: '',
        initialPrimaryStyle: '',
        initialSecondaryStyle: '',
        primaryStyle: '',
        secondaryStyle: '',
        availableAvatarStyles: [],
        availableAvatarStylesMap: new Map(),
        initialTags: [],
        authorTags: ''
    });

    const avatarDialogPlatform = computed(() => {
        const { ref } = avatarDialog.value;
        const platforms = [];
        if (ref.unityPackages) {
            for (const unityPackage of ref.unityPackages) {
                if (
                    unityPackage.variant &&
                    unityPackage.variant !== 'standard' &&
                    unityPackage.variant !== 'security'
                ) {
                    continue;
                }
                let platform = 'PC';
                if (unityPackage.platform === 'standalonewindows') {
                    platform = 'PC';
                } else if (unityPackage.platform === 'android') {
                    platform = 'Android';
                } else if (unityPackage.platform) {
                    ({ platform } = unityPackage);
                }
                platforms.push(`${platform}/${unityPackage.unityVersion}`);
            }
        }
        return platforms.join(', ');
    });

    watch(
        () => avatarDialog.value.loading,
        (newVal) => {
            if (newVal) {
                nextTick(() => {
                    const D = avatarDialog.value;
                    if (D.visible) {
                        adjustDialogZ(avatarDialogRef.value.$el);
                    }
                });
                handleDialogOpen();
            }
        }
    );

    function getImageUrlFromImageId(imageId) {
        return `https://api.vrchat.cloud/api/1/file/${imageId}/1/`;
    }

    function handleDialogOpen() {
        avatarDialog.value.fileAnalysis = {};
        memo.value = '';
        treeData.value = [];
        getAvatarTimeSpent();
        getAvatarMemo();
    }

    function getAvatarTimeSpent() {
        const D = avatarDialog.value;
        database.getAvatarTimeSpent(D.id).then((aviTime) => {
            if (D.id === aviTime.avatarId) {
                timeSpent.value = aviTime.timeSpent;
                if (D.id === currentUser.value.currentAvatar && currentUser.value.$previousAvatarSwapTime) {
                    timeSpent.value += Date.now() - currentUser.value.$previousAvatarSwapTime;
                }
            }
        });
    }

    function getAvatarMemo() {
        const D = avatarDialog.value;
        database.getAvatarMemoDB(D.id).then((res) => {
            if (D.id === res.avatarId) {
                memo.value = res.memo;
            }
        });
    }

    function avatarDialogCommand(command) {
        const D = avatarDialog.value;
        switch (command) {
            case 'Refresh':
                showAvatarDialog(D.id);
                break;
            case 'Share':
                copyAvatarUrl(D.id);
                break;
            case 'Rename':
                promptRenameAvatar(D);
                break;
            case 'Change Image':
                displayPreviousImages('Change');
                break;
            case 'Previous Images':
                displayPreviousImages('Display');
                break;
            case 'Change Description':
                promptChangeAvatarDescription(D);
                break;
            case 'Change Content Tags':
                showSetAvatarTagsDialog(D.id);
                break;
            case 'Change Styles and Author Tags':
                showSetAvatarStylesDialog();
                break;
            case 'Download Unity Package':
                openExternalLink(replaceVrcPackageUrl(avatarDialog.value.ref.unityPackageUrl));
                break;
            case 'Add Favorite':
                showFavoriteDialog('avatar', D.id);
                break;
            default:
                $confirm(`Continue? ${command}`, 'Confirm', {
                    confirmButtonText: 'Confirm',
                    cancelButtonText: 'Cancel',
                    type: 'info',
                    callback: (action) => {
                        if (action !== 'confirm') {
                            return;
                        }
                        switch (command) {
                            case 'Delete Favorite':
                                favoriteRequest.deleteFavorite({
                                    objectId: D.id
                                });
                                break;
                            case 'Select Fallback Avatar':
                                avatarRequest
                                    .selectFallbackAvatar({
                                        avatarId: D.id
                                    })
                                    .then((args) => {
                                        $message({
                                            message: 'Fallback avatar changed',
                                            type: 'success'
                                        });
                                        return args;
                                    });
                                break;
                            case 'Block Avatar':
                                avatarModerationRequest
                                    .sendAvatarModeration({
                                        avatarModerationType: 'block',
                                        targetAvatarId: D.id
                                    })
                                    .then((args) => {
                                        // 'AVATAR-MODERATION';
                                        applyAvatarModeration(args.json);
                                        $message({
                                            message: 'Avatar blocked',
                                            type: 'success'
                                        });
                                        return args;
                                    });
                                break;
                            case 'Unblock Avatar':
                                avatarModerationRequest
                                    .deleteAvatarModeration({
                                        avatarModerationType: 'block',
                                        targetAvatarId: D.id
                                    })
                                    .then((args) => {
                                        cachedAvatarModerations.value.delete(args.params.targetAvatarId);
                                        const D = avatarDialog.value;
                                        if (
                                            args.params.avatarModerationType === 'block' &&
                                            D.id === args.params.targetAvatarId
                                        ) {
                                            D.isBlocked = false;
                                        }
                                    });
                                break;
                            case 'Make Public':
                                avatarRequest
                                    .saveAvatar({
                                        id: D.id,
                                        releaseStatus: 'public'
                                    })
                                    .then((args) => {
                                        applyAvatar(args.json);
                                        $message({
                                            message: 'Avatar updated to public',
                                            type: 'success'
                                        });
                                        return args;
                                    });
                                break;
                            case 'Make Private':
                                avatarRequest
                                    .saveAvatar({
                                        id: D.id,
                                        releaseStatus: 'private'
                                    })
                                    .then((args) => {
                                        applyAvatar(args.json);
                                        $message({
                                            message: 'Avatar updated to private',
                                            type: 'success'
                                        });
                                        return args;
                                    });
                                break;
                            case 'Delete':
                                avatarRequest
                                    .deleteAvatar({
                                        avatarId: D.id
                                    })
                                    .then((args) => {
                                        const { json } = args;
                                        cachedAvatars.value.delete(json._id);
                                        if (userDialog.value.id === json.authorId) {
                                            const map = new Map();
                                            for (const ref of cachedAvatars.value.values()) {
                                                if (ref.authorId === json.authorId) {
                                                    map.set(ref.id, ref);
                                                }
                                            }
                                            const array = Array.from(map.values());
                                            sortUserDialogAvatars(array);
                                        }

                                        $message({
                                            message: 'Avatar deleted',
                                            type: 'success'
                                        });
                                        D.visible = false;
                                        return args;
                                    });
                                break;
                            case 'Delete Imposter':
                                avatarRequest
                                    .deleteImposter({
                                        avatarId: D.id
                                    })
                                    .then((args) => {
                                        $message({
                                            message: 'Imposter deleted',
                                            type: 'success'
                                        });
                                        showAvatarDialog(D.id);
                                        return args;
                                    });
                                break;
                            case 'Create Imposter':
                                avatarRequest
                                    .createImposter({
                                        avatarId: D.id
                                    })
                                    .then((args) => {
                                        $message({
                                            message: 'Imposter queued for creation',
                                            type: 'success'
                                        });
                                        return args;
                                    });
                                break;
                            case 'Regenerate Imposter':
                                avatarRequest
                                    .deleteImposter({
                                        avatarId: D.id
                                    })
                                    .then((args) => {
                                        showAvatarDialog(D.id);
                                        return args;
                                    })
                                    .finally(() => {
                                        avatarRequest
                                            .createImposter({
                                                avatarId: D.id
                                            })
                                            .then((args) => {
                                                $message({
                                                    message: 'Imposter deleted and queued for creation',
                                                    type: 'success'
                                                });
                                                return args;
                                            });
                                    });
                                break;
                        }
                    }
                });
                break;
        }
    }

    function displayPreviousImages(command) {
        previousImagesTable.value = [];
        previousImagesFileId.value = '';
        const { imageUrl } = avatarDialog.value.ref;
        const fileId = extractFileId(imageUrl);
        if (!fileId) {
            return;
        }
        const params = {
            fileId
        };
        if (command === 'Display') {
            previousImagesDialogVisible.value = true;
        }
        if (command === 'Change') {
            changeAvatarImageDialogVisible.value = true;
        }
        imageRequest.getAvatarImages(params).then((args) => {
            storeAvatarImage(args, cachedAvatarNames.value);
            previousImagesFileId.value = args.json.id;

            const images = [];
            args.json.versions.forEach((item) => {
                if (!item.deleted) {
                    images.unshift(item);
                }
            });
            checkPreviousImageAvailable(images);
        });
    }

    function promptChangeAvatarDescription(avatar) {
        $prompt(t('prompt.change_avatar_description.description'), t('prompt.change_avatar_description.header'), {
            distinguishCancelAndClose: true,
            confirmButtonText: t('prompt.change_avatar_description.ok'),
            cancelButtonText: t('prompt.change_avatar_description.cancel'),
            inputValue: avatar.ref.description,
            inputErrorMessage: t('prompt.change_avatar_description.input_error'),
            callback: (action, instance) => {
                if (action === 'confirm' && instance.inputValue !== avatar.ref.description) {
                    avatarRequest
                        .saveAvatar({
                            id: avatar.id,
                            description: instance.inputValue
                        })
                        .then((args) => {
                            applyAvatar(args.json);
                            $message({
                                message: t('prompt.change_avatar_description.message.success'),
                                type: 'success'
                            });
                            return args;
                        });
                }
            }
        });
    }

    function promptRenameAvatar(avatar) {
        $prompt(t('prompt.rename_avatar.description'), t('prompt.rename_avatar.header'), {
            distinguishCancelAndClose: true,
            confirmButtonText: t('prompt.rename_avatar.ok'),
            cancelButtonText: t('prompt.rename_avatar.cancel'),
            inputValue: avatar.ref.name,
            inputErrorMessage: t('prompt.rename_avatar.input_error'),
            callback: (action, instance) => {
                if (action === 'confirm' && instance.inputValue !== avatar.ref.name) {
                    avatarRequest
                        .saveAvatar({
                            id: avatar.id,
                            name: instance.inputValue
                        })
                        .then((args) => {
                            applyAvatar(args.json);
                            $message({
                                message: t('prompt.rename_avatar.message.success'),
                                type: 'success'
                            });
                            return args;
                        });
                }
            }
        });
    }

    function onAvatarMemoChange() {
        if (memo.value) {
            database.setAvatarMemo({
                avatarId: avatarDialog.value.id,
                editedAt: new Date().toJSON(),
                memo: memo.value
            });
        } else {
            database.deleteAvatarMemo(avatarDialog.value.id);
        }
    }

    function copyAvatarId(id) {
        copyToClipboard(id);
    }

    function copyAvatarUrl(id) {
        copyToClipboard(`https://vrchat.com/home/avatar/${id}`);
    }

    function refreshAvatarDialogTreeData() {
        treeData.value = buildTreeData(avatarDialog.value.ref);
    }

    function showSetAvatarTagsDialog(avatarId) {
        const D = setAvatarTagsDialog;
        D.visible = true;
        D.loading = true;
        D.ownAvatars = [];
        D.forceUpdate = 0;
        D.selectedTags = [];
        D.selectedTagsCsv = '';
        D.contentHorror = false;
        D.contentGore = false;
        D.contentViolence = false;
        D.contentAdult = false;
        D.contentSex = false;
        const oldTags = avatarDialog.value.ref.tags;
        oldTags.forEach((tag) => {
            switch (tag) {
                case 'content_horror':
                    D.contentHorror = true;
                    break;
                case 'content_gore':
                    D.contentGore = true;
                    break;
                case 'content_violence':
                    D.contentViolence = true;
                    break;
                case 'content_adult':
                    D.contentAdult = true;
                    break;
                case 'content_sex':
                    D.contentSex = true;
                    break;
                default:
                    if (tag.startsWith('content_')) {
                        D.selectedTags.push(tag.substring(8));
                    }
                    break;
            }
        });
        for (const ref of cachedAvatars.value.values()) {
            if (ref.authorId === currentUser.value.id) {
                ref.$selected = false;
                ref.$tagString = '';
                if (avatarId === ref.id) {
                    ref.$selected = true;
                    const conentTags = [];
                    ref.tags.forEach((tag) => {
                        if (tag.startsWith('content_')) {
                            conentTags.push(tag.substring(8));
                        }
                    });
                    for (let i = 0; i < conentTags.length; ++i) {
                        const tag = conentTags[i];
                        if (i < conentTags.length - 1) {
                            ref.$tagString += `${tag}, `;
                        } else {
                            ref.$tagString += tag;
                        }
                    }
                }
                D.ownAvatars.push(ref);
            }
        }
        nextTick(() => {
            D.loading = false;
        });
    }

    function showSetAvatarStylesDialog() {
        const D = setAvatarStylesDialog;
        D.visible = true;
        D.loading = true;
        D.avatarId = avatarDialog.value.id;
        D.primaryStyle = avatarDialog.value.ref.styles?.primary || '';
        D.secondaryStyle = avatarDialog.value.ref.styles?.secondary || '';
        D.initialPrimaryStyle = D.primaryStyle;
        D.initialSecondaryStyle = D.secondaryStyle;
        D.initialTags = avatarDialog.value.ref.tags;
        D.authorTags = '';
        for (const tag of D.initialTags) {
            if (tag.startsWith('author_tag_')) {
                if (D.authorTags) {
                    D.authorTags += ',';
                }
                D.authorTags += tag.substring(11);
            }
        }
        nextTick(() => {
            D.loading = false;
        });
    }

    function displayAvatarGalleryUpload() {
        document.getElementById('AvatarGalleryUploadButton').click();
    }

    function onFileChangeAvatarGallery(e) {
        const clearFile = function () {
            const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#AvatarGalleryUploadButton'));
            if (fileInput) {
                fileInput.value = '';
            }
        };
        const files = e.target.files || e.dataTransfer.files;
        if (!files.length) {
            return;
        }
        if (files[0].size >= 100000000) {
            // 100MB
            $message({
                message: t('message.file.too_large'),
                type: 'error'
            });
            clearFile();
            return;
        }
        if (!files[0].type.match(/image.*/)) {
            $message({
                message: t('message.file.not_image'),
                type: 'error'
            });
            clearFile();
            return;
        }
        const r = new FileReader();
        r.onload = function () {
            avatarDialog.value.galleryLoading = true;
            const base64Body = btoa(r.result.toString());
            avatarRequest
                .uploadAvatarGalleryImage(base64Body, avatarDialog.value.id)
                .then(async (args) => {
                    $message({
                        message: t('message.avatar_gallery.uploaded'),
                        type: 'success'
                    });
                    console.log(args);
                    avatarDialog.value.galleryImages = await getAvatarGallery(avatarDialog.value.id);
                    return args;
                })
                .finally(() => {
                    avatarDialog.value.galleryLoading = false;
                });
        };
        r.readAsBinaryString(files[0]);
        clearFile();
    }

    function reorderAvatarGalleryImage(imageUrl, direction) {
        const fileId = extractFileId(imageUrl);
        let fileIds = [];
        avatarDialog.value.ref.gallery.forEach((item) => {
            fileIds.push(extractFileId(item.id));
        });
        const index = fileIds.indexOf(fileId);
        if (index === -1) {
            $message({
                message: t('message.avatar_gallery.not_found'),
                type: 'error'
            });
            return;
        }
        if (direction === -1 && index === 0) {
            $message({
                message: t('message.avatar_gallery.already_first'),
                type: 'warning'
            });
            return;
        }
        if (direction === 1 && index === fileIds.length - 1) {
            $message({
                message: t('message.avatar_gallery.already_last'),
                type: 'warning'
            });
            return;
        }
        if (direction === -1) {
            moveArrayItem(fileIds, index, index - 1);
        } else {
            moveArrayItem(fileIds, index, index + 1);
        }
        avatarRequest.setAvatarGalleryOrder(fileIds).then(async (args) => {
            $message({
                message: t('message.avatar_gallery.reordered'),
                type: 'success'
            });
            avatarDialog.value.galleryImages = await getAvatarGallery(avatarDialog.value.id);
            return args;
        });
    }

    function deleteAvatarGalleryImage(imageUrl) {
        const fileId = extractFileId(imageUrl);
        miscRequest.deleteFile(fileId).then((args) => {
            $message({
                message: t('message.avatar_gallery.deleted'),
                type: 'success'
            });
            getAvatarGallery(avatarDialog.value.id);
            return args;
        });
    }
</script>
