<template>
	<MkStickyContainer>
		<template #header
			><MkPageHeader :actions="headerActions" :tabs="headerTabs"
		/></template>
		<MkSpacer :content-max="800">
			<XPostForm
				v-if="state === 'writing'"
				fixed
				:instant="true"
				:initial-text="initialText"
				:initial-visibility="visibility"
				:initial-files="files"
				:initial-local-only="localOnly"
				:reply="reply"
				:renote="renote"
				:initial-visible-users="visibleUsers"
				class="_panel"
				@posted="state = 'posted'"
			/>
			<MkButton
				v-else-if="state === 'posted'"
				primary
				class="close"
				@click="close()"
				>{{ i18n.ts.close }}</MkButton
			>
		</MkSpacer>
	</MkStickyContainer>
</template>

<script lang="ts" setup>
// SPECIFICATION: https://misskey-hub.net/docs/features/share-form.html

import {} from "vue";
import { noteVisibilities } from "calckey-js";
import * as Acct from "calckey-js/built/acct";
import * as Misskey from "calckey-js";
import MkButton from "@/components/MkButton.vue";
import XPostForm from "@/components/MkPostForm.vue";
import * as os from "@/os";
import { mainRouter } from "@/router";
import { definePageMetadata } from "@/scripts/page-metadata";
import { i18n } from "@/i18n";

const urlParams = new URLSearchParams(window.location.search);
const localOnlyQuery = urlParams.get("localOnly");
const visibilityQuery = urlParams.get("visibility");

let state = $ref("fetching" as "fetching" | "writing" | "posted");
let title = $ref(urlParams.get("title"));
const text = urlParams.get("text");
const url = urlParams.get("url");
let initialText = $ref(null as string | null);
let reply = $ref(null as Misskey.entities.Note | null);
let renote = $ref(null as Misskey.entities.Note | null);
let visibility = $ref(
	noteVisibilities.includes(visibilityQuery) ? visibilityQuery : null
);
let localOnly = $ref(
	localOnlyQuery === "0" ? false : localOnlyQuery === "1" ? true : null
);
let files = $ref([] as Misskey.entities.DriveFile[]);
let visibleUsers = $ref([] as Misskey.entities.User[]);

async function init() {
	let noteText = "";
	if (title) noteText += `[ ${title} ]\n`;
	// Googleニュース対策
	if (text?.startsWith(`${title}.\n`))
		noteText += text.replace(`${title}.\n`, "");
	else if (text && title !== text) noteText += `${text}\n`;
	if (url) noteText += `${url}`;
	initialText = noteText.trim();

	if (visibility === "specified") {
		const visibleUserIds = urlParams.get("visibleUserIds");
		const visibleAccts = urlParams.get("visibleAccts");
		await Promise.all(
			[
				...(visibleUserIds
					? visibleUserIds.split(",").map((userId) => ({ userId }))
					: []),
				...(visibleAccts
					? visibleAccts.split(",").map(Acct.parse)
					: []),
			]
				// TypeScriptの指示通りに変換する
				.map((q) =>
					"username" in q
						? {
								username: q.username,
								host: q.host === null ? undefined : q.host,
						  }
						: q
				)
				.map((q) =>
					os.api("users/show", q).then(
						(user) => {
							visibleUsers.push(user);
						},
						() => {
							console.error(
								`Invalid user query: ${JSON.stringify(q)}`
							);
						}
					)
				)
		);
	}

	try {
		//#region Reply
		const replyId = urlParams.get("replyId");
		const replyUri = urlParams.get("replyUri");
		if (replyId) {
			reply = await os.api("notes/show", {
				noteId: replyId,
			});
		} else if (replyUri) {
			const obj = await os.api("ap/show", {
				uri: replyUri,
			});
			if (obj.type === "Note") {
				reply = obj.object;
			}
		}
		//#endregion

		//#region Renote
		const renoteId = urlParams.get("renoteId");
		const renoteUri = urlParams.get("renoteUri");
		if (renoteId) {
			renote = await os.api("notes/show", {
				noteId: renoteId,
			});
		} else if (renoteUri) {
			const obj = await os.api("ap/show", {
				uri: renoteUri,
			});
			if (obj.type === "Note") {
				renote = obj.object;
			}
		}
		//#endregion

		//#region Drive files
		const fileIds = urlParams.get("fileIds");
		if (fileIds) {
			await Promise.all(
				fileIds.split(",").map((fileId) =>
					os.api("drive/files/show", { fileId }).then(
						(file) => {
							files.push(file);
						},
						() => {
							console.error(`Failed to fetch a file ${fileId}`);
						}
					)
				)
			);
		}
		//#endregion
	} catch (err) {
		os.alert({
			type: "error",
			title: err.message,
			text: err.name,
		});
	}

	state = "writing";
}

init();

function close(): void {
	window.close();

	// 閉じなければ100ms後タイムラインに
	window.setTimeout(() => {
		mainRouter.push("/");
	}, 100);
}

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

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

definePageMetadata({
	title: i18n.ts.share,
	icon: "ph-share-network ph-bold ph-lg",
});
</script>

<style lang="scss" scoped>
.close {
	margin: 16px auto;
}
</style>