import { error } from '@sveltejs/kit';
import type { PageServerLoad, Actions } from './$types';
import { log } from '$lib/server/logger';
import { backendFetch } from '$lib/server/scraper';
import {
	bookToListing,
	type CatalogueResponse,
	type NovelListing
} from '$lib/server/catalogue';

export type { NovelListing };

export const load: PageServerLoad = async ({ url, locals }) => {
	const page = url.searchParams.get('page') ?? '1';
	const genre = url.searchParams.get('genre') ?? 'all';
	const sort = url.searchParams.get('sort') ?? 'popular';
	const status = url.searchParams.get('status') ?? 'all';
	const q = url.searchParams.get('q') ?? '';

	const params = new URLSearchParams({ page, genre, sort, status });
	if (q.trim().length >= 2) {
		params.set('q', q.trim());
	}

	let novels: NovelListing[] = [];
	let pageNum = parseInt(page, 10) || 1;
	let hasNext = false;
	let total = 0;
	// Dynamic facets from Meilisearch — fall back to empty arrays if unavailable.
	let genres: string[] = [];
	let statuses: string[] = [];

	try {
		const res = await backendFetch(`/api/catalogue?${params.toString()}`);
		if (!res.ok) {
			log.error('catalogue', 'catalogue returned error', { status: res.status });
			throw error(502, `Catalogue fetch failed: ${res.status}`);
		}
		const data: CatalogueResponse = await res.json();
		novels = (data.books ?? []).map(bookToListing);
		pageNum = data.page ?? 1;
		hasNext = data.has_next ?? false;
		total = data.total ?? 0;
		genres = data.facets?.genres ?? [];
		statuses = data.facets?.statuses ?? [];
	} catch (e) {
		if (e instanceof Error && 'status' in e) throw e;
		log.error('catalogue', 'catalogue network error', { err: String(e) });
		throw error(502, 'Could not reach catalogue service');
	}

	return {
		novels,
		page: pageNum,
		hasNext,
		total,
		genre,
		sort,
		status,
		// Dynamic filter options from Meilisearch facet distribution.
		// Empty arrays when Meilisearch is unavailable — UI falls back to hardcoded lists.
		genres,
		statuses,
		isAdmin: locals.user?.role === 'admin',
		searchQuery: q.trim().length >= 2 ? q.trim() : '',
		searchLocalCount: 0,
		searchRemoteCount: 0
	};
};

// Admin action: trigger a full catalogue scrape (refreshes ranking + library).
export const actions: Actions = {
	refresh: async ({ locals, fetch }) => {
		if (!locals.user || locals.user.role !== 'admin') {
			throw error(403, 'Forbidden');
		}
		try {
			const res = await fetch('/api/scrape', {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({})
			});
			if (res.status === 409) return { status: 'busy' };
			if (!res.ok) return { status: 'error' };
			return { status: 'queued' };
		} catch {
			return { status: 'error' };
		}
	}
};
