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

type ActivityFeedItemDTO = components['schemas']['ActivityFeedItemDTO'];
type NotificationDTO = components['schemas']['NotificationDTO'];
type AuditKind = NonNullable<operations['getActivity']['parameters']['query']>['kinds'] extends
	| (infer K)[]
	| undefined
	? K
	: never;

export type FilterValue = 'alle' | 'fuer-dich' | 'hochgeladen' | 'transkription' | 'kommentare';

const VALID_FILTERS: FilterValue[] = [
	'alle',
	'fuer-dich',
	'hochgeladen',
	'transkription',
	'kommentare'
];

// fuer-dich stays client-side: youMentioned || youParticipated cannot be expressed as a kinds filter
const KINDS_FOR_FILTER: Partial<Record<FilterValue, AuditKind[]>> = {
	hochgeladen: ['FILE_UPLOADED'],
	transkription: ['TEXT_SAVED', 'BLOCK_REVIEWED', 'ANNOTATION_CREATED'],
	kommentare: ['COMMENT_ADDED', 'MENTION_CREATED']
};

function parseFilter(raw: string | null): FilterValue {
	if (raw && (VALID_FILTERS as string[]).includes(raw)) return raw as FilterValue;
	return 'alle';
}

export async function load({ fetch, url }) {
	const api = createApiClient(fetch);
	const filter = parseFilter(url.searchParams.get('filter'));
	const limit = Math.min(Number(url.searchParams.get('limit')) || 40, 40);
	const kinds = KINDS_FOR_FILTER[filter];

	const [activityResult, unreadResult] = await Promise.allSettled([
		api.GET('/api/dashboard/activity', { params: { query: { limit, ...(kinds && { kinds }) } } }),
		api.GET('/api/notifications', {
			params: { query: { read: false, page: 0, size: 20 } }
		})
	]);

	let activityFeed: ActivityFeedItemDTO[] = [];
	let unreadNotifications: NotificationDTO[] = [];
	let loadError: string | null = null;

	if (activityResult.status === 'fulfilled' && activityResult.value.response.ok) {
		activityFeed = (activityResult.value.data as ActivityFeedItemDTO[]) ?? [];
	} else if (activityResult.status === 'fulfilled') {
		loadError = 'activity';
	}

	if (unreadResult.status === 'fulfilled' && unreadResult.value.response.ok) {
		unreadNotifications = unreadResult.value.data?.content ?? [];
	}

	return {
		filter,
		activityFeed,
		unreadNotifications,
		loadError
	};
}

export const actions = {
	'dismiss-notification': async ({ request, fetch }) => {
		const data = await request.formData();
		const raw = data.get('notificationId');
		const notificationId = typeof raw === 'string' ? raw : null;
		if (!notificationId) return fail(400, { error: getErrorMessage(undefined) });
		const api = createApiClient(fetch);
		const result = await api.PATCH('/api/notifications/{id}/read', {
			params: { path: { id: notificationId } }
		});
		if (!result.response.ok) {
			const code = (result.error as unknown as { code?: string })?.code;
			return fail(result.response.status, { error: getErrorMessage(code) });
		}
		return { success: true };
	},

	'mark-all-read': async ({ fetch }) => {
		const api = createApiClient(fetch);
		const result = await api.POST('/api/notifications/read-all');
		if (!result.response.ok) {
			const code = (result.error as unknown as { code?: string })?.code;
			return fail(result.response.status, { error: getErrorMessage(code) });
		}
		return { success: true };
	}
};
