/**
 * Backend API helper.
 *
 * Centralises the BACKEND_URL constant and provides a thin fetch wrapper that:
 *   - Resolves paths relative to BACKEND_API_URL.
 *   - Throws 502 on network errors (unreachable backend).
 *   - Re-throws SvelteKit `error()` objects so callers can still short-circuit.
 *   - Passes a RequestInit through verbatim so callers keep full control.
 *
 * Import only from server-side modules (`+server.ts`, `*.server.ts`).
 */

import { error } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import * as cache from '$lib/server/cache';

export const BACKEND_URL = env.BACKEND_API_URL ?? 'http://localhost:8080';

/**
 * Fetch a path on the backend, throwing a 502 on network failures.
 *
 * The `path` must start with `/` (e.g. `/api/voices`).
 *
 * SvelteKit `error()` exceptions are always re-thrown so callers can
 * short-circuit correctly inside their own catch blocks.
 */
export async function backendFetch(path: string, init?: RequestInit): Promise<Response> {
	try {
		return await fetch(`${BACKEND_URL}${path}`, init);
	} catch (e) {
		// Re-throw SvelteKit HTTP errors so they propagate to the framework.
		if (e instanceof Error && 'status' in e) throw e;
		throw error(502, 'Could not reach backend');
	}
}

// ─── Cached admin model lists ─────────────────────────────────────────────────

const MODELS_CACHE_TTL = 10 * 60; // 10 minutes — model lists rarely change

/**
 * Fetch image-gen model list from the Go backend with a 10-minute cache.
 * Returns an empty array on error (callers should surface a warning).
 */
export async function listImageModels<T>(): Promise<T[]> {
	const key = 'backend:models:image-gen';
	const cached = await cache.get<T[]>(key);
	if (cached) return cached;
	try {
		const res = await backendFetch('/api/admin/image-gen/models');
		if (!res.ok) return [];
		const data = await res.json();
		const models = (data.models ?? []) as T[];
		await cache.set(key, models, MODELS_CACHE_TTL);
		return models;
	} catch {
		return [];
	}
}

/**
 * Fetch text-gen model list from the Go backend with a 10-minute cache.
 * Returns an empty array on error.
 */
export async function listTextModels<T>(): Promise<T[]> {
	const key = 'backend:models:text-gen';
	const cached = await cache.get<T[]>(key);
	if (cached) return cached;
	try {
		const res = await backendFetch('/api/admin/text-gen/models');
		if (!res.ok) return [];
		const data = await res.json();
		const models = (data.models ?? []) as T[];
		await cache.set(key, models, MODELS_CACHE_TTL);
		return models;
	} catch {
		return [];
	}
}

// ─── Response types ───────────────────────────────────────────────────────────

/**
 * Metadata shape returned inside the 200 response from GET /api/book-preview/{slug}.
 * Used in both the SSR page load and the API proxy to avoid duplicating the inline type.
 */
export interface BookPreviewMeta {
	slug: string;
	title: string;
	author: string;
	cover: string;
	status: string;
	genres: string[];
	summary: string;
	total_chapters: number;
	source_url: string;
}

/** Full 200 response from GET /api/book-preview/{slug}. */
export interface BookPreviewResponse {
	in_lib: boolean;
	meta: BookPreviewMeta;
	chapters: { number: number; title: string; date?: string }[];
}

