/**
 * Hybrid brand-voice fixer — deterministic rule fixes first, optional AI rewrite
 * for remaining alignment issues.
 */
import { scoreBrandAlignment, } from './brand-voice-structured.js';
const EMOJI_RE = /[\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}]/gu;
/** Apply safe, deterministic fixes from structured rules (no LLM). */
export function applyDeterministicBrandFixes(content, structured, channelId) {
    let text = content;
    const fixes = [];
    for (const banned of structured.bannedTerms) {
        const term = banned.term.trim();
        if (!term)
            continue;
        const re = new RegExp(`\\b${escapeRegExp(term)}\\b`, 'gi');
        if (!re.test(text))
            continue;
        const replacement = banned.useInstead.trim() || '';
        text = text.replace(re, (match) => {
            if (!replacement)
                return '';
            if (match === match.toUpperCase())
                return replacement.toUpperCase();
            if (match[0] === match[0]?.toUpperCase()) {
                return replacement.charAt(0).toUpperCase() + replacement.slice(1);
            }
            return replacement;
        });
        fixes.push(replacement
            ? `Replaced banned term "${term}" with "${replacement}".`
            : `Removed banned term "${term}".`);
    }
    if (structured.mechanics.exclamationPoints === 'forbid' && text.includes('!')) {
        text = text.replace(/!+/g, '.');
        fixes.push('Removed exclamation points.');
    }
    if (structured.mechanics.emoji === 'forbid' && EMOJI_RE.test(text)) {
        text = text.replace(EMOJI_RE, '').replace(/\s{2,}/g, ' ');
        fixes.push('Removed emoji.');
    }
    const channelRule = channelId ? structured.channels.find((c) => c.id === channelId) : undefined;
    const limit = channelRule?.maxChars ?? channelRule?.maxDescriptionChars;
    if (typeof limit === 'number' && text.length > limit) {
        text = text.slice(0, limit).trimEnd();
        fixes.push(`Trimmed to ${limit} characters for ${channelRule.label}.`);
    }
    return { text: text.trim(), fixes };
}
function escapeRegExp(value) {
    return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
export function buildBrandVoiceFixPrompt(content, issues, structured) {
    const issueLines = issues
        .slice(0, 12)
        .map((i) => `- ${i.message}${i.suggestion ? ` → ${i.suggestion}` : ''}`)
        .join('\n');
    const preferred = structured.preferredTerms.length > 0
        ? `Preferred terms: ${structured.preferredTerms.slice(0, 12).join(', ')}`
        : '';
    return {
        system: 'You are a brand voice editor. Rewrite the supplied copy so it matches the brand ' +
            'voice rules. Preserve the original meaning and approximate length unless a channel ' +
            'character limit requires shortening. Return only the revised copy — no quotes, ' +
            'no preamble, no markdown.',
        prompt: [
            'Fix this copy to resolve the alignment issues below.',
            preferred,
            '',
            'Issues:',
            issueLines || '- General off-brand tone or vocabulary.',
            '',
            'Copy to fix:',
            `<<<COPY\n${content.slice(0, 4000)}\n>>>`,
        ]
            .filter(Boolean)
            .join('\n'),
    };
}
export function needsAiBrandFix(score) {
    if (score.score >= 90)
        return false;
    return score.issues.some((i) => i.severity === 'error' || i.severity === 'warning');
}
/** Score before/after deterministic fixes; caller runs AI when `needsAiBrandFix`. */
export function runDeterministicBrandFix(content, structured, channel) {
    const beforeScore = scoreBrandAlignment(content, structured, channel);
    const { text, fixes } = applyDeterministicBrandFixes(content, structured, channel);
    const afterScore = scoreBrandAlignment(text, structured, channel);
    return {
        text,
        deterministicFixes: fixes,
        beforeScore,
        afterScore,
        usedAi: false,
    };
}
//# sourceMappingURL=brand-voice-fix.js.map