import { fail } from '@sveltejs/kit';
import { createApiClient, extractErrorCode } from '$lib/shared/api.server';
import { getErrorMessage } from '$lib/shared/errors';
import type { Actions, PageServerLoad } from './$types';
import type { components } from '$lib/generated/api';

export type InviteListItem = components['schemas']['InviteListItemDTO'];
export type UserGroup = components['schemas']['UserGroup'];

const VALID_STATUSES = ['ACTIVE', 'REVOKED', 'EXPIRED'] as const;
type InviteStatus = (typeof VALID_STATUSES)[number];

export const load: PageServerLoad = async ({ url, fetch }) => {
	const rawStatus = url.searchParams.get('status');
	const status: InviteStatus = VALID_STATUSES.includes(rawStatus as InviteStatus)
		? (rawStatus as InviteStatus)
		: 'ACTIVE';
	const api = createApiClient(fetch);

	const [invitesResult, groupsResult] = await Promise.all([
		api.GET('/api/invites', { params: { query: { status } } }),
		api.GET('/api/groups')
	]);

	let invites: InviteListItem[] = [];
	let loadError: string | null = null;
	if (!invitesResult.response.ok) {
		loadError = extractErrorCode(invitesResult.error) ?? 'INTERNAL_ERROR';
	} else {
		invites = (invitesResult.data ?? []) as InviteListItem[];
	}

	let groups: UserGroup[] = [];
	let groupsLoadError: string | null = null;
	if (!groupsResult.response.ok) {
		groupsLoadError = extractErrorCode(groupsResult.error) ?? 'INTERNAL_ERROR';
	} else {
		const raw = groupsResult.data ?? [];
		groups = [...raw].sort((a, b) => a.name.localeCompare(b.name));
	}

	return { invites, status, loadError, groups, groupsLoadError };
};

export const actions = {
	create: async ({ request, fetch }) => {
		const formData = await request.formData();
		const label = (formData.get('label') as string) || undefined;
		const maxUsesRaw = formData.get('maxUses') as string;
		const maxUses = maxUsesRaw ? parseInt(maxUsesRaw, 10) : undefined;
		const prefillFirstName = (formData.get('prefillFirstName') as string) || undefined;
		const prefillLastName = (formData.get('prefillLastName') as string) || undefined;
		const prefillEmail = (formData.get('prefillEmail') as string) || undefined;
		const expiresAt = (formData.get('expiresAt') as string) || undefined;
		const groupIds = formData.getAll('groupIds') as string[];

		const api = createApiClient(fetch);
		const result = await api.POST('/api/invites', {
			body: { label, maxUses, prefillFirstName, prefillLastName, prefillEmail, expiresAt, groupIds }
		});

		if (!result.response.ok) {
			return fail(result.response.status, {
				createError: extractErrorCode(result.error) ?? 'INTERNAL_ERROR'
			});
		}

		return { created: result.data! as InviteListItem };
	},

	revoke: async ({ request, fetch }) => {
		const formData = await request.formData();
		const id = formData.get('id') as string | null;
		if (!id) return fail(400, { revokeError: getErrorMessage('VALIDATION_ERROR') });

		const api = createApiClient(fetch);
		const result = await api.DELETE('/api/invites/{id}', { params: { path: { id } } });

		if (!result.response.ok) {
			return fail(result.response.status, {
				revokeError: extractErrorCode(result.error) ?? 'INTERNAL_ERROR'
			});
		}

		return { revoked: id };
	}
} satisfies Actions;
