<template>
	<MkStickyContainer>
		<template #header>
			<MkPageHeader
				:actions="headerActions"
				:tabs="headerTabs"
				:display-back-button="true"
			/>
		</template>
		<MkSpacer :content-max="900">
			<div class="verifiedBadges">
				<div class="_panel section">
					<h2>認証バッジを直接変更</h2>
					<div class="directGrant">
						<MkInput
							v-model="directTarget"
							type="text"
							:spellcheck="false"
							placeholder="@username / @username@host / userId"
						>
							<template #label>対象アカウント</template>
						</MkInput>
						<MkButton
							primary
							:disabled="directTarget.trim() === ''"
							@click="setDirectVerified(true)"
						>
							<i class="ph-seal-check ph-bold ph-lg"></i>
							付与
						</MkButton>
						<MkButton
							danger
							:disabled="directTarget.trim() === ''"
							@click="setDirectVerified(false)"
						>
							<i class="ph-seal-warning ph-bold ph-lg"></i>
							剥奪
						</MkButton>
					</div>
					<div v-if="directUser" class="directUser">
						<MkUserCardMini :user="directUser" />
					</div>
				</div>

				<div class="_panel section">
					<h2>付与済みアカウント</h2>
					<MkPagination
						v-slot="{ items }"
						ref="verifiedUsers"
						:pagination="verifiedUsersPagination"
					>
						<div
							v-for="user in items"
							:key="user.id"
							class="verifiedUser"
						>
							<MkUserCardMini class="verifiedUserCard" :user="user" />
							<MkButton danger @click="revoke(user)">
								<i class="ph-seal-warning ph-bold ph-lg"></i>
								剥奪
							</MkButton>
						</div>
					</MkPagination>
				</div>

				<div class="_panel section">
					<div class="header">
						<h2>認証バッジ申請</h2>
						<MkSelect v-model="state" class="state">
							<template #label>状態</template>
							<option value="pending">未処理</option>
							<option value="approved">承認済み</option>
							<option value="rejected">却下済み</option>
							<option value="all">すべて</option>
						</MkSelect>
					</div>

					<MkPagination
						v-slot="{ items }"
						ref="requests"
						:pagination="pagination"
					>
						<div
							v-for="request in items"
							:key="request.id"
							class="request _panel"
						>
							<MkA class="user" :to="`/user-info/${request.userId}`">
								<MkAvatar class="avatar" :user="request.user" />
								<div class="names">
									<MkUserName :user="request.user" />
									<MkAcct :user="request.user" />
								</div>
							</MkA>
							<div class="body">
								<div class="meta">
									<span>{{ statusText(request.status) }}</span>
									<span><MkTime :time="request.createdAt" /></span>
								</div>
								<Mfm v-if="request.comment" :text="request.comment" />
								<div v-if="request.resolver" class="resolver">
									処理者: <MkAcct :user="request.resolver" />
								</div>
								<div v-if="request.status === 'pending'" class="actions">
									<MkButton primary @click="resolve(request.id, true)">
										承認して付与
									</MkButton>
									<MkButton @click="resolve(request.id, false)">
										却下
									</MkButton>
								</div>
							</div>
						</div>
					</MkPagination>
				</div>
			</div>
		</MkSpacer>
	</MkStickyContainer>
</template>

<script lang="ts" setup>
import { computed, ref } from "vue";
import MkButton from "@/components/MkButton.vue";
import MkInput from "@/components/form/input.vue";
import MkSelect from "@/components/form/select.vue";
import MkPagination from "@/components/MkPagination.vue";
import MkUserCardMini from "@/components/MkUserCardMini.vue";
import * as os from "@/os";
import { definePageMetadata } from "@/scripts/page-metadata";

const directTarget = ref("");
const directUser = ref<any>(null);
const state = ref("pending");
const requests = ref<InstanceType<typeof MkPagination>>();
const verifiedUsers = ref<InstanceType<typeof MkPagination>>();

const pagination = {
	endpoint: "admin/verified-badge-requests" as const,
	limit: 10,
	params: computed(() => ({
		state: state.value,
	})),
};

const verifiedUsersPagination = {
	endpoint: "admin/show-users" as const,
	limit: 10,
	params: {
		state: "verified",
		origin: "combined",
		sort: "+createdAt",
	},
	offsetMode: true,
};

function normalizeAcct(input: string) {
	const target = input.trim().replace(/^@/, "");
	const parts = target.split("@");
	if (parts.length >= 2) {
		return { username: parts[0], host: parts.slice(1).join("@") };
	}
	return { username: target, host: null };
}

async function lookupTarget(input: string) {
	try {
		return await os.api("users/show", { userId: input.trim() });
	} catch {
		return await os.api("users/show", normalizeAcct(input));
	}
}

async function setDirectVerified(isVerified: boolean) {
	const user = await lookupTarget(directTarget.value);
	directUser.value = user;

	if (!isVerified) {
		const confirm = await os.confirm({
			type: "warning",
			text: `@${user.username}${user.host ? `@${user.host}` : ""} から認証バッジを剥奪しますか？`,
		});
		if (confirm.canceled) return;
	}

	await os.apiWithDialog("admin/set-user-verified", {
		userId: user.id,
		isVerified,
	});

	directUser.value = {
		...user,
		isVerified,
	};
	verifiedUsers.value?.reload();
}

async function revoke(user: any) {
	const confirm = await os.confirm({
		type: "warning",
		text: `@${user.username}${user.host ? `@${user.host}` : ""} から認証バッジを剥奪しますか？`,
	});
	if (confirm.canceled) return;

	await os.apiWithDialog("admin/set-user-verified", {
		userId: user.id,
		isVerified: false,
	});
	verifiedUsers.value?.removeItem((item) => item.id === user.id);
}

async function resolve(requestId: string, approve: boolean) {
	await os.apiWithDialog("admin/resolve-verified-badge-request", {
		requestId,
		approve,
	});
	requests.value?.removeItem((item) => item.id === requestId);
	if (approve) verifiedUsers.value?.reload();
}

function statusText(status: string) {
	switch (status) {
		case "approved":
			return "承認済み";
		case "rejected":
			return "却下済み";
		default:
			return "未処理";
	}
}

const headerActions = computed(() => []);
const headerTabs = computed(() => []);

definePageMetadata({
	title: "認証バッジ",
	icon: "ph-seal-check ph-bold ph-lg",
});
</script>

<style lang="scss" scoped>
.verifiedBadges {
	margin: var(--margin);
}

.section {
	padding: 24px;
	margin-bottom: var(--margin);
}

h2 {
	margin: 0 0 16px;
	font-size: 1.1em;
}

.directGrant {
	display: grid;
	grid-template-columns: 1fr auto auto;
	gap: 12px;
	align-items: end;
}

.directUser {
	margin-top: 16px;
}

.header {
	display: flex;
	align-items: end;
	justify-content: space-between;
	gap: 16px;
	margin-bottom: 16px;
}

.state {
	width: 180px;
}

.verifiedUser {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: 12px;
	align-items: center;
	margin-bottom: 12px;
}

.verifiedUserCard {
	min-width: 0;
}

.request {
	display: grid;
	grid-template-columns: 280px 1fr;
	gap: 16px;
	padding: 16px;
	margin-bottom: 12px;
}

.user {
	display: flex;
	align-items: center;
	gap: 12px;
	min-width: 0;
}

.avatar {
	width: 48px;
	height: 48px;
}

.names {
	display: grid;
	min-width: 0;
}

.meta {
	display: flex;
	gap: 12px;
	opacity: 0.7;
	font-size: 0.9em;
	margin-bottom: 8px;
}

.resolver {
	margin-top: 8px;
	opacity: 0.8;
}

.actions {
	display: flex;
	gap: 8px;
	margin-top: 16px;
}

@media (max-width: 700px) {
	.directGrant,
	.verifiedUser,
	.request {
		grid-template-columns: 1fr;
	}

	.header {
		display: block;
	}

	.state {
		width: 100%;
	}
}
</style>
