import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { getBooksBySlugs, allProgress, getSavedSlugs } from '$lib/server/pocketbase';
import { log } from '$lib/server/logger';
import type { Book } from '$lib/server/pocketbase';

/**
 * GET /api/library
 * Returns the user's library: books they have started reading or explicitly saved.
 * Each item includes the book record, the last chapter read, and saved_at timestamp.
 *
 * Response shape mirrors LibraryItem in the iOS APIClient.
 */
export const GET: RequestHandler = async ({ locals }) => {
	let progressList: Awaited<ReturnType<typeof allProgress>> = [];
	let savedSlugs: Set<string> = new Set();

	try {
		[progressList, savedSlugs] = await Promise.all([
			allProgress(locals.sessionId, locals.user?.id),
			getSavedSlugs(locals.sessionId, locals.user?.id)
		]);
	} catch (e) {
		log.error('api/library', 'failed to load library data', { err: String(e) });
	}

	// Fetch only the books the user actually has in their library.
	const progressSlugs = new Set(progressList.map((p) => p.slug));
	const allNeededSlugs = new Set([...progressSlugs, ...savedSlugs]);
	const books = allNeededSlugs.size > 0
		? await getBooksBySlugs(allNeededSlugs).catch(() => [] as Book[])
		: [];

	const progressMap: Record<string, number> = {};
	const progressUpdatedMap: Record<string, string> = {};
	for (const p of progressList) {
		progressMap[p.slug] = p.chapter;
		progressUpdatedMap[p.slug] = p.updated;
	}

	const withProgress = books.filter((b) => progressSlugs.has(b.slug));
	const savedOnly = books
		.filter((b) => !progressSlugs.has(b.slug))
		.sort((a, b) => (a.title ?? '').localeCompare(b.title ?? ''));

	withProgress.sort((a, b) => {
		const ta = progressUpdatedMap[a.slug] ?? '';
		const tb = progressUpdatedMap[b.slug] ?? '';
		return tb.localeCompare(ta);
	});

	const ordered = [...withProgress, ...savedOnly];

	const items = ordered.map((book) => ({
		book,
		last_chapter: progressMap[book.slug] ?? null,
		saved_at: progressUpdatedMap[book.slug] ?? new Date().toISOString()
	}));

	return json(items);
};
