<template>
	<div class="_formRoot">
		<FormSection>
			<template #label>User emojis</template>
			<MkInput
				v-model="name"
				class="_formBlock"
				pattern="^[a-z0-9_]{1,64}$"
				placeholder="abc"
			>
				<template #label>Name</template>
				<template #caption>Use lowercase letters, numbers, and underscores.</template>
			</MkInput>
			<MkSwitch v-model="glyph" class="_formBlock">
				<template #label>Glyph</template>
				<template #caption>Use semicolon syntax such as ;name@user;.</template>
			</MkSwitch>
			<div class="actions _formBlock">
				<MkButton primary inline @click="selectImage">
					<i class="ph-image-square ph-bold ph-lg"></i>
					Select image
				</MkButton>
			</div>
		</FormSection>

		<FormSection>
			<template #label>Registered</template>
			<div v-if="fetching" class="empty">{{ i18n.ts.fetching }}</div>
			<div v-else-if="emojis.length === 0" class="empty">
				{{ i18n.ts.nothing }}
			</div>
			<div v-else class="emojis">
				<div v-for="emoji in emojis" :key="emoji.id" class="emoji _panel">
					<img class="preview" :src="emoji.url" :alt="emoji.name" />
					<div class="body">
						<div class="name _monospace">{{ emoji.name }}</div>
						<div class="code _monospace">
							{{ emoji.glyph ? `;${emoji.name}@${$i.username};` : `:${emoji.name}@${$i.username}:` }}
						</div>
					</div>
					<button class="_button delete" @click="deleteEmoji(emoji)">
						<i class="ph-trash ph-bold ph-lg"></i>
					</button>
				</div>
			</div>
		</FormSection>
	</div>
</template>

<script lang="ts" setup>
import { onMounted, ref } from "vue";
import MkButton from "@/components/MkButton.vue";
import MkInput from "@/components/form/input.vue";
import MkSwitch from "@/components/form/switch.vue";
import FormSection from "@/components/form/section.vue";
import { selectFile } from "@/scripts/select-file";
import * as os from "@/os";
import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata";
import { $i } from "@/account";

type UserEmoji = {
	id: string;
	name: string;
	url: string;
	glyph: boolean;
	glyphUrl: string | null;
	width: number | null;
	height: number | null;
};

const name = ref("");
const glyph = ref(false);
const emojis = ref<UserEmoji[]>([]);
const fetching = ref(true);

async function load() {
	fetching.value = true;
	emojis.value = (await os.api("i/user-emojis/list")) as UserEmoji[];
	fetching.value = false;
}

async function selectImage(ev: MouseEvent | KeyboardEvent) {
	const emojiName = name.value.trim();
	if (!/^[a-z0-9_]{1,64}$/.test(emojiName)) {
		os.alert({
			type: "error",
			text: "Use lowercase letters, numbers, and underscores for the name.",
		});
		return;
	}

	try {
		const file = await selectFile(ev.currentTarget ?? ev.target, "User emoji image");
		await os.api("i/user-emojis/create", {
			name: emojiName,
			fileId: file.id,
			glyph: glyph.value,
		});
		name.value = "";
		await load();
		os.success();
	} catch (err) {
		os.alert({
			type: "error",
			text: err instanceof Error ? err.message : "Failed to create user emoji.",
		});
	}
}

async function deleteEmoji(emoji: UserEmoji) {
	const { canceled } = await os.confirm({
		type: "warning",
		text: i18n.t("deleteAreYouSure", { x: emoji.name }),
	});
	if (canceled) return;

	await os.api("i/user-emojis/delete", { id: emoji.id });
	await load();
	os.success();
}

onMounted(load);

definePageMetadata({
	title: "User emojis",
	icon: "ph-identification-card ph-bold ph-lg",
});
</script>

<style lang="scss" scoped>
.actions {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
}

.empty {
	color: var(--fgTransparentWeak);
	padding: 16px 0;
}

.emojis {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: 10px;
}

.emoji {
	display: grid;
	grid-template-columns: 44px minmax(0, 1fr) 36px;
	align-items: center;
	gap: 10px;
	padding: 10px;
	border-radius: 6px;
}

.preview {
	width: 44px;
	height: 44px;
	object-fit: contain;
}

.body {
	min-width: 0;
}

.name,
.code {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.code {
	color: var(--fgTransparentWeak);
	font-size: 0.9em;
}

.delete {
	width: 36px;
	min-width: 36px;
	height: 36px;
	min-height: 36px;
	padding: 0;
}
</style>
