<script setup lang="tsx">
import type { TokenInjectType, Responses } from '@/api';
import type { SelectOption, DataTableColumn } from 'naive-ui';
import { inject, onBeforeMount, ref } from 'vue';
import { check_token, Admin, isErrorResponse } from '@/api';
import { onBeforeRouteUpdate } from 'vue-router';
import router from '@/router';
import { loadingMsgWrapper } from '@/utils';
import {
	useMessage,
	NDataTable,
	NSelect,
	NButton,
	NButtonGroup
} from 'naive-ui';

const message = useMessage();

const jwt = inject<TokenInjectType>('jwt') as TokenInjectType;

const users = ref<Responses.GetUsersEntry[]>([]);

onBeforeRouteUpdate(async () => {
	await updatePanel();
});
onBeforeMount(async () => {
	await updatePanel();
});

const updatePanel = loadingMsgWrapper(message, async () => {
	const token = await check_token(jwt);
	if (!token) return;

	const res = await Admin.get_users(token);
	if (isErrorResponse(res)) return router.replace({ path: '/' });
	users.value = res.users;
});

const setRole = loadingMsgWrapper(
	message,
	async (user: number, role: number) => {
		const token = await check_token(jwt);
		if (!token) return;

		const res = await Admin.set_role(user, role, token);
		if (isErrorResponse(res)) console.error(res.message);
		await updatePanel();
	}
);

const action = (
	func: (
		user: number,
		token: string
	) => Promise<Responses.Success | Responses.Error>
) => {
	return loadingMsgWrapper(message, async (user: number) => {
		const token = await check_token(jwt);
		if (!token) return;

		const res = await func(user, token);
		if (isErrorResponse(res)) console.error(res.message);
		await updatePanel();
	});
};

const logoutUser = action(Admin.logout);
const disableTfa = action(Admin.disable_tfa);
const deleteUser = action(Admin.delete_user);

const selectOptions: SelectOption[] = [
	{
		label: 'Disabled',
		value: 0
	},
	{
		label: 'User',
		value: 1
	},
	{
		label: 'Admin',
		value: 2
	}
];

const columns: DataTableColumn<Responses.GetUsersEntry>[] = [
	{
		title: 'Name',
		key: 'name'
	},
	{
		title: 'Type',
		key: 'gitlab',
		render(user) {
			return user.gitlab ? 'Gitlab' : 'Password';
		}
	},
	{
		title: 'Role',
		key: 'role',
		minWidth: 120,
		render(user) {
			return (
				<NSelect
					value={user.role}
					options={selectOptions}
					onUpdateValue={(value: number) => setRole(user.id, value)}
				/>
			);
		}
	},
	{
		title: 'Tfa Status',
		key: 'tfaEnabled',
		render(user) {
			return user.gitlab ? '' : user.tfaEnabled ? 'Enabled' : 'Disabled';
		}
	},
	{
		title: 'Actions',
		key: 'actions',
		render(user) {
			return (
				<NButtonGroup>
					<NButton onClick={() => logoutUser(user.id)}>
						Logout all
					</NButton>
					{user.tfaEnabled ? (
						<NButton
							type="warning"
							onClick={() => disableTfa(user.id)}
						>
							Disable Tfa
						</NButton>
					) : (
						''
					)}
					<NButton onClick={() => deleteUser(user.id)} type="error">
						Delete
					</NButton>
				</NButtonGroup>
			);
		}
	}
];
</script>

<template>
	<n-data-table :columns="columns" :data="users" />
</template>

<style scoped></style>