import { mkdir, writeFile } from 'node:fs/promises';
import path from 'node:path';
import { AVATAR_MAX_BYTES } from '$lib/constants/avatar';

export { AVATAR_MAX_BYTES };

const ALLOWED_MIME = new Set(['image/jpeg', 'image/png', 'image/webp', 'image/gif']);

const EXT_BY_MIME: Record<string, string> = {
	'image/jpeg': 'jpg',
	'image/png': 'png',
	'image/webp': 'webp',
	'image/gif': 'gif'
};

export type AvatarUploadError = 'FILE_TOO_LARGE' | 'INVALID_TYPE' | 'EMPTY_FILE';

export function getAvatarUploadDir(): string {
	return path.join(process.cwd(), 'uploads', 'avatars');
}

export async function saveMemberAvatar(memberId: number, file: File): Promise<string> {
	if (!(file instanceof File) || file.size === 0) {
		throw new Error('EMPTY_FILE' satisfies AvatarUploadError);
	}

	if (file.size > AVATAR_MAX_BYTES) {
		throw new Error('FILE_TOO_LARGE' satisfies AvatarUploadError);
	}

	if (!ALLOWED_MIME.has(file.type)) {
		throw new Error('INVALID_TYPE' satisfies AvatarUploadError);
	}

	const ext = EXT_BY_MIME[file.type];
	const filename = `${memberId}.${ext}`;
	const dir = getAvatarUploadDir();
	await mkdir(dir, { recursive: true });

	const buffer = Buffer.from(await file.arrayBuffer());
	await writeFile(path.join(dir, filename), buffer);

	return `/uploads/avatars/${filename}`;
}
