<template>
    <div class="w-223">
        <DialogHeader class="sr-only">
            <DialogTitle>{{ worldDialog.ref?.name || t('dialog.world.info.header') }}</DialogTitle>
            <DialogDescription>
                {{ worldDialog.ref?.description || worldDialog.ref?.name || t('dialog.world.info.header') }}
            </DialogDescription>
        </DialogHeader>
        <div>
            <div style="display: flex">
                <div style="flex: none; width: 160px; height: 120px">
                    <img
                        v-if="!worldDialog.loading"
                        :src="worldDialog.ref.thumbnailImageUrl"
                        class="cursor-pointer"
                        style="width: 160px; height: 120px; border-radius: 12px"
                        @click="showFullscreenImageDialog(worldDialog.ref.imageUrl)"
                        loading="lazy" />
                </div>
                <div style="flex: 1; display: flex; align-items: flex-start; margin-left: 15px">
                    <div style="flex: 1">
                        <div>
                            <span class="font-bold" style="margin-right: 5px; cursor: pointer" @click="copyWorldName">
                                <Home
                                    v-if="
                                        currentUser.$homeLocation &&
                                        currentUser.$homeLocation.worldId === worldDialog.id
                                    "
                                    class="inline-block" />
                                {{ worldDialog.ref.name }}
                            </span>
                        </div>
                        <div style="margin-top: 5px">
                            <span
                                class="cursor-pointer x-grey"
                                style="font-family: monospace"
                                @click="showUserDialog(worldDialog.ref.authorId)"
                                v-text="worldDialog.ref.authorName" />
                        </div>
                        <div>
                            <Badge
                                v-if="worldDialog.ref.$isLabs"
                                variant="outline"
                                style="margin-right: 5px; margin-top: 5px">
                                {{ t('dialog.world.tags.labs') }}
                            </Badge>
                            <Badge
                                v-else-if="worldDialog.ref.releaseStatus === 'public'"
                                variant="outline"
                                style="margin-right: 5px; margin-top: 5px">
                                {{ t('dialog.world.tags.public') }}
                            </Badge>
                            <Badge v-else variant="outline" style="margin-right: 5px; margin-top: 5px">
                                {{ t('dialog.world.tags.private') }}
                            </Badge>
                            <TooltipWrapper v-if="worldDialog.isPC" side="top" content="PC">
                                <Badge
                                    class="x-tag-platform-pc"
                                    variant="outline"
                                    style="margin-right: 5px; margin-top: 5px">
                                    <Monitor class="h-4 w-4 x-tag-platform-pc" />
                                    <span
                                        v-if="worldDialog.fileAnalysis.standalonewindows?._fileSize"
                                        :class="['x-grey', 'x-tag-platform-pc', 'x-tag-border-left']">
                                        {{ worldDialog.fileAnalysis.standalonewindows._fileSize }}
                                    </span>
                                </Badge>
                            </TooltipWrapper>

                            <TooltipWrapper v-if="worldDialog.isQuest" side="top" content="Quest">
                                <Badge
                                    class="x-tag-platform-quest"
                                    variant="outline"
                                    style="margin-right: 5px; margin-top: 5px">
                                    <Smartphone class="h-4 w-4 x-tag-platform-quest" />
                                    <span
                                        v-if="worldDialog.fileAnalysis.android?._fileSize"
                                        :class="['x-grey', 'x-tag-platform-quest', 'x-tag-border-left']">
                                        {{ worldDialog.fileAnalysis.android._fileSize }}
                                    </span>
                                </Badge>
                            </TooltipWrapper>

                            <TooltipWrapper v-if="worldDialog.isIos" side="top" content="iOS">
                                <Badge
                                    class="text-platform-ios border-platform-ios"
                                    variant="outline"
                                    style="margin-right: 5px; margin-top: 5px">
                                    <Apple class="h-4 w-4 text-platform-ios" />
                                    <span
                                        v-if="worldDialog.fileAnalysis.ios?._fileSize"
                                        :class="[
                                            'x-grey',
                                            'x-tag-border-left',
                                            'text-platform-ios',
                                            'border-platform-ios'
                                        ]">
                                        {{ worldDialog.fileAnalysis.ios._fileSize }}
                                    </span>
                                </Badge>
                            </TooltipWrapper>

                            <Badge
                                v-if="worldDialog.avatarScalingDisabled"
                                variant="outline"
                                style="margin-right: 5px; margin-top: 5px">
                                {{ t('dialog.world.tags.avatar_scaling_disabled') }}
                            </Badge>
                            <Badge
                                v-if="worldDialog.focusViewDisabled"
                                variant="outline"
                                style="margin-right: 5px; margin-top: 5px">
                                {{ t('dialog.world.tags.focus_view_disabled') }}
                            </Badge>
                            <Badge
                                v-if="worldDialog.ref.unityPackageUrl"
                                variant="outline"
                                style="margin-right: 5px; margin-top: 5px">
                                {{ t('dialog.world.tags.future_proofing') }}
                            </Badge>
                            <Badge
                                v-if="worldDialog.inCache"
                                variant="outline"
                                class="cursor-pointer"
                                style="margin-right: 5px; margin-top: 5px"
                                @click="openFolderGeneric(worldDialog.cachePath)">
                                <span v-text="worldDialog.cacheSize" />
                                | {{ t('dialog.world.tags.cache') }}
                            </Badge>
                        </div>
                        <div>
                            <template v-for="tag in worldDialog.ref.tags" :key="tag">
                                <Badge
                                    v-if="tag.startsWith('content_')"
                                    variant="outline"
                                    style="margin-right: 5px; margin-top: 5px">
                                    <span v-if="tag === 'content_horror'">
                                        {{ t('dialog.world.tags.content_horror') }}
                                    </span>
                                    <span v-else-if="tag === 'content_gore'">
                                        {{ t('dialog.world.tags.content_gore') }}
                                    </span>
                                    <span v-else-if="tag === 'content_violence'">
                                        {{ t('dialog.world.tags.content_violence') }}
                                    </span>
                                    <span v-else-if="tag === 'content_adult'">
                                        {{ t('dialog.world.tags.content_adult') }}
                                    </span>
                                    <span v-else-if="tag === 'content_sex'">
                                        {{ t('dialog.world.tags.content_sex') }}
                                    </span>
                                    <span v-else>
                                        {{ tag.replace('content_', '') }}
                                    </span>
                                </Badge>
                            </template>
                        </div>
                        <div style="margin-top: 5px; display: flex; align-items: center">
                            <span
                                v-show="worldDialog.ref.name !== worldDialog.ref.description"
                                style="font-size: 12px; flex: 1; margin-right: 0.5em"
                                >{{ translatedDescription || worldDialog.ref.description }}</span
                            >
                            <Button
                                v-if="
                                    translationApi &&
                                    worldDialog.ref.description &&
                                    worldDialog.ref.name !== worldDialog.ref.description
                                "
                                class="w-3 h-6 text-xs"
                                size="icon-sm"
                                variant="ghost"
                                @click="translateDescription">
                                <Spinner v-if="isTranslating" class="size-1" />
                                <Languages v-else class="h-3 w-3" />
                            </Button>
                        </div>
                    </div>
                    <div class="ml-2 mt-12">
                        <TooltipWrapper
                            v-if="worldDialog.inCache"
                            side="top"
                            :content="t('dialog.world.actions.delete_cache_tooltip')">
                            <Button
                                class="rounded-full mr-2"
                                size="icon-lg"
                                variant="outline"
                                :disabled="isGameRunning && worldDialog.cacheLocked"
                                @click="deleteVRChatCache(worldDialog.ref)"
                                ><Trash2
                            /></Button>
                        </TooltipWrapper>
                        <TooltipWrapper
                            v-if="worldDialog.isFavorite"
                            side="top"
                            :content="t('dialog.world.actions.favorites_tooltip')">
                            <Button class="rounded-full" size="icon-lg" @click="worldDialogCommand('Add Favorite')"
                                ><Star
                            /></Button>
                        </TooltipWrapper>
                        <TooltipWrapper v-else side="top" :content="t('dialog.world.actions.favorites_tooltip')">
                            <Button
                                class="rounded-full"
                                size="icon-lg"
                                variant="outline"
                                @click="worldDialogCommand('Add Favorite')"
                                ><Star
                            /></Button>
                        </TooltipWrapper>
                        <DropdownMenu>
                            <DropdownMenuTrigger as-child>
                                <Button variant="outline" size="icon-lg" class="rounded-full ml-2">
                                    <Ellipsis />
                                </Button>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent>
                                <DropdownMenuItem @click="worldDialogCommand('Refresh')">
                                    <RefreshCw class="size-4" />
                                    {{ t('dialog.world.actions.refresh') }}
                                </DropdownMenuItem>
                                <DropdownMenuItem @click="worldDialogCommand('Share')">
                                    <Share2 class="size-4" />
                                    {{ t('dialog.world.actions.share') }}
                                </DropdownMenuItem>
                                <DropdownMenuSeparator />
                                <DropdownMenuItem @click="worldDialogCommand('New Instance')">
                                    <Flag class="size-4" />
                                    {{ t('dialog.world.actions.new_instance') }}
                                </DropdownMenuItem>
                                <DropdownMenuItem @click="worldDialogCommand('New Instance and Self Invite')">
                                    <MessageSquare class="size-4" />
                                    {{
                                        canOpenInstanceInGame
                                            ? t('dialog.world.actions.new_instance_and_open_ingame')
                                            : t('dialog.world.actions.new_instance_and_self_invite')
                                    }}
                                </DropdownMenuItem>
                                <DropdownMenuSeparator />
                                <DropdownMenuItem
                                    v-if="
                                        currentUser.$homeLocation &&
                                        currentUser.$homeLocation.worldId === worldDialog.id
                                    "
                                    @click="worldDialogCommand('Reset Home')">
                                    <Wand2 class="size-4" />
                                    {{ t('dialog.world.actions.reset_home') }}
                                </DropdownMenuItem>
                                <DropdownMenuItem v-else @click="worldDialogCommand('Make Home')">
                                    <Home class="size-4" />
                                    {{ t('dialog.world.actions.make_home') }}
                                </DropdownMenuItem>
                                <DropdownMenuItem @click="worldDialogCommand('Previous Instances')">
                                    <LineChart class="size-4" />
                                    {{ t('dialog.world.actions.show_previous_instances') }}
                                </DropdownMenuItem>
                                <template v-if="currentUser.id !== worldDialog.ref.authorId">
                                    <DropdownMenuItem
                                        :disabled="!worldDialog.hasPersistData"
                                        @click="worldDialogCommand('Delete Persistent Data')">
                                        <Upload class="size-4" />
                                        {{ t('dialog.world.actions.delete_persistent_data') }}
                                    </DropdownMenuItem>
                                </template>
                                <template v-else>
                                    <DropdownMenuItem @click="worldDialogCommand('Rename')">
                                        <Pencil class="size-4" />
                                        {{ t('dialog.world.actions.rename') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem @click="worldDialogCommand('Change Description')">
                                        <Pencil class="size-4" />
                                        {{ t('dialog.world.actions.change_description') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem @click="worldDialogCommand('Change Capacity')">
                                        <Pencil class="size-4" />
                                        {{ t('dialog.world.actions.change_capacity') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem @click="worldDialogCommand('Change Recommended Capacity')">
                                        <Pencil class="size-4" />
                                        {{ t('dialog.world.actions.change_recommended_capacity') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem @click="worldDialogCommand('Change YouTube Preview')">
                                        <Pencil class="size-4" />
                                        {{ t('dialog.world.actions.change_preview') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem @click="worldDialogCommand('Change Tags')">
                                        <Pencil class="size-4" />
                                        {{ t('dialog.world.actions.change_warnings_settings_tags') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem @click="worldDialogCommand('Change Allowed Domains')">
                                        <Pencil class="size-4" />
                                        {{ t('dialog.world.actions.change_allowed_video_player_domains') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem v-if="isWindows" @click="worldDialogCommand('Change Image')">
                                        <Image class="size-4" />
                                        {{ t('dialog.world.actions.change_image') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem
                                        v-if="worldDialog.ref.unityPackageUrl"
                                        @click="worldDialogCommand('Download Unity Package')">
                                        <Download class="size-4" />
                                        {{ t('dialog.world.actions.download_package') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuSeparator />
                                    <DropdownMenuItem
                                        v-if="
                                            worldDialog.ref?.tags?.includes('system_approved') ||
                                            worldDialog.ref?.tags?.includes('system_labs')
                                        "
                                        @click="worldDialogCommand('Unpublish')">
                                        <Eye class="size-4" />
                                        {{ t('dialog.world.actions.unpublish') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem v-else @click="worldDialogCommand('Publish')">
                                        <Eye class="size-4" />
                                        {{ t('dialog.world.actions.publish_to_labs') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem
                                        :disabled="!worldDialog.hasPersistData"
                                        @click="worldDialogCommand('Delete Persistent Data')">
                                        <Upload class="size-4" />
                                        {{ t('dialog.world.actions.delete_persistent_data') }}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem variant="destructive" @click="worldDialogCommand('Delete')">
                                        <Trash2 class="size-4" />
                                        {{ t('dialog.world.actions.delete') }}
                                    </DropdownMenuItem>
                                </template>
                            </DropdownMenuContent>
                        </DropdownMenu>
                    </div>
                </div>
            </div>
            <TabsUnderline
                v-model="worldDialog.activeTab"
                :items="worldDialogTabs"
                :unmount-on-hide="false"
                @update:modelValue="worldDialogTabClick">
                <template #Instances>
                    <div class="flex items-center text-sm">
                        <User />
                        {{ t('dialog.world.instances.public_count', { count: worldDialog.ref.publicOccupants }) }}
                        <User style="margin-left: 10px" />
                        {{
                            t('dialog.world.instances.private_count', {
                                count: worldDialog.ref.privateOccupants
                            })
                        }}
                        <Check style="margin-left: 10px" />
                        {{
                            t('dialog.world.instances.capacity_count', {
                                count: worldDialog.ref.recommendedCapacity,
                                max: worldDialog.ref.capacity
                            })
                        }}
                    </div>
                    <div v-for="room in worldDialog.rooms" :key="room.id">
                        <template
                            v-if="isAgeGatedInstancesVisible || !(room.ageGate || room.location?.includes('~ageGate'))">
                            <div style="margin: 5px 0">
                                <div class="flex items-center">
                                    <LocationWorld
                                        class="text-sm"
                                        :locationobject="room.$location"
                                        :currentuserid="currentUser.id"
                                        :worlddialogshortname="worldDialog.$location.shortName" />
                                    <InstanceActionBar
                                        class="ml-1 text-sm"
                                        :location="room.$location.tag"
                                        :launch-location="room.tag"
                                        :instance-location="room.tag"
                                        :shortname="room.$location.shortName"
                                        :currentlocation="lastLocation.location"
                                        :instance="room.ref"
                                        :friendcount="room.friendCount"
                                        :refresh-tooltip="t('dialog.world.instances.refresh_instance_info')"
                                        :show-history="!!instanceJoinHistory.get(room.$location.tag)"
                                        :history-tooltip="t('dialog.previous_instances.info')"
                                        :on-refresh="() => refreshInstancePlayerCount(room.tag)"
                                        :on-history="() => showPreviousInstancesInfoDialog(room.location)" />
                                </div>
                                <div
                                    v-if="room.$location.userId || room.users.length"
                                    class="flex flex-wrap items-start"
                                    style="margin: 10px 0; max-height: unset">
                                    <div
                                        v-if="room.$location.userId"
                                        class="box-border flex items-center p-1.5 text-[13px] cursor-pointer w-[167px] hover:rounded-[25px_5px_5px_25px]"
                                        @click="showUserDialog(room.$location.userId)">
                                        <template v-if="room.$location.user">
                                            <div
                                                class="relative inline-block flex-none size-9 mr-2.5"
                                                :class="userStatusClass(room.$location.user)">
                                                <img
                                                    class="size-full rounded-full object-cover"
                                                    :src="userImage(room.$location.user, true)"
                                                    loading="lazy" />
                                            </div>
                                            <div class="flex-1 overflow-hidden">
                                                <span
                                                    class="block truncate font-medium leading-[18px]"
                                                    :style="{ color: room.$location.user.$userColour }"
                                                    v-text="room.$location.user.displayName" />
                                                <span class="block truncate text-xs">
                                                    {{ t('dialog.world.instances.instance_creator') }}
                                                </span>
                                            </div>
                                        </template>
                                        <span v-else v-text="room.$location.userId" />
                                    </div>
                                    <div
                                        v-for="user in room.users"
                                        :key="user.id"
                                        class="box-border flex items-center p-1.5 text-[13px] cursor-pointer w-[167px] hover:rounded-[25px_5px_5px_25px]"
                                        @click="showUserDialog(user.id)">
                                        <div
                                            class="relative inline-block flex-none size-9 mr-2.5"
                                            :class="userStatusClass(user)">
                                            <img
                                                class="size-full rounded-full object-cover"
                                                :src="userImage(user, true)"
                                                loading="lazy" />
                                        </div>
                                        <div class="flex-1 overflow-hidden">
                                            <span
                                                class="block truncate font-medium leading-[18px]"
                                                :style="{ color: user.$userColour }"
                                                v-text="user.displayName" />
                                            <span v-if="user.location === 'traveling'" class="block truncate text-xs">
                                                <Spinner class="inline-block mr-1" />
                                                <Timer :epoch="user.$travelingToTime" />
                                            </span>
                                            <span v-else class="block truncate text-xs">
                                                <Timer :epoch="user.$location_at" />
                                            </span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </template>
                    </div>
                </template>
                <template #Info>
                    <div class="flex flex-wrap items-start px-2.5" style="max-height: none">
                        <div class="box-border flex items-center p-1.5 text-[13px] w-full cursor-default">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.memo') }}
                                </span>
                                <InputGroupTextareaField
                                    v-model="memo"
                                    class="text-xs"
                                    :rows="2"
                                    :placeholder="t('dialog.world.info.memo_placeholder')"
                                    input-class="resize-none min-h-0"
                                    @change="onWorldMemoChange" />
                            </div>
                        </div>
                        <div style="width: 100%; display: flex">
                            <div class="box-border flex items-center p-1.5 text-[13px] w-full cursor-default">
                                <div class="flex-1 overflow-hidden">
                                    <span class="block truncate font-medium leading-[18px]">
                                        {{ t('dialog.world.info.id') }}
                                    </span>
                                    <span class="block truncate text-xs" style="display: inline">
                                        {{ worldDialog.id }}
                                    </span>
                                    <TooltipWrapper side="top" :content="t('dialog.world.info.id_tooltip')">
                                        <DropdownMenu>
                                            <DropdownMenuTrigger as-child>
                                                <Button
                                                    class="rounded-full text-xs"
                                                    size="icon-sm"
                                                    variant="ghost"
                                                    @click.stop
                                                    ><Copy class="h-4 w-4" />
                                                </Button>
                                            </DropdownMenuTrigger>
                                            <DropdownMenuContent>
                                                <DropdownMenuItem @click="copyWorldId()">
                                                    {{ t('dialog.world.info.copy_id') }}
                                                </DropdownMenuItem>
                                                <DropdownMenuItem @click="copyWorldUrl()">
                                                    {{ t('dialog.world.info.copy_url') }}
                                                </DropdownMenuItem>
                                                <DropdownMenuItem @click="copyWorldName()">
                                                    {{ t('dialog.world.info.copy_name') }}
                                                </DropdownMenuItem>
                                            </DropdownMenuContent>
                                        </DropdownMenu>
                                    </TooltipWrapper>
                                </div>
                            </div>
                        </div>
                        <div
                            v-if="worldDialog.ref.previewYoutubeId"
                            class="box-border flex items-center p-1.5 text-[13px] cursor-pointer"
                            style="width: 350px"
                            @click="
                                openExternalLink(`https://www.youtube.com/watch?v=${worldDialog.ref.previewYoutubeId}`)
                            ">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.youtube_preview') }}
                                </span>
                                <span class="block truncate text-xs">
                                    https://www.youtube.com/watch?v={{ worldDialog.ref.previewYoutubeId }}
                                </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] w-full cursor-default">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.author_tags') }}
                                </span>
                                <span
                                    v-if="
                                        worldDialog.ref.tags?.filter((tag) => tag.startsWith('author_tag')).length > 0
                                    "
                                    class="block truncate text-xs">
                                    {{ worldTags }}
                                </span>
                                <span v-else class="block truncate text-xs"> - </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.players') }}
                                </span>
                                <span class="block truncate text-xs">
                                    {{ commaNumber(worldDialog.ref.occupants) }}
                                </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.favorites') }}
                                </span>
                                <span class="block truncate text-xs">
                                    {{ commaNumber(worldDialog.ref.favorites)
                                    }}<span
                                        v-if="worldDialog.ref?.favorites > 0 && worldDialog.ref?.visits > 0"
                                        class="text-xs">
                                        ({{ favoriteRate }}%)
                                    </span>
                                </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.visits') }}
                                </span>
                                <span class="block truncate text-xs">
                                    {{ commaNumber(worldDialog.ref.visits) }}
                                </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.capacity') }}
                                </span>
                                <span class="block truncate text-xs">
                                    {{ commaNumber(worldDialog.ref.recommendedCapacity) }} ({{
                                        commaNumber(worldDialog.ref.capacity)
                                    }})
                                </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.created_at') }}
                                </span>
                                <span class="block truncate text-xs">
                                    {{ formatDateFilter(worldDialog.ref.created_at, 'long') }}
                                </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]" style="display: inline">
                                    {{ t('dialog.world.info.last_updated') }}
                                </span>
                                <TooltipWrapper
                                    v-if="Object.keys(worldDialog.fileAnalysis).length"
                                    side="top"
                                    style="margin-left: 5px">
                                    <template #content>
                                        <template
                                            v-for="(created_at, platform) in worldDialogPlatformCreatedAt"
                                            :key="platform">
                                            <div class="flex justify-between w-full">
                                                <span class="mr-1">{{ platform }}:</span>
                                                <span>{{ formatDateFilter(created_at, 'long') }}</span>
                                            </div>
                                        </template>
                                    </template>
                                    <ChevronDown class="inline-block" />
                                </TooltipWrapper>
                                <span class="block truncate text-xs">
                                    {{ formatDateFilter(worldDialog.ref.updated_at, 'long') }}
                                </span>
                            </div>
                        </div>
                        <div
                            v-if="worldDialog.ref.labsPublicationDate !== 'none'"
                            class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.labs_publication_date') }}
                                </span>
                                <span class="block truncate text-xs">
                                    {{ formatDateFilter(worldDialog.ref.labsPublicationDate, 'long') }}
                                </span>
                            </div>
                        </div>
                        <div
                            v-if="worldDialog.ref.publicationDate !== 'none'"
                            class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]" style="display: inline">
                                    {{ t('dialog.world.info.publication_date') }}
                                </span>
                                <TooltipWrapper v-if="isTimeInLabVisible" side="top" style="margin-left: 5px">
                                    <template #content>
                                        <span>
                                            {{ t('dialog.world.info.time_in_labs') }}
                                            {{ timeInLab }}
                                        </span>
                                    </template>
                                    <ChevronDown class="inline-block" />
                                </TooltipWrapper>
                                <span class="block truncate text-xs">
                                    {{ formatDateFilter(worldDialog.ref.publicationDate, 'long') }}
                                </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.version') }}
                                </span>
                                <span class="block truncate text-xs" v-text="worldDialog.ref.version" />
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.heat') }}
                                </span>
                                <span class="block truncate text-xs">
                                    {{ commaNumber(worldDialog.ref.heat) }} {{ '🔥'.repeat(worldDialog.ref.heat) }}
                                </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.popularity') }}
                                </span>
                                <span class="block truncate text-xs">
                                    {{ commaNumber(worldDialog.ref.popularity) }}
                                    {{ '💖'.repeat(worldDialog.ref.popularity) }}
                                </span>
                            </div>
                        </div>
                        <div class="box-border flex items-center p-1.5 text-[13px] w-full cursor-default">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.platform') }}
                                </span>
                                <span class="block truncate text-xs" style="white-space: normal">{{
                                    worldDialogPlatform
                                }}</span>
                            </div>
                        </div>

                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.last_visited') }}
                                </span>
                                <span class="block truncate text-xs">{{
                                    formatDateFilter(worldDialog.lastVisit, 'long')
                                }}</span>
                            </div>
                        </div>

                        <div
                            class="box-border flex items-center p-1.5 text-[13px] cursor-pointer w-[167px]"
                            @click="showPreviousInstancesListDialog(worldDialog.ref)">
                            <div class="flex-1 overflow-hidden">
                                <div
                                    class="block truncate font-medium leading-[18px]"
                                    style="display: flex; justify-content: space-between; align-items: center">
                                    <div>
                                        {{ t('dialog.world.info.visit_count') }}
                                    </div>

                                    <TooltipWrapper side="top" :content="t('dialog.user.info.open_previous_instance')">
                                        <MoreHorizontal style="margin-right: 16px" />
                                    </TooltipWrapper>
                                </div>
                                <span v-if="worldDialog.visitCount === 0" class="block truncate text-xs">-</span>
                                <span v-else class="block truncate text-xs" v-text="worldDialog.visitCount"></span>
                            </div>
                        </div>

                        <div class="box-border flex items-center p-1.5 text-[13px] cursor-default w-[167px]">
                            <div class="flex-1 overflow-hidden">
                                <span class="block truncate font-medium leading-[18px]">
                                    {{ t('dialog.world.info.time_spent') }}
                                </span>
                                <span class="block truncate text-xs">
                                    {{ worldDialog.timeSpent === 0 ? ' - ' : timeSpent }}
                                </span>
                            </div>
                        </div>
                    </div>
                </template>
                <template #JSON>
                    <Button
                        class="rounded-full mr-2"
                        size="icon-sm"
                        variant="ghost"
                        @click="refreshWorldDialogTreeData()">
                        <RefreshCw />
                    </Button>
                    <Button
                        class="rounded-full"
                        size="icon-sm"
                        variant="ghost"
                        @click="downloadAndSaveJson(worldDialog.id, worldDialog.ref)">
                        <Download />
                    </Button>
                    <vue-json-pretty
                        :key="treeData?.id"
                        :data="treeData"
                        :deep="2"
                        :theme="isDarkMode ? 'dark' : 'light'"
                        show-icon />
                    <br />
                    <vue-json-pretty
                        v-if="Object.keys(worldDialog.fileAnalysis).length"
                        :data="worldDialog.fileAnalysis"
                        :deep="2"
                        :theme="isDarkMode ? 'dark' : 'light'"
                        show-icon />
                </template>
            </TabsUnderline>
        </div>

        <template v-if="isDialogVisible">
            <WorldAllowedDomainsDialog :world-allowed-domains-dialog="worldAllowedDomainsDialog" />
            <SetWorldTagsDialog
                v-model:is-set-world-tags-dialog-visible="isSetWorldTagsDialogVisible"
                :old-tags="worldDialog.ref?.tags"
                :world-id="worldDialog.id"
                :is-world-dialog-visible="worldDialog.visible" />
            <NewInstanceDialog
                :new-instance-dialog-location-tag="newInstanceDialogLocationTag"
                :last-location="lastLocation" />
            <input
                id="WorldImageUploadButton"
                type="file"
                accept="image/*"
                style="display: none"
                @change="onFileChangeWorldImage" />
            <ImageCropDialog
                :open="cropDialogOpen"
                :title="t('dialog.change_content_image.world')"
                :aspect-ratio="4 / 3"
                :file="cropDialogFile"
                @update:open="cropDialogOpen = $event"
                @confirm="onCropConfirmWorld" />
        </template>
    </div>
</template>

<script setup>
    import {
        Apple,
        Check,
        ChevronDown,
        Copy,
        Download,
        Ellipsis,
        Eye,
        Flag,
        Home,
        Image,
        Languages,
        LineChart,
        MessageSquare,
        Monitor,
        MoreHorizontal,
        Pencil,
        RefreshCw,
        Share2,
        Smartphone,
        Star,
        Trash2,
        Upload,
        User,
        Wand2
    } from 'lucide-vue-next';
    import { computed, defineAsyncComponent, nextTick, ref, watch } from 'vue';
    import { DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
    import { Button } from '@/components/ui/button';
    import { InputGroupTextareaField } from '@/components/ui/input-group';
    import { Spinner } from '@/components/ui/spinner';
    import { TabsUnderline } from '@/components/ui/tabs';
    import { storeToRefs } from 'pinia';
    import { toast } from 'vue-sonner';
    import { useI18n } from 'vue-i18n';

    import VueJsonPretty from 'vue-json-pretty';

    import {
        commaNumber,
        compareUnityVersion,
        deleteVRChatCache,
        downloadAndSaveJson,
        formatDateFilter,
        openExternalLink,
        openFolderGeneric,
        refreshInstancePlayerCount,
        replaceVrcPackageUrl,
        timeToText,
        userImage,
        userStatusClass
    } from '../../../shared/utils';
    import {
        useAdvancedSettingsStore,
        useAppearanceSettingsStore,
        useFavoriteStore,
        useGalleryStore,
        useGameStore,
        useInstanceStore,
        useInviteStore,
        useLocationStore,
        useModalStore,
        useUserStore,
        useWorldStore
    } from '../../../stores';
    import {
        DropdownMenu,
        DropdownMenuContent,
        DropdownMenuItem,
        DropdownMenuSeparator,
        DropdownMenuTrigger
    } from '../../ui/dropdown-menu';
    import {
        handleImageUploadInput,
        readFileAsBase64,
        resizeImageToFitLimits,
        uploadImageLegacy,
        withUploadTimeout
    } from '../../../shared/utils/imageUpload';
    import { favoriteRequest, miscRequest, userRequest, worldRequest } from '../../../api';
    import { Badge } from '../../ui/badge';
    import { database } from '../../../service/database';
    import { formatJsonVars } from '../../../shared/utils/base/ui';

    import ImageCropDialog from '../ImageCropDialog.vue';
    import InstanceActionBar from '../../InstanceActionBar.vue';

    const SetWorldTagsDialog = defineAsyncComponent(() => import('./SetWorldTagsDialog.vue'));
    const WorldAllowedDomainsDialog = defineAsyncComponent(() => import('./WorldAllowedDomainsDialog.vue'));
    const NewInstanceDialog = defineAsyncComponent(() => import('../NewInstanceDialog.vue'));

    const { isAgeGatedInstancesVisible, isDarkMode } = storeToRefs(useAppearanceSettingsStore());
    const { showUserDialog } = useUserStore();
    const { currentUser, userDialog } = storeToRefs(useUserStore());
    const { worldDialog } = storeToRefs(useWorldStore());
    const { cachedWorlds, showWorldDialog } = useWorldStore();
    const { lastLocation } = storeToRefs(useLocationStore());
    const { newInstanceSelfInvite, canOpenInstanceInGame } = useInviteStore();
    const { showFavoriteDialog } = useFavoriteStore();
    const { showPreviousInstancesInfoDialog, showPreviousInstancesListDialog: openPreviousInstancesListDialog } =
        useInstanceStore();
    const { instanceJoinHistory } = storeToRefs(useInstanceStore());
    const { isGameRunning } = storeToRefs(useGameStore());
    const { showFullscreenImageDialog } = useGalleryStore();
    const { translationApi } = storeToRefs(useAdvancedSettingsStore());
    const modalStore = useModalStore();

    const { t } = useI18n();
    const worldDialogTabs = computed(() => [
        { value: 'Instances', label: t('dialog.world.instances.header') },
        { value: 'Info', label: t('dialog.world.info.header') },
        { value: 'JSON', label: t('dialog.world.json.header') }
    ]);

    const treeData = ref({});
    const worldAllowedDomainsDialog = ref({
        visible: false,
        worldId: '',
        urlList: []
    });
    const isSetWorldTagsDialogVisible = ref(false);
    const newInstanceDialogLocationTag = ref('');
    const cropDialogOpen = ref(false);
    const cropDialogFile = ref(null);
    const changeWorldImageLoading = ref(false);
    const translatedDescription = ref('');
    const isTranslating = ref(false);

    const isDialogVisible = computed({
        get() {
            return worldDialog.value.visible;
        },
        set(value) {
            worldDialog.value.visible = value;
        }
    });

    const isWindows = computed(() => WINDOWS);

    const memo = computed({
        get() {
            return worldDialog.value.memo;
        },
        set(value) {
            worldDialog.value.memo = value;
        }
    });

    const isTimeInLabVisible = computed(() => {
        return (
            worldDialog.value.ref.publicationDate &&
            worldDialog.value.ref.publicationDate !== 'none' &&
            worldDialog.value.ref.labsPublicationDate &&
            worldDialog.value.ref.labsPublicationDate !== 'none'
        );
    });

    const timeInLab = computed(() => {
        return timeToText(
            new Date(worldDialog.value.ref.publicationDate).getTime() -
                new Date(worldDialog.value.ref.labsPublicationDate).getTime()
        );
    });

    const favoriteRate = computed(() => {
        return (
            Math.round(
                (((worldDialog.value.ref?.favorites - worldDialog.value.ref?.visits) / worldDialog.value.ref?.visits) *
                    100 +
                    100) *
                    100
            ) / 100
        );
    });

    const worldTags = computed(() => {
        return worldDialog.value.ref?.tags
            .filter((tag) => tag.startsWith('author_tag'))
            .map((tag) => tag.replace('author_tag_', ''))
            .join(', ');
    });

    const timeSpent = computed(() => {
        return timeToText(worldDialog.value.timeSpent);
    });

    const worldDialogPlatform = computed(() => {
        const { ref } = worldDialog.value;
        const platforms = [];
        if (ref.unityPackages) {
            for (const unityPackage of ref.unityPackages) {
                if (!compareUnityVersion(unityPackage.unitySortNumber)) {
                    continue;
                }
                let platform = 'PC';
                if (unityPackage.platform === 'standalonewindows') {
                    platform = 'PC';
                } else if (unityPackage.platform === 'android') {
                    platform = 'Android';
                } else if (unityPackage.platform) {
                    platform = unityPackage.platform;
                }
                platforms.unshift(`${platform}/${unityPackage.unityVersion}`);
            }
        }
        return platforms.join(', ');
    });

    const worldDialogPlatformCreatedAt = computed(() => {
        const { ref } = worldDialog.value;
        if (!ref.unityPackages) {
            return null;
        }
        let newest = {};
        for (const unityPackage of ref.unityPackages) {
            if (unityPackage.variant && unityPackage.variant !== 'standard' && unityPackage.variant !== 'security') {
                continue;
            }
            const platform = unityPackage.platform;
            const createdAt = unityPackage.created_at;
            if (!newest[platform] || new Date(createdAt) > new Date(newest[platform])) {
                newest[platform] = createdAt;
            }
        }
        return newest;
    });

    watch(
        () => worldDialog.value.loading,
        () => {
            if (worldDialog.value.visible) {
                handleDialogOpen();
                !worldDialog.value.loading && loadLastActiveTab();
            }
        }
    );

    /**
     *
     * @param tabName
     */
    function handleWorldDialogTab(tabName) {
        worldDialog.value.lastActiveTab = tabName;
        if (tabName === 'JSON') {
            refreshWorldDialogTreeData();
        }
    }

    /**
     *
     */
    function loadLastActiveTab() {
        handleWorldDialogTab(worldDialog.value.lastActiveTab);
    }

    /**
     *
     * @param tabName
     */
    function worldDialogTabClick(tabName) {
        if (tabName === worldDialog.value.lastActiveTab) {
            if (tabName === 'JSON') {
                refreshWorldDialogTreeData();
            }
            return;
        }
        handleWorldDialogTab(tabName);
    }

    /**
     *
     */
    function handleDialogOpen() {
        treeData.value = {};
    }

    /**
     *
     */
    function showChangeWorldImageDialog() {
        document.getElementById('WorldImageUploadButton').click();
    }

    /**
     *
     * @param e
     */
    function onFileChangeWorldImage(e) {
        const { file, clearInput } = handleImageUploadInput(e, {
            inputSelector: '#WorldImageUploadButton',
            tooLargeMessage: () => t('message.file.too_large'),
            invalidTypeMessage: () => t('message.file.not_image')
        });
        if (!file) {
            return;
        }
        if (!worldDialog.value.visible || worldDialog.value.loading) {
            clearInput();
            return;
        }
        clearInput();
        cropDialogFile.value = file;
        cropDialogOpen.value = true;
    }

    /**
     *
     * @param blob
     */
    async function onCropConfirmWorld(blob) {
        changeWorldImageLoading.value = true;
        try {
            await withUploadTimeout(
                (async () => {
                    const base64Body = await readFileAsBase64(blob);
                    const base64File = await resizeImageToFitLimits(base64Body);
                    await uploadImageLegacy('world', {
                        entityId: worldDialog.value.id,
                        imageUrl: worldDialog.value.ref.imageUrl,
                        base64File,
                        blob
                    });
                })()
            );
            toast.success(t('message.upload.success'));
        } catch (error) {
            console.error('World image upload process failed:', error);
            toast.error(t('message.upload.error'));
        } finally {
            changeWorldImageLoading.value = false;
            cropDialogOpen.value = false;
        }
    }

    /**
     *
     * @param tag
     */
    function showNewInstanceDialog(tag) {
        // trigger watcher
        newInstanceDialogLocationTag.value = '';
        nextTick(() => (newInstanceDialogLocationTag.value = tag));
    }

    /**
     *
     * @param command
     */
    function worldDialogCommand(command) {
        const D = worldDialog.value;
        if (D.visible === false) {
            return;
        }
        switch (command) {
            case 'Delete Favorite':
            case 'Make Home':
            case 'Reset Home':
            case 'Publish':
            case 'Unpublish':
            case 'Delete Persistent Data':
            case 'Delete':
                const commandLabelMap = {
                    'Delete Favorite': t('dialog.world.actions.favorites_tooltip'),
                    'Make Home': t('dialog.world.actions.make_home'),
                    'Reset Home': t('dialog.world.actions.reset_home'),
                    Publish: t('dialog.world.actions.publish_to_labs'),
                    Unpublish: t('dialog.world.actions.unpublish'),
                    'Delete Persistent Data': t('dialog.world.actions.delete_persistent_data'),
                    Delete: t('dialog.world.actions.delete')
                };
                modalStore
                    .confirm({
                        description: t('confirm.command_question', {
                            command: commandLabelMap[command] ?? command
                        }),
                        title: t('confirm.title')
                    })
                    .then(({ ok }) => {
                        if (!ok) return;
                        switch (command) {
                            case 'Delete Favorite':
                                favoriteRequest.deleteFavorite({
                                    objectId: D.id
                                });
                                break;
                            case 'Make Home':
                                userRequest
                                    .saveCurrentUser({
                                        homeLocation: D.id
                                    })
                                    .then((args) => {
                                        toast.success(t('message.world.home_updated'));
                                        return args;
                                    });
                                break;
                            case 'Reset Home':
                                userRequest
                                    .saveCurrentUser({
                                        homeLocation: ''
                                    })
                                    .then((args) => {
                                        toast.success(t('message.world.home_reset'));
                                        return args;
                                    });
                                break;
                            case 'Publish':
                                worldRequest
                                    .publishWorld({
                                        worldId: D.id
                                    })
                                    .then((args) => {
                                        toast.success(t('message.world.published'));
                                        return args;
                                    });
                                break;
                            case 'Unpublish':
                                worldRequest
                                    .unpublishWorld({
                                        worldId: D.id
                                    })
                                    .then((args) => {
                                        toast.success(t('message.world.unpublished'));
                                        return args;
                                    });
                                break;
                            case 'Delete Persistent Data':
                                miscRequest
                                    .deleteWorldPersistData({
                                        worldId: D.id
                                    })
                                    .then((args) => {
                                        if (args.params.worldId === worldDialog.value.id && worldDialog.value.visible) {
                                            worldDialog.value.hasPersistData = false;
                                        }
                                        toast.success(t('message.world.persistent_data_deleted'));
                                        return args;
                                    });
                                break;
                            case 'Delete':
                                worldRequest
                                    .deleteWorld({
                                        worldId: D.id
                                    })
                                    .then((args) => {
                                        const { json } = args;
                                        cachedWorlds.delete(json.id);
                                        if (worldDialog.value.ref.authorId === json.authorId) {
                                            const map = new Map();
                                            for (const ref of cachedWorlds.values()) {
                                                if (ref.authorId === json.authorId) {
                                                    map.set(ref.id, ref);
                                                }
                                            }
                                            const array = Array.from(map.values());
                                            userDialog.value.worlds = array;
                                        }
                                        toast.success(t('message.world.deleted'));
                                        D.visible = false;
                                        return args;
                                    });
                                break;
                        }
                    })
                    .catch(() => {});
                break;
            case 'Previous Instances':
                showPreviousInstancesListDialog(D.ref);
                break;
            case 'Share':
                copyWorldUrl();
                break;
            case 'Change Allowed Domains':
                showWorldAllowedDomainsDialog();
                break;
            case 'Change Tags':
                isSetWorldTagsDialogVisible.value = true;
                break;
            case 'Download Unity Package':
                openExternalLink(replaceVrcPackageUrl(worldDialog.value.ref.unityPackageUrl));
                break;
            case 'Change Image':
                showChangeWorldImageDialog();
                break;
            case 'Refresh':
                const { tag, shortName } = worldDialog.value.$location;
                showWorldDialog(tag, shortName, { forceRefresh: true });
                break;
            case 'New Instance':
                showNewInstanceDialog(D.$location.tag);
                break;
            case 'Add Favorite':
                showFavoriteDialog('world', D.id);
                break;
            case 'New Instance and Self Invite':
                newInstanceSelfInvite(D.id);
                break;
            case 'Rename':
                promptRenameWorld(D);
                break;
            case 'Change Description':
                promptChangeWorldDescription(D);
                break;
            case 'Change Capacity':
                promptChangeWorldCapacity(D);
                break;
            case 'Change Recommended Capacity':
                promptChangeWorldRecommendedCapacity(D);
                break;
            case 'Change YouTube Preview':
                promptChangeWorldYouTubePreview(D);
                break;
            default:
                break;
        }
    }

    /**
     *
     * @param world
     */
    function promptRenameWorld(world) {
        modalStore
            .prompt({
                title: t('prompt.rename_world.header'),
                description: t('prompt.rename_world.description'),
                confirmText: t('prompt.rename_world.ok'),
                cancelText: t('prompt.rename_world.cancel'),
                inputValue: world.ref.name,
                errorMessage: t('prompt.rename_world.input_error')
            })
            .then(({ ok, value }) => {
                if (!ok) return;
                if (value && value !== world.ref.name) {
                    worldRequest
                        .saveWorld({
                            id: world.id,
                            name: value
                        })
                        .then((args) => {
                            toast.success(t('prompt.rename_world.message.success'));
                            return args;
                        });
                }
            })
            .catch(() => {});
    }
    /**
     *
     * @param world
     */
    function promptChangeWorldDescription(world) {
        modalStore
            .prompt({
                title: t('prompt.change_world_description.header'),
                description: t('prompt.change_world_description.description'),
                confirmText: t('prompt.change_world_description.ok'),
                cancelText: t('prompt.change_world_description.cancel'),
                inputValue: world.ref.description,
                errorMessage: t('prompt.change_world_description.input_error')
            })
            .then(({ ok, value }) => {
                if (!ok) return;
                if (value && value !== world.ref.description) {
                    worldRequest
                        .saveWorld({
                            id: world.id,
                            description: value
                        })
                        .then((args) => {
                            toast.success(t('prompt.change_world_description.message.success'));
                            return args;
                        });
                }
            })
            .catch(() => {});
    }

    /**
     *
     * @param world
     */
    function promptChangeWorldCapacity(world) {
        modalStore
            .prompt({
                title: t('prompt.change_world_capacity.header'),
                description: t('prompt.change_world_capacity.description'),
                confirmText: t('prompt.change_world_capacity.ok'),
                cancelText: t('prompt.change_world_capacity.cancel'),
                inputValue: world.ref.capacity,
                pattern: /\d+$/,
                errorMessage: t('prompt.change_world_capacity.input_error')
            })
            .then(({ ok, value }) => {
                if (!ok) return;
                if (value && value !== world.ref.capacity) {
                    worldRequest
                        .saveWorld({
                            id: world.id,
                            capacity: Number(value)
                        })
                        .then((args) => {
                            toast.success(t('prompt.change_world_capacity.message.success'));
                            return args;
                        });
                }
            })
            .catch(() => {});
    }

    /**
     *
     * @param world
     */
    function promptChangeWorldRecommendedCapacity(world) {
        modalStore
            .prompt({
                title: t('prompt.change_world_recommended_capacity.header'),
                description: t('prompt.change_world_recommended_capacity.description'),
                confirmText: t('prompt.change_world_capacity.ok'),
                cancelText: t('prompt.change_world_capacity.cancel'),
                inputValue: world.ref.recommendedCapacity,
                pattern: /\d+$/,
                errorMessage: t('prompt.change_world_recommended_capacity.input_error')
            })
            .then(({ ok, value }) => {
                if (!ok) return;
                if (value && value !== world.ref.recommendedCapacity) {
                    worldRequest
                        .saveWorld({
                            id: world.id,
                            recommendedCapacity: Number(value)
                        })
                        .then((args) => {
                            toast.success(t('prompt.change_world_recommended_capacity.message.success'));
                            return args;
                        });
                }
            })
            .catch(() => {});
    }

    /**
     *
     * @param world
     */
    function promptChangeWorldYouTubePreview(world) {
        modalStore
            .prompt({
                title: t('prompt.change_world_preview.header'),
                description: t('prompt.change_world_preview.description'),
                confirmText: t('prompt.change_world_preview.ok'),
                cancelText: t('prompt.change_world_preview.cancel'),
                inputValue: world.ref.previewYoutubeId,
                errorMessage: t('prompt.change_world_preview.input_error')
            })
            .then(({ ok, value }) => {
                if (!ok) return;
                if (value && value !== world.ref.previewYoutubeId) {
                    let processedValue = value;
                    if (value.length > 11) {
                        try {
                            const url = new URL(value);
                            const id1 = url.pathname;
                            const id2 = url.searchParams.get('v');
                            if (id1 && id1.length === 12) {
                                processedValue = id1.substring(1, 12);
                            }
                            if (id2 && id2.length === 11) {
                                processedValue = id2;
                            }
                        } catch {
                            toast.error(t('prompt.change_world_preview.message.error'));
                            return;
                        }
                    }
                    if (processedValue !== world.ref.previewYoutubeId) {
                        worldRequest
                            .saveWorld({
                                id: world.id,
                                previewYoutubeId: processedValue
                            })
                            .then((args) => {
                                toast.success(t('prompt.change_world_preview.message.success'));
                                return args;
                            });
                    }
                }
            })
            .catch(() => {});
    }
    /**
     *
     */
    function onWorldMemoChange() {
        const worldId = worldDialog.value.id;
        const memo = worldDialog.value.memo;
        if (memo) {
            database.setWorldMemo({
                worldId,
                editedAt: new Date().toJSON(),
                memo
            });
        } else {
            database.deleteWorldMemo(worldId);
        }
    }
    /**
     *
     * @param worldRef
     */
    function showPreviousInstancesListDialog(worldRef) {
        openPreviousInstancesListDialog('world', worldRef);
    }
    /**
     *
     */
    function refreshWorldDialogTreeData() {
        treeData.value = formatJsonVars(worldDialog.value.ref);
    }
    /**
     *
     */
    function copyWorldId() {
        navigator.clipboard
            .writeText(worldDialog.value.id)
            .then(() => {
                toast.success(t('message.world.id_copied'));
            })
            .catch((err) => {
                console.error('copy failed:', err);
                toast.error(t('message.copy_failed'));
            });
    }
    /**
     *
     */
    function copyWorldUrl() {
        navigator.clipboard
            .writeText(`https://vrchat.com/home/world/${worldDialog.value.id}`)
            .then(() => {
                toast.success(t('message.world.url_copied'));
            })
            .catch((err) => {
                console.error('copy failed:', err);
                toast.error(t('message.copy_failed'));
            });
    }
    /**
     *
     */
    function copyWorldName() {
        navigator.clipboard
            .writeText(worldDialog.value.ref.name)
            .then(() => {
                toast.success(t('message.world.name_copied'));
            })
            .catch((err) => {
                console.error('copy failed:', err);
                toast.error(t('message.copy_failed'));
            });
    }
    /**
     *
     */
    function showWorldAllowedDomainsDialog() {
        const D = worldAllowedDomainsDialog.value;
        D.worldId = worldDialog.value.id;
        D.urlList = worldDialog.value.ref?.urlList ?? [];
        D.visible = true;
    }

    /**
     *
     */
    async function translateDescription() {
        if (isTranslating.value) return;

        const description = worldDialog.value.ref.description;
        if (!description) return;

        // Toggle: if already translated, clear to show original
        if (translatedDescription.value) {
            translatedDescription.value = '';
            return;
        }

        isTranslating.value = true;
        try {
            const translated = await translateText(description, bioLanguage.value);
            if (!translated) {
                throw new Error('No translation returned');
            }

            translatedDescription.value = translated;
        } catch (error) {
            console.error('Translation failed:', error);
        } finally {
            isTranslating.value = false;
        }
    }

    watch(
        () => [worldDialog.value.id, worldDialog.value.ref?.description],
        () => {
            translatedDescription.value = '';
        }
    );
</script>
