<template>
	<section class="profile-section">
		<div class="section-header">
			<h3 class="heading">API Keys</h3>

			<div class="keys-actions">
				<Icon
					v-tooltip="'Flush all keys'"
					icon="stack-cancel"
					class="keys-flush"
					@click="flushKeys"
				/>

				<button
					class="button"
					@click="createKey"
				>
					<Icon icon="key" />
					<span class="button-label">New key</span>
				</button>
			</div>
		</div>

		<div
			v-if="newKey"
			class="newkey"
		>
			<p class="key-info">Successfully generated key with identifier <strong class="newkey-identifier ellipsis">{{ newKey.identifier }}</strong>:</p>

			<input
				:value="newKey.key"
				class="input ellipsis"
				@click="copyKey"
			>

			<p class="key-info">Please store this key securely, you will <strong>not</strong> be able to retrieve it later. If you lose it, you must generate a new key.</p>
		</div>

		<ul
			v-if="keys.length > 0"
			class="keys nolist"
		>
			<li
				v-for="key in keys"
				:key="`key-${key.id}`"
				class="key"
			>
				<div class="key-row key-header">
					<strong class="key-value key-identifier ellipsis">{{ key.identifier }}</strong>

					<span class="key-actions">
						<Icon
							icon="bin"
							class="key-remove"
							@click="removeKey(key)"
						/>
					</span>
				</div>

				<div class="key-row key-details">
					<span class="key-value key-created">
						<Icon icon="plus-circle" />

						<time
							v-tooltip="`Created ${format(key.createdAt, 'yyyy-MM-dd hh:mm:ss')}`"
							:datetime="key.createdAt.toISOString()"
						>{{ formatDistanceStrict(key.createdAt, now) }} ago</time>
					</span>

					<span class="key-value key-used">
						<Icon icon="history" />

						<template v-if="key.lastUsedAt">
							<time
								v-tooltip="`Last used ${format(key.lastUsedAt, 'yyyy-MM-dd hh:mm:ss')} from IP ${key.lastUsedIp}`"
								:datetime="key.lastUsedAt.toISOString()"
							>{{ formatDistanceStrict(key.lastUsedAt, now) }} ago</time>
						</template>

						<template v-else>Never</template>
					</span>
				</div>
			</li>
		</ul>

		<div
			v-if="keys.length > 0"
			class="info"
		>
			<h3 class="info-heading">HTTP headers</h3>

			<code class="headers">
				API-User: {{ user.id }}<br>
				API-Key: YourSecurelyStoredApiKey12345678
			</code>
		</div>
	</section>
</template>

<script setup>
import { ref, inject } from 'vue';
import { format, formatDistanceStrict } from 'date-fns';

import { get, post, del } from '#/src/api.js';
import events from '#/src/events.js';

const pageContext = inject('pageContext');
const now = pageContext.meta.now;
const user = pageContext.user;
const keys = ref(pageContext.pageProps.keys);
const newKey = ref(null);

async function createKey() {
	const key = await post('/me/keys', null, {
		appendErrorMessage: true,
	});

	newKey.value = key;
	keys.value = await get('/me/keys');
}

async function removeKey(key) {
	if (confirm(`Are you sure you want to remove API key '${key.identifier}'? It can not be restored.`)) { // eslint-disable-line no-restricted-globals, no-alert
		newKey.value = null;

		await del(`/me/keys/${key.identifier}`);

		keys.value = await get('/me/keys');
	}
}

async function flushKeys() {
	if (confirm('Are you sure you want to remove ALL your API keys? They can not be restored.')) { // eslint-disable-line no-restricted-globals, no-alert
		newKey.value = null;

		await del('/me/keys');

		keys.value = [];
	}
}

function copyKey(event) {
	event.target.select();
	navigator.clipboard.writeText(newKey.value.key);

	events.emit('feedback', {
		type: 'success',
		message: 'Key copied to clipboard',
	});
}
</script>

<style scoped>
.page {
	display: flex;
	flex-grow: 1;
	justify-content: center;
}

.manager {
	width: 1200px;
	max-width: 100%;
	box-sizing: border-box;
}

.keys-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: .5rem;
}

.keys-actions {
	display: flex;
	align-items: center;

	> .icon {
		padding: .5rem 1rem;
	}
}

.keys-actions,
.key-actions {
	.icon {
		height: 100%;
		fill: var(--glass);

		&:hover {
			cursor: pointer;
		}
	}
}

.keys-flush,
.key-remove {
	&:hover {
		fill: var(--error);
	}
}

.keys {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(25rem, 1fr));
	gap: .5rem;
	margin-bottom: 2rem;
}

.key {
	background: var(--background);
	box-shadow: 0 0 3px var(--shadow-weak-30);
	border-radius: .25rem;
	font-size: .9rem;
}

.key-row {
	display: flex;
	justify-content: space-between;
	align-items: center;
	overflow: hidden;
}

.key-value {
	display: flex;
	align-items: center;
	gap: .25rem;
	box-sizing: border-box;

	.icon {
		width: .9rem;
		height: .9rem;
		margin-right: .25rem;
		fill: var(--glass);
	}
}

.key-header .key-value {
	padding: .5rem .75rem;
}

.key-details .key-value {
	padding: .25rem .75rem .75rem .75rem;
}

.key-identifier {
	display: inline-block;
	width: 0;
	flex-grow: 1;
}

.key-actions .icon {
	height: 1rem;
	padding: .75rem .75rem .5rem .75rem;
	overflow: hidden;
}

.newkey {
	max-width: 100%;
	display: inline-block;
	box-sizing: border-box;
	padding: .5rem .75rem;
	margin-bottom: 1rem;
	background: var(--enabled-background);
	border: solid 1px var(--success);
	border-radius: .25rem;
	line-height: 1.5;

	.input {
		width: 24rem;
		max-width: 100%;
		padding: .25rem .5rem;
		margin-bottom: .5rem;
		font-weight: bold;
	}
}

.newkey-identifier {
	white-space: nowrap;
}

.key-info {
	margin: 0;

	&:not(:last-child) {
		margin-bottom: .25rem;
	}
}

.headers {
	display: block;
	max-width: 100%;
	padding: .5rem 0;
	white-space: nowrap;
	overflow: auto;
}

.info-heading {
	margin: 0;
}

@media(--small-20) {
	.keys {
		grid-template-columns: 1fr;
	}
}
</style>