(function () {
const ns = (window.CabinetExpert = window.CabinetExpert || {});
ns.formatExpertReview = function formatExpertReview(text, mode = "short") {
const cleaned = window.stripTags ? window.stripTags(text) : String(text || "").trim();
if (!cleaned) {
return `
Экспертный разбор пока не готов. Как только появится достаточно данных, здесь будет короткое и понятное объяснение главной ситуации по кампании.
`;
}
const normalized = cleaned
.replace(/\u2022/g, "•")
.replace(/[ \t]+\n/g, "\n")
.replace(/\n{2,}/g, "\n")
.trim();
const lines = normalized.split("\n").map((item) => item.trim()).filter(Boolean);
const fullText = lines.join(" ");
const findLine = (pattern) => lines.find((line) => pattern.test(line)) || "";
const rawStatus = findLine(/сейчас:/i);
const rawSummary = findLine(/итог простыми словами:/i);
const rawNumbers = findLine(/основные цифры/i);
const rawProblems = findLine(/главные проблемы/i);
const rawGrowth = findLine(/точки роста/i);
const rawQuickWins = findLine(/быстрые победы/i);
const rawReason = findLine(/разбор основан/i);
const extractAfterColon = (value) => {
const source = String(value || "").trim();
if (!source) return "";
const parts = source.split(/:\s+/);
return parts.length > 1 ? parts.slice(1).join(": ").trim() : source;
};
const escapeHtml = window.escapeHtml || ((value) => String(value || ""));
const statusText = rawStatus
? rawStatus
.replace(/^.*?Сейчас:/i, "Сейчас:")
.replace(/\s+Проверка Яндекса:/i, " • Проверка Яндекса:")
.trim()
: "Сейчас нет достаточно данных, чтобы уверенно оценить состояние кампании.";
const summaryText = rawSummary
? extractAfterColon(rawSummary)
: "Пока мы видим только базовую картину по рекламе. Ниже собраны вывод и следующий понятный шаг.";
const numbersText = rawNumbers
? rawNumbers.replace(/^Основные цифры[^:]*:\s*/i, "").trim()
: "";
const problemsText = rawProblems
? rawProblems.replace(/^.*?главные проблемы\s*/i, "").trim()
: "";
const growthText = rawGrowth
? rawGrowth.replace(/^.*?точки роста\s*/i, "").trim()
: "";
const quickWinsText = rawQuickWins
? rawQuickWins.replace(/^.*?быстрые победы\s*/i, "").trim()
: "";
const reasonText = rawReason
? rawReason.replace(/^Разбор основан/i, "Этот вывод сделан").trim()
: "Этот вывод сделан по данным рекламы: показы, клики, расход, CTR и средняя цена клика. Для оценки прибыли нужно дополнительно учитывать заявки и продажи.";
let severity = "Стабильно";
let severityClass = "bg-green-500/15 text-green-300 border-green-500/20";
if (/останов|критич|не получает новые показы|не получает новые клики/i.test(fullText)) {
severity = "Критично";
severityClass = "bg-red-500/15 text-red-300 border-red-500/20";
} else if (/мало статистики|недостаточно данных|накопить больше данных|пока мало данных/i.test(fullText)) {
severity = "Пока мало данных";
severityClass = "bg-yellow-500/15 text-yellow-300 border-yellow-500/20";
}
const currentSituation = /останов/i.test(fullText)
? "Кампания сейчас остановлена и не получает новые показы."
: /мало статистики|недостаточно данных/i.test(fullText)
? "Кампания уже получает первые данные, но статистики пока недостаточно для уверенных выводов."
: "Кампания получает показы и клики, а текущий поток трафика выглядит рабочим.";
const meaningText = /останов/i.test(fullText)
? "Пока кампания выключена, реклама не приводит новых переходов и не может давать новые обращения."
: /мало статистики|недостаточно данных/i.test(fullText)
? "Сейчас рано делать жёсткие выводы. Лучше следить за первыми сигналами и не спешить с изменениями."
: "Сейчас важнее не ломать рабочий поток, а аккуратно улучшать качество трафика и стоимость результата.";
const actionItems = (() => {
if (/останов/i.test(fullText)) {
return [
"Проверить, должна ли кампания сейчас работать.",
"Если да — включить её и убедиться, что бюджет не ограничивает показы.",
"Проверить, допущены ли объявления к показам.",
];
}
if (/мало статистики|недостаточно данных/i.test(fullText)) {
return [
"Дать кампании накопить больше кликов и расхода.",
"Проверить, идут ли стабильные показы и не слишком ли дорогой клик.",
"Повторить разбор после накопления новой статистики.",
];
}
return [
"Проверить, какие устройства и регионы дают лучший отклик.",
"Посмотреть объявления с лучшим и худшим результатом.",
"Сверить рекламу с заявками или продажами, чтобы оценить бизнес-результат.",
];
})();
const isFullMode = mode === "full";
const attentionTitle = /останов/i.test(fullText)
? "На что обратить внимание"
: /мало статистики|недостаточно данных/i.test(fullText)
? "Что проверить дальше"
: "Что можно улучшить";
const attentionNotes = [problemsText, growthText, quickWinsText]
.filter(Boolean)
.map((item) => item.replace(/\s{2,}/g, " ").trim())
.slice(0, 2);
const primaryGrid = `
Ситуация сейчас
${escapeHtml(currentSituation)}
${escapeHtml(statusText)}
Что это значит
${escapeHtml(meaningText)}
${summaryText ? `
${escapeHtml(summaryText)}
` : ""}
Что сделать первым
${actionItems.map((item, index) => `
${index + 1}
${escapeHtml(item)}
`).join("")}
Почему такой вывод
${escapeHtml(reasonText)}
`;
const fullModeExtras = `
${numbersText ? `
Основные цифры
${escapeHtml(numbersText)}
` : ""}
${attentionNotes.length ? `
${attentionTitle}
${attentionNotes.map((item) => `
${escapeHtml(item)}
`).join("")}
` : ""}
Следующий шаг
${
/останов/i.test(fullText)
? "Сначала верните кампанию в рабочее состояние, а затем через сутки посмотрите, появились ли показы, клики и не выросла ли цена клика."
: /мало статистики|недостаточно данных/i.test(fullText)
? "Дайте кампании накопить статистику и повторите разбор позже, когда будет больше кликов и расхода."
: "Теперь можно углубиться в устройства, регионы, объявления и сверить рекламу с заявками или продажами."
}
`;
return `
${severity}
${isFullMode ? "Подробный разбор простым языком" : "Короткий разбор без рекламного жаргона"}
${primaryGrid}
${isFullMode ? fullModeExtras : ""}
`;
};
})();