const HTML_ESCAPE_MAP = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;',
};
function escapeHtml(str) {
    return str.replace(/[&<>"']/g, (ch) => HTML_ESCAPE_MAP[ch]);
}
export function generateMetaTags(input) {
    const tags = {};
    const ogTitle = input.ogTitle ?? input.title;
    const ogDescription = input.ogDescription ?? input.description;
    const twTitle = input.twitterTitle ?? ogTitle;
    const twDescription = input.twitterDescription ?? ogDescription;
    const twImage = input.twitterImage ?? input.ogImage?.url;
    tags['og:title'] = ogTitle;
    if (ogDescription)
        tags['og:description'] = ogDescription;
    tags['og:url'] = input.url;
    tags['og:site_name'] = input.siteName;
    tags['og:locale'] = input.locale ?? 'en_US';
    tags['og:type'] = input.type ?? 'website';
    if (input.ogImage) {
        tags['og:image'] = input.ogImage.url;
        if (input.ogImage.width != null)
            tags['og:image:width'] = String(input.ogImage.width);
        if (input.ogImage.height != null)
            tags['og:image:height'] = String(input.ogImage.height);
        if (input.ogImage.alt)
            tags['og:image:alt'] = input.ogImage.alt;
    }
    if (input.type === 'article') {
        if (input.publishedTime)
            tags['article:published_time'] = input.publishedTime;
        if (input.modifiedTime)
            tags['article:modified_time'] = input.modifiedTime;
        if (input.author)
            tags['article:author'] = input.author;
        if (input.section)
            tags['article:section'] = input.section;
        if (input.tags) {
            for (const tag of input.tags) {
                tags['article:tag'] = tag;
            }
        }
    }
    const hasImage = !!(twImage || input.ogImage);
    tags['twitter:card'] = input.twitterCard ?? (hasImage ? 'summary_large_image' : 'summary');
    tags['twitter:title'] = twTitle;
    if (twDescription)
        tags['twitter:description'] = twDescription;
    if (twImage)
        tags['twitter:image'] = twImage;
    if (input.twitterSite)
        tags['twitter:site'] = input.twitterSite;
    const robotsParts = [];
    if (input.noIndex)
        robotsParts.push('noindex');
    if (input.noFollow)
        robotsParts.push('nofollow');
    if (robotsParts.length > 0)
        tags['robots'] = robotsParts.join(', ');
    return tags;
}
const OG_PROPERTY_PREFIXES = ['og:', 'article:'];
function isPropertyTag(key) {
    return OG_PROPERTY_PREFIXES.some((prefix) => key.startsWith(prefix));
}
export function renderMetaTagsHtml(input) {
    const tags = generateMetaTags(input);
    const lines = [];
    if (input.canonical) {
        lines.push(`<link rel="canonical" href="${escapeHtml(input.canonical)}" />`);
    }
    for (const [key, value] of Object.entries(tags)) {
        const escaped = escapeHtml(value);
        if (isPropertyTag(key)) {
            lines.push(`<meta property="${key}" content="${escaped}" />`);
        }
        else {
            lines.push(`<meta name="${key}" content="${escaped}" />`);
        }
    }
    // article:tag can have multiple values — generateMetaTags only stores the last one.
    // Re-emit all tags for the article:tag case.
    if (input.type === 'article' && input.tags && input.tags.length > 1) {
        for (let i = 0; i < input.tags.length - 1; i++) {
            lines.push(`<meta property="article:tag" content="${escapeHtml(input.tags[i])}" />`);
        }
    }
    return lines.join('\n');
}
function cleanToken(v) {
    return typeof v === 'string' && v.trim() !== '' ? v.trim() : undefined;
}
/** Standard provider → meta-tag-name mapping. */
const VERIFICATION_TAG_NAMES = {
    googleSearchConsole: 'google-site-verification',
    bingWebmasterTools: 'msvalidate.01',
    yandex: 'yandex-verification',
    pinterest: 'p:domain_verify',
    facebookDomain: 'facebook-domain-verification',
};
/**
 * Build the flat list of verification `<meta>` entries from the configured
 * tokens. Empty values are skipped. Custom tags require a `content` plus at
 * least one of `name`/`property`.
 */
export function buildVerificationMetaEntries(tokens) {
    if (!tokens)
        return [];
    const entries = [];
    for (const [key, metaName] of Object.entries(VERIFICATION_TAG_NAMES)) {
        const content = cleanToken(tokens[key]);
        if (content)
            entries.push({ name: metaName, content });
    }
    for (const tag of tokens.customMetaTags ?? []) {
        const content = cleanToken(tag?.content);
        const name = cleanToken(tag?.name);
        const property = cleanToken(tag?.property);
        if (!content || (!name && !property))
            continue;
        entries.push(property ? { property, content } : { name: name, content });
    }
    return entries;
}
/** Render verification entries as escaped `<meta>` HTML lines. */
export function renderVerificationMetaHtml(tokens) {
    return buildVerificationMetaEntries(tokens)
        .map((e) => e.property
        ? `<meta property="${escapeHtml(e.property)}" content="${escapeHtml(e.content)}" />`
        : `<meta name="${escapeHtml(e.name)}" content="${escapeHtml(e.content)}" />`)
        .join('\n');
}
/**
 * Build the Next.js `metadata.verification` object. Google + Yandex map to
 * first-class keys; everything else (Bing, Pinterest, Facebook, custom
 * name-based tags) goes under `other`. Returns undefined when nothing is set.
 */
export function buildNextVerification(tokens) {
    if (!tokens)
        return undefined;
    const out = {};
    const other = {};
    const google = cleanToken(tokens.googleSearchConsole);
    if (google)
        out.google = google;
    const yandex = cleanToken(tokens.yandex);
    if (yandex)
        out.yandex = yandex;
    const bing = cleanToken(tokens.bingWebmasterTools);
    if (bing)
        other['msvalidate.01'] = bing;
    const pinterest = cleanToken(tokens.pinterest);
    if (pinterest)
        other['p:domain_verify'] = pinterest;
    const facebook = cleanToken(tokens.facebookDomain);
    if (facebook)
        other['facebook-domain-verification'] = facebook;
    for (const tag of tokens.customMetaTags ?? []) {
        const content = cleanToken(tag?.content);
        const name = cleanToken(tag?.name);
        if (content && name)
            other[name] = content;
    }
    if (Object.keys(other).length > 0)
        out.other = other;
    return out.google || out.yandex || out.other ? out : undefined;
}
export function generateNextMetadata(input) {
    const ogTitle = input.ogTitle ?? input.title;
    const ogDescription = input.ogDescription ?? input.description;
    const twTitle = input.twitterTitle ?? ogTitle;
    const twDescription = input.twitterDescription ?? ogDescription;
    const twImage = input.twitterImage ?? input.ogImage?.url;
    const hasImage = !!(twImage || input.ogImage);
    const metadata = {
        title: input.title,
    };
    if (input.description)
        metadata.description = input.description;
    if (input.canonical) {
        metadata.alternates = { canonical: input.canonical };
    }
    metadata.robots = {
        index: !input.noIndex,
        follow: !input.noFollow,
    };
    const openGraph = {
        title: ogTitle,
        url: input.url,
        siteName: input.siteName,
        locale: input.locale ?? 'en_US',
        type: input.type ?? 'website',
    };
    if (ogDescription)
        openGraph.description = ogDescription;
    if (input.ogImage) {
        openGraph.images = [
            {
                url: input.ogImage.url,
                ...(input.ogImage.width != null && { width: input.ogImage.width }),
                ...(input.ogImage.height != null && { height: input.ogImage.height }),
                ...(input.ogImage.alt && { alt: input.ogImage.alt }),
            },
        ];
    }
    if (input.type === 'article') {
        if (input.publishedTime)
            openGraph.publishedTime = input.publishedTime;
        if (input.modifiedTime)
            openGraph.modifiedTime = input.modifiedTime;
        if (input.author)
            openGraph.authors = [input.author];
        if (input.section)
            openGraph.section = input.section;
        if (input.tags)
            openGraph.tags = input.tags;
    }
    metadata.openGraph = openGraph;
    const twitter = {
        card: input.twitterCard ?? (hasImage ? 'summary_large_image' : 'summary'),
        title: twTitle,
    };
    if (twDescription)
        twitter.description = twDescription;
    if (twImage)
        twitter.images = [twImage];
    if (input.twitterSite)
        twitter.site = input.twitterSite;
    metadata.twitter = twitter;
    return metadata;
}
//# sourceMappingURL=meta-tags.js.map