import { ApiError } from "@/lib/api/errors";
import { createQsirchProvider } from "@/lib/search/providers/qsirch";
import { createFsProvider } from "@/lib/search/providers/fs";

/**
 * Provider selection.
 *
 * We keep provider selection in one place:
 * - SEARCH_PROVIDER=qsirch | fs
 *
 * This allows:
 * - local dev: fs fallback
 * - production: qsirch (fast, indexed)
 */

let cachedProvider = null;

function normalizeProviderName(value) {
	return String(value || "")
		.trim()
		.toLowerCase();
}

function normalizeLower(value, fallback) {
	const raw = String(value ?? "").trim();
	return raw ? raw.toLowerCase() : fallback;
}

function normalizeTrim(value, fallback) {
	const raw = String(value ?? "").trim();
	return raw ? raw : fallback;
}

export function getSearchProvider() {
	if (cachedProvider) return cachedProvider;

	const providerName = normalizeProviderName(
		process.env.SEARCH_PROVIDER || "fs"
	);

	if (providerName === "fs") {
		cachedProvider = createFsProvider();
		return cachedProvider;
	}

	if (providerName === "qsirch") {
		// Important: normalize runtime env values so behavior matches validateEnv().
		// - validateEnv() accepts values case-insensitively.
		// - runtime must not accidentally pass "Modified"/"ASYNC" etc. to the provider.
		cachedProvider = createQsirchProvider({
			baseUrl: process.env.QSIRCH_BASE_URL,
			account: process.env.QSIRCH_ACCOUNT,
			password: process.env.QSIRCH_PASSWORD,
			pathPrefix: normalizeTrim(
				process.env.QSIRCH_PATH_PREFIX,
				"/Niederlassungen"
			),
			dateField: normalizeLower(process.env.QSIRCH_DATE_FIELD, "modified"),
			mode: normalizeLower(process.env.QSIRCH_MODE, "sync"),
		});

		return cachedProvider;
	}

	throw new ApiError({
		status: 500,
		code: "SEARCH_BACKEND_UNAVAILABLE",
		message: "Internal server error",
	});
}

/**
 * Unified search entrypoint used by route handlers.
 *
 * @param {{
 *   mode: "branch"|"multi"|"all",
 *   branches: string[]|null,
 *   q: string|null,
 *   from: string|null,
 *   to: string|null,
 *   limit: number,
 *   cursor: string|null
 * }} input
 */
export async function search(input) {
	const provider = getSearchProvider();
	return provider.search(input);
}
