<?php
/**
 * Модуль exit-banner — угловой exit-intent баннер "Уже уходите?" в стиле
 * glassmorphism (белый полупрозрачный фон + backdrop-filter blur).
 *
 * Настройки задаются индивидуально для каждого сайта через панель
 * управления и приходят сюда в $ap_module_config (см. /ap_system/inc.php —
 * читает config_schema из module.json + переопределения из
 * _state/module_config/).
 *
 * Новое в 1.1.0:
 *  - time_from / time_to — окно показа по времени (формат "ЧЧ:ММ").
 *    Проверяется по времени PHP на сервере САЙТА (не по времени браузера
 *    посетителя — иначе окно "плавало" бы в зависимости от часового пояса
 *    каждого конкретного посетителя). Любое из полей пустое — без
 *    ограничения по времени. Поддерживается диапазон через полночь
 *    (например, 22:00–06:00).
 *  - goal_show / goal_click — произвольный JS-код (например, вызов
 *    Яндекс.Метрики ym(...,'reachGoal',...)), выполняется при показе
 *    баннера и при клике по кнопке соответственно. Обёрнут в try/catch
 *    на стороне banner.js — ошибка в этом коде не сломает сам баннер.
 *  - btn_css — произвольные CSS-декларации для кнопки баннера (то, что
 *    обычно пишут внутри "селектор { ... }") — только содержимое между
 *    фигурными скобками, без самого селектора.
 *
 * Новое в 1.2.0:
 *  - show_limit — сколько раз за сессию посетителя можно показать баннер
 *    (по умолчанию 1). Счётчик показов хранится в sessionStorage на
 *    стороне браузера, логика — в banner.js.
 *  - клик по кнопке баннера теперь сразу закрывает сам баннер (не только
 *    триггерит существующий попап/звонок).
 */

$cfg = isset($ap_module_config) && is_array($ap_module_config) ? $ap_module_config : array();

/**
 * Проверяет, попадает ли текущее время сервера в заданный диапазон
 * "ЧЧ:ММ"–"ЧЧ:ММ". Пустые/некорректные значения = "без ограничения".
 * Поддерживает диапазоны через полночь (from > to).
 */
function ap_exit_banner_in_time_window($from, $to)
{
    $from = trim((string)$from);
    $to = trim((string)$to);
    if ($from === '' || $to === '') {
        return true;
    }

    $timeRe = '/^([01]\d|2[0-3]):([0-5]\d)$/';
    if (!preg_match($timeRe, $from) || !preg_match($timeRe, $to)) {
        // Некорректный формат в настройках — не блокируем показ баннера
        // из-за опечатки администратора, просто игнорируем ограничение.
        return true;
    }

    $now = date('H:i');
    if ($from <= $to) {
        return ($now >= $from && $now <= $to);
    }
    // Диапазон через полночь, например 22:00–06:00.
    return ($now >= $from || $now <= $to);
}

$timeFrom = isset($cfg['time_from']) ? $cfg['time_from'] : '';
$timeTo = isset($cfg['time_to']) ? $cfg['time_to'] : '';

if (!ap_exit_banner_in_time_window($timeFrom, $timeTo)) {
    // Вне окна показа — ничего не выводим на этой загрузке страницы.
    return;
}

$title = (isset($cfg['title']) && $cfg['title'] !== '') ? $cfg['title'] : 'Уже уходите?';
$text = isset($cfg['text']) ? $cfg['text'] : '';
$phone = isset($cfg['phone']) ? $cfg['phone'] : '';
$buttonText = (isset($cfg['button_text']) && $cfg['button_text'] !== '') ? $cfg['button_text'] : 'Перезвонить?';
$popupSelector = isset($cfg['popup_selector']) ? $cfg['popup_selector'] : '';
$bgColor = (isset($cfg['bg_color']) && $cfg['bg_color'] !== '') ? $cfg['bg_color'] : 'rgba(255,255,255,0.55)';
$goalShow = isset($cfg['goal_show']) ? trim($cfg['goal_show']) : '';
$goalClick = isset($cfg['goal_click']) ? trim($cfg['goal_click']) : '';
$btnCss = isset($cfg['btn_css']) ? trim($cfg['btn_css']) : '';

$showLimit = isset($cfg['show_limit']) ? (int)$cfg['show_limit'] : 1;
if ($showLimit < 1) {
    $showLimit = 1;
}

// Не даём вставленному коду/CSS разорвать окружающий <script>/<style> тег,
// даже если админ случайно вставит в поле что-то вроде "</script>".
$goalShowSafe = str_replace('</script', '<\/script', $goalShow);
$goalClickSafe = str_replace('</script', '<\/script', $goalClick);
$btnCssSafe = str_replace('</style', '<\/style', $btnCss);

$version = trim(@file_get_contents(__DIR__ . '/version.txt'));
$cssPath = '/ap_system/modules/exit-banner/banner.css';
$jsPath  = '/ap_system/modules/exit-banner/banner.js';
?>
<link rel="stylesheet" href="<?php echo htmlspecialchars($cssPath); ?>?v=<?php echo urlencode($version); ?>">
<?php if ($btnCssSafe !== ''): ?>
<style>
/* Более специфичный селектор (#id .class), чем базовый в banner.css —
   гарантированно переопределяет дефолтный стиль кнопки. */
#ap-exit-banner .ap-exit-banner__btn {
<?php echo $btnCssSafe; ?>

}
</style>
<?php endif; ?>
<div id="ap-exit-banner" class="ap-exit-banner" style="--ap-exit-bg: <?php echo htmlspecialchars($bgColor, ENT_QUOTES); ?>;" data-popup-selector="<?php echo htmlspecialchars($popupSelector, ENT_QUOTES); ?>" data-show-limit="<?php echo (int)$showLimit; ?>">
    <button type="button" class="ap-exit-banner__close" aria-label="Закрыть">&times;</button>
    <div class="ap-exit-banner__title"><?php echo htmlspecialchars($title); ?></div>
    <?php if ($text !== ''): ?>
        <div class="ap-exit-banner__text"><?php echo nl2br(htmlspecialchars($text)); ?></div>
    <?php endif; ?>
    <?php if ($phone !== ''): ?>
        <div class="ap-exit-banner__phone"><?php echo htmlspecialchars($phone); ?></div>
    <?php endif; ?>
    <button type="button" class="ap-exit-banner__btn" id="ap-exit-banner__callback"><?php echo htmlspecialchars($buttonText); ?></button>
</div>
<script>
window.__apExitBannerGoals = window.__apExitBannerGoals || {};
window.__apExitBannerGoals.onShow = function () {
<?php echo $goalShowSafe; ?>

};
window.__apExitBannerGoals.onClick = function () {
<?php echo $goalClickSafe; ?>

};
</script>
<script src="<?php echo htmlspecialchars($jsPath); ?>?v=<?php echo urlencode($version); ?>" defer></script>
