import { executeFetchInput } from '../../tools/fetch/index.js';
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils/error-display';
export function resolveDomain(url) {
    try {
        return new URL(url).hostname;
    }
    catch {
        return undefined;
    }
}
export function trimSnippet(value, limit = 320) {
    if (typeof value !== 'string')
        return undefined;
    const normalized = value.replace(/\s+/g, ' ').trim();
    if (!normalized)
        return undefined;
    if (normalized.length <= limit)
        return normalized;
    return `${normalized.slice(0, Math.max(0, limit - 3)).trimEnd()}...`;
}
export function makeEvidence(url, content, metadata = {}, extract = 'summary') {
    if (typeof content !== 'string')
        return undefined;
    const normalized = content.trim();
    if (!normalized)
        return undefined;
    return [{
            url,
            extract,
            content: normalized,
            tokensUsed: Math.ceil(normalized.length / 4),
            metadata,
        }];
}
export function withInlineApiKey(env, envKeys, headerName) {
    if (!envKeys || envKeys.length === 0)
        return undefined;
    for (const key of envKeys) {
        const value = env[key];
        if (typeof value === 'string' && value.trim().length > 0) {
            return {
                type: 'api-key',
                header: headerName,
                key: value.trim(),
            };
        }
    }
    return undefined;
}
export function withInlineBearer(env, envKeys) {
    if (!envKeys || envKeys.length === 0)
        return undefined;
    for (const key of envKeys) {
        const value = env[key];
        if (typeof value === 'string' && value.trim().length > 0) {
            return {
                type: 'bearer',
                token: value.trim(),
            };
        }
    }
    return undefined;
}
export function hasConfiguredCredential(serviceRegistry, env, envKeys, serviceName) {
    const envConfigured = (envKeys ?? []).some((key) => typeof env[key] === 'string' && env[key].trim().length > 0);
    if (envConfigured)
        return true;
    return Boolean(serviceName && serviceRegistry.get(serviceName));
}
export function resolveBaseUrl(serviceRegistry, env, envKeys, serviceName, defaultBaseUrl) {
    for (const key of envKeys ?? []) {
        const value = env[key];
        if (typeof value === 'string' && value.trim().length > 0) {
            return value.trim().replace(/\/+$/, '');
        }
    }
    const configuredService = serviceName ? serviceRegistry.get(serviceName) : null;
    const serviceUrl = configuredService?.baseUrl?.trim();
    if (serviceUrl)
        return serviceUrl.replace(/\/+$/, '');
    return defaultBaseUrl ? defaultBaseUrl.replace(/\/+$/, '') : null;
}
export function buildDescriptor(config, context) {
    const configured = config.requiresAuth === false
        ? resolveBaseUrl(context.serviceRegistry, context.env, config.baseUrlEnvCandidates, config.serviceName, config.defaultBaseUrl) != null
        : hasConfiguredCredential(context.serviceRegistry, context.env, config.envKeyCandidates, config.serviceName);
    return {
        id: config.id,
        label: config.label,
        capabilities: ['search', 'evidence'],
        requiresAuth: config.requiresAuth ?? true,
        configured,
        note: config.note,
    };
}
export async function executeJsonRequest(config) {
    const fetcher = config.fetcher ?? executeFetchInput;
    const urlInput = {
        url: config.url,
        method: config.method ?? 'GET',
        extract: 'json',
        ...(config.params ? { params: config.params } : {}),
        ...(config.headers ? { headers: config.headers } : {}),
        ...(config.body ? { body_type: 'json', body: JSON.stringify(config.body) } : {}),
        ...(config.service ? { service: config.service } : {}),
        ...(config.auth ? { auth: config.auth } : {}),
        ...(config.maxContentLength ? { max_content_length: config.maxContentLength } : {}),
    };
    const output = await fetcher({
        urls: [urlInput],
        parallel: false,
        verbosity: 'standard',
        sanitize_mode: 'safe-text',
        max_content_length: config.maxContentLength ?? 512_000,
    });
    const response = output.results?.[0];
    if (!response || response.error || typeof response.content !== 'string') {
        throw new Error(response?.error ?? `Search provider request failed for ${config.url}`);
    }
    let payload;
    try {
        payload = JSON.parse(response.content);
    }
    catch (error) {
        throw new Error(`Search provider returned invalid JSON for ${config.url}: ${summarizeError(error)}`);
    }
    return { payload, response };
}
export function resultFromRecord(providerId, rank, record, options = {}) {
    const url = firstString(record, options.urlKeys ?? ['url', 'link', 'id']);
    if (!url)
        return null;
    return {
        rank,
        url,
        ...(firstString(record, options.titleKeys ?? ['title', 'name', 'heading']) ? { title: firstString(record, options.titleKeys ?? ['title', 'name', 'heading']) } : {}),
        ...(trimSnippet(firstString(record, options.snippetKeys ?? ['snippet', 'description', 'content', 'text'])) ? { snippet: trimSnippet(firstString(record, options.snippetKeys ?? ['snippet', 'description', 'content', 'text'])) } : {}),
        ...(firstString(record, options.displayUrlKeys ?? ['displayUrl', 'display_url']) ? { displayUrl: firstString(record, options.displayUrlKeys ?? ['displayUrl', 'display_url']) } : {}),
        ...(resolveDomain(url) ? { domain: resolveDomain(url) } : {}),
        type: 'organic',
        providerId,
        metadata: {
            ...(options.metadata ?? {}),
            ...(options.evidenceKeys
                ? {
                    hasProviderEvidence: options.evidenceKeys.some((key) => typeof record[key] === 'string' && String(record[key]).trim().length > 0),
                }
                : {}),
        },
        ...(providerEvidence(url, record, options.evidenceKeys) ? { evidence: providerEvidence(url, record, options.evidenceKeys) } : {}),
    };
}
export function firstString(record, keys) {
    for (const key of keys) {
        const value = record[key];
        if (typeof value === 'string' && value.trim().length > 0)
            return value.trim();
    }
    return undefined;
}
function providerEvidence(url, record, keys) {
    for (const key of keys ?? []) {
        const value = record[key];
        if (typeof value !== 'string' || value.trim().length === 0)
            continue;
        return makeEvidence(url, value, { providerField: key });
    }
    return undefined;
}
