import { createLogger } from "../utils/logger/index.js";
import { init_logger } from "../utils/logger.js";
import { init_loader, loadConfig } from "../config/loader.js";
//#region src/extensions/marketplace.ts
init_loader();
init_logger();
const log = createLogger("ExtensionMarketplace");
const DEFAULT_STORE_BASE = "https://store.xopc.ai";
const CACHE_TTL_MS = 300 * 1e3;
let cache = null;
let lastStale = null;
/** Resolved xopc-store base (same order as skills marketplace). */
function getExtensionMarketplaceStoreBaseUrl() {
	return normalizeStoreBaseUrl();
}
function emptyRegistry() {
	return {
		version: 1,
		extensions: []
	};
}
function normalizeStoreBaseUrl() {
	const env = process.env.XOPC_SKILLS_STORE_URL?.trim();
	if (env) try {
		return new URL(env).toString().replace(/\/$/, "");
	} catch {}
	try {
		const fromCfg = loadConfig().gateway?.skillsStoreBaseUrl?.trim();
		if (fromCfg) try {
			return new URL(fromCfg).toString().replace(/\/$/, "");
		} catch {}
	} catch {}
	return DEFAULT_STORE_BASE;
}
function titleCaseSlug(slug) {
	return slug.split("-").filter(Boolean).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" ");
}
async function fetchExtensionCatalogFromStore() {
	const listUrl = `${normalizeStoreBaseUrl()}/api/v1/packages?type=extension&pageSize=200`;
	try {
		const res = await fetch(listUrl, { signal: AbortSignal.timeout(2e4) });
		if (!res.ok) {
			log.warn({
				status: res.status,
				url: listUrl
			}, "Store extension catalog request failed");
			return null;
		}
		const raw = await res.json();
		const items = Array.isArray(raw.items) ? raw.items : [];
		const extensions = [];
		for (const it of items) {
			const name = typeof it.name === "string" ? it.name.trim() : "";
			if (!name) continue;
			const author = it.author?.username ?? void 0;
			extensions.push({
				id: name,
				name: titleCaseSlug(name),
				description: typeof it.description === "string" ? it.description : void 0,
				npmPackage: name,
				version: typeof it.latestVersion === "string" ? it.latestVersion : void 0,
				author,
				verified: author === "xopcai"
			});
		}
		return extensions.length > 0 ? extensions : null;
	} catch (err) {
		log.warn({
			err,
			url: listUrl
		}, "Store extension catalog fetch failed");
		return null;
	}
}
async function fetchRegistry(forceRefresh = false) {
	const now = Date.now();
	if (!forceRefresh && cache && now - cache.at < CACHE_TTL_MS) return cache.data;
	const storeBase = normalizeStoreBaseUrl();
	const fromStore = await fetchExtensionCatalogFromStore();
	if (fromStore && fromStore.length > 0) {
		const data = {
			version: 1,
			extensions: fromStore
		};
		lastStale = data;
		cache = {
			at: now,
			data
		};
		log.debug({
			count: fromStore.length,
			storeBase
		}, "Loaded extension catalog from xopc-store");
		return data;
	}
	log.warn({ storeBase }, "Extension catalog from xopc-store was empty or unreachable");
	if (lastStale) return lastStale;
	return emptyRegistry();
}
function matchesKeyword(entry, keyword) {
	const k = keyword.toLowerCase();
	return [
		entry.id,
		entry.name,
		entry.description ?? "",
		...entry.categories ?? [],
		...entry.tags ?? [],
		entry.npmPackage
	].join(" ").toLowerCase().includes(k);
}
async function searchExtensions(keyword) {
	const reg = await fetchRegistry();
	const k = keyword.trim();
	if (!k) return reg.extensions;
	return reg.extensions.filter((e) => matchesKeyword(e, k));
}
async function findExtension(id) {
	return (await fetchRegistry()).extensions.find((e) => e.id === id);
}
async function listExtensions(category) {
	const reg = await fetchRegistry();
	if (!category?.trim()) return reg.extensions;
	const c = category.trim().toLowerCase();
	return reg.extensions.filter((e) => (e.categories ?? []).some((x) => x.toLowerCase() === c));
}
//#endregion
export { fetchRegistry, findExtension, getExtensionMarketplaceStoreBaseUrl, listExtensions, searchExtensions };

//# sourceMappingURL=marketplace.js.map