<template>
<div v-if="$i && fetching" class="">
	<MkLoading/>
</div>
<div v-else-if="$i">
	<XForm
		v-if="state == 'waiting'"
		ref="form"
		class="form"
		:session="session"
		@denied="state = 'denied'"
		@accepted="accepted"
	/>
	<div v-if="state == 'denied'" class="denied">
		<h1>{{ i18n.ts._auth.denied }}</h1>
	</div>
	<div v-if="state == 'accepted'" class="accepted">
		<h1>{{ session.app.isAuthorized ? i18n.t('already-authorized') : i18n.ts.allowed }}</h1>
		<p v-if="session.app.callbackUrl && !auth_code">{{ i18n.ts._auth.callback }}<MkEllipsis/></p>
		<MkKeyValue v-if="session.app.callbackUrl && auth_code" :copy="auth_code">
			<template #key>{{ i18n.ts._auth.copyAsk }}</template>
			<template #value>{{ auth_code }}</template>
		</MkKeyValue>
		<p v-if="!session.app.callbackUrl">{{ i18n.ts._auth.pleaseGoBack }}</p>
	</div>
	<div v-if="state == 'fetch-session-error'" class="error">
		<p>{{ i18n.ts.somethingHappened }}</p>
	</div>
</div>
<div v-else class="signin">
	<MkSignin @login="onLogin"/>
</div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import XForm from './auth.form.vue';
import MkSignin from '@/components/MkSignin.vue';
import MkKeyValue from '@/components/MkKeyValue.vue';
import * as os from '@/os';
import { login } from '@/account';
import { i18n } from '@/i18n';

export default defineComponent({
	components: {
		XForm,
		MkSignin,
		MkKeyValue
	},
	props: ['token'],
	data() {
		return {
			state: null,
			session: null,
			fetching: true,
			i18n,
			auth_code: null
		};
	},
	mounted() {
		if (!this.$i) return;

		// Fetch session
		os.api('auth/session/show', {
			token: this.token,
		}).then(session => {
			this.session = session;
			this.fetching = false;

			// 既に連携していた場合
			if (this.session.app.isAuthorized) {
				os.api('auth/accept', {
					token: this.session.token,
				}).then(() => {
					this.accepted();
				});
			} else {
				this.state = 'waiting';
			}
		}).catch(error => {
			this.state = 'fetch-session-error';
			this.fetching = false;
		});
	},
	methods: {
		accepted() {
			this.state = 'accepted';
			const getUrlParams = () => window.location.search.substring(1).split('&').reduce((result, query) => { const [k, v] = query.split('='); result[k] = decodeURI(v); return result; }, {});
			const isMastodon = !!getUrlParams().mastodon
			if (this.session.app.callbackUrl && isMastodon) {
				const callbackUrl = new URL(this.session.app.callbackUrl);
				callbackUrl.searchParams.append("code", this.session.token);
				if (!!getUrlParams().state) callbackUrl.searchParams.append("state", getUrlParams().state);
				location.href = callbackUrl.toString();
			} else if (this.session.app.callbackUrl) {
				const url = new URL(this.session.app.callbackUrl);
				if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url');
				if (this.session.app.callbackUrl === "urn:ietf:wg:oauth:2.0:oob") {
					this.auth_code = this.session.token;
				} else {
					location.href = `${this.session.app.callbackUrl}?token=${this.session.token}&code=${this.session.token}&state=${getUrlParams().state || ''}`;
				}
			}
		}, onLogin(res) {
			login(res.i);
		},
	},
});
</script>

<style lang="scss" scoped>

</style>