import { error } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import { createApiClient, extractErrorCode } from '$lib/shared/api.server';
import { getErrorMessage } from '$lib/shared/errors';
import type { components } from '$lib/generated/api';

type UserGroup = components['schemas']['UserGroup'];

function hasPerm(user: { groups?: UserGroup[] } | undefined, perm: string): boolean {
	return user?.groups?.some((g) => g.permissions.includes(perm)) ?? false;
}

function hasAnyAdminPerm(user: { groups?: UserGroup[] } | undefined): boolean {
	return (
		hasPerm(user, 'ADMIN') ||
		hasPerm(user, 'ADMIN_USER') ||
		hasPerm(user, 'ADMIN_TAG') ||
		hasPerm(user, 'ADMIN_PERMISSION')
	);
}

export async function load({ fetch, locals }) {
	const user = locals.user;
	if (!hasAnyAdminPerm(user)) throw error(403, getErrorMessage('FORBIDDEN'));

	const api = createApiClient(fetch);
	const canManageUsers = hasPerm(user, 'ADMIN_USER');

	// TODO(#453): replace with dedicated /api/admin/stats endpoint returning counts only
	const [usersResult, groupsResult, tagsResult] = await Promise.all([
		api.GET('/api/users'),
		api.GET('/api/groups'),
		api.GET('/api/tags')
	]);

	if (!usersResult.response.ok) {
		throw error(usersResult.response.status, getErrorMessage(extractErrorCode(usersResult.error)));
	}
	if (!groupsResult.response.ok) {
		throw error(
			groupsResult.response.status,
			getErrorMessage(extractErrorCode(groupsResult.error))
		);
	}
	if (!tagsResult.response.ok) {
		throw error(tagsResult.response.status, getErrorMessage(extractErrorCode(tagsResult.error)));
	}

	let inviteCount = 0;
	if (canManageUsers) {
		const apiUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
		const inviteRes = await fetch(`${apiUrl}/api/invites`);
		if (inviteRes.ok) {
			const invites = await inviteRes.json();
			inviteCount = Array.isArray(invites) ? invites.length : 0;
		}
	}

	return {
		userCount: (usersResult.data ?? []).length,
		groupCount: (groupsResult.data ?? []).length,
		tagCount: (tagsResult.data ?? []).length,
		inviteCount,
		canManageUsers,
		canManageTags: hasPerm(user, 'ADMIN_TAG'),
		canManagePermissions: hasPerm(user, 'ADMIN_PERMISSION'),
		canRunMaintenance: hasPerm(user, 'ADMIN')
	};
}
