<?php
/**
 * Campaign-first admin workspace.
 *
 * @package SwairishXHeaderBarNotificationOffer
 */

if (!defined('ABSPATH')) {
    exit;
}

class SwairishX_Admin {
    private $storage;
    private $registry;
    private $renderer;

    public function __construct(SwairishX_Storage $storage, SwairishX_Registry $registry, SwairishX_Renderer $renderer) {
        $this->storage = $storage;
        $this->registry = $registry;
        $this->renderer = $renderer;
        add_action('admin_menu', array($this, 'menu'));
        add_action('admin_enqueue_scripts', array($this, 'assets'));
        add_filter('admin_body_class', array($this, 'body_class'));
        add_action('admin_post_swairishx_save_campaign', array($this, 'save_campaign'));
        add_action('admin_post_swairishx_set_campaign_status', array($this, 'set_campaign_status'));
        add_action('admin_post_swairishx_duplicate_campaign', array($this, 'duplicate_campaign'));
        add_action('admin_post_swairishx_delete_campaign', array($this, 'delete_campaign'));
        add_action('admin_post_swairishx_save_settings', array($this, 'save_settings'));
    }

    public function menu() {
        $capability = $this->capability();
        add_menu_page(
            __('Swairish Notifications', 'swairish-header-bar-offer-notifications'),
            __('Swairish Notifications', 'swairish-header-bar-offer-notifications'),
            $capability,
            'swairishx',
            array($this, 'dashboard'),
            'dashicons-megaphone',
            58
        );
        add_submenu_page('swairishx', __('Campaigns', 'swairish-header-bar-offer-notifications'), __('Campaigns', 'swairish-header-bar-offer-notifications'), $capability, 'swairishx-campaigns', array($this, 'campaigns'));
        add_submenu_page('swairishx', __('Create notification', 'swairish-header-bar-offer-notifications'), __('Create notification', 'swairish-header-bar-offer-notifications'), $capability, 'swairishx-builder', array($this, 'builder'));
        add_submenu_page('swairishx', __('Integrations', 'swairish-header-bar-offer-notifications'), __('Integrations', 'swairish-header-bar-offer-notifications'), $capability, 'swairishx-integrations', array($this, 'integrations'));
        add_submenu_page('swairishx', __('Settings', 'swairish-header-bar-offer-notifications'), __('Settings', 'swairish-header-bar-offer-notifications'), $capability, 'swairishx-settings', array($this, 'settings'));
    }

    public function assets($hook) {
        if (false === strpos($hook, 'swairishx')) {
            return;
        }
        wp_enqueue_style('swairishx-admin', SWAIRISHX_URL . 'assets/css/admin-v4.css', array(), SWAIRISHX_VERSION);
        wp_enqueue_script('swairishx-admin', SWAIRISHX_URL . 'assets/js/admin-v4.js', array(), SWAIRISHX_VERSION, true);
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing value.
        $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
        if ('swairishx-builder' === $page) {
            wp_enqueue_media();
        }
        wp_localize_script('swairishx-admin', 'SwairishXAdmin', array(
            'deleteConfirm' => __('Move this campaign to the trash?', 'swairish-header-bar-offer-notifications'),
            'publishReady' => __('Ready to publish', 'swairish-header-bar-offer-notifications'),
            'stepLabel' => __('Step', 'swairish-header-bar-offer-notifications'),
            'usePreset' => __('Use preset', 'swairish-header-bar-offer-notifications'),
            'presetApplied' => __('Applied', 'swairish-header-bar-offer-notifications'),
            'chooseImage' => __('Choose offer image', 'swairish-header-bar-offer-notifications'),
            'useImage' => __('Use this image', 'swairish-header-bar-offer-notifications'),
        ));
    }

    public function body_class($classes) {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing value.
        $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
        return 0 === strpos($page, 'swairishx') ? $classes . ' swairishx-screen' : $classes;
    }

    public function dashboard() {
        $campaigns = $this->storage->campaigns(array('publish', 'draft'));
        $report = $this->storage->report(30);
        $totals = $this->report_totals($report);
        $published = count(array_filter($campaigns, function ($campaign) { return 'publish' === $campaign->post_status; }));
        $drafts = count($campaigns) - $published;
        $ctr = $totals['impressions'] ? round(($totals['clicks'] / $totals['impressions']) * 100, 1) : 0;

        $this->shell_start(
            __('Overview', 'swairish-header-bar-offer-notifications'),
            __('See what is live, what visitors noticed, and what needs attention.', 'swairish-header-bar-offer-notifications'),
            __('Create notification', 'swairish-header-bar-offer-notifications'),
            admin_url('admin.php?page=swairishx-builder')
        );
        ?>
        <section class="swx-focus-card">
            <div class="swx-focus-card__copy">
                <span class="swx-eyebrow"><?php esc_html_e('Campaign workspace', 'swairish-header-bar-offer-notifications'); ?></span>
                <h2><?php echo $published ? esc_html__('Your visitor signals are running.', 'swairish-header-bar-offer-notifications') : esc_html__('Turn one useful message into a live signal.', 'swairish-header-bar-offer-notifications'); ?></h2>
                <?php /* translators: %d: Number of live campaigns. */ ?>
                <p><?php echo $published ? esc_html(sprintf(_n('%d campaign is live. Review the signal funnel, then improve the next message.', '%d campaigns are live. Review the signal funnel, then improve the next message.', $published, 'swairish-header-bar-offer-notifications'), $published)) : esc_html__('Choose a notification type, connect its source, write the message, and publish with a live preview.', 'swairish-header-bar-offer-notifications'); ?></p>
                <div class="swx-focus-card__actions">
                    <a class="swx-button swx-button--primary" href="<?php echo esc_url(admin_url('admin.php?page=swairishx-builder')); ?>"><?php esc_html_e('Start a campaign', 'swairish-header-bar-offer-notifications'); ?><?php $this->print_icon('arrow'); ?></a>
                    <a class="swx-text-link" href="<?php echo esc_url(admin_url('admin.php?page=swairishx-integrations')); ?>"><?php esc_html_e('Check data sources', 'swairish-header-bar-offer-notifications'); ?></a>
                </div>
            </div>
            <div class="swx-signal-funnel" aria-label="<?php esc_attr_e('Last 30 days signal funnel', 'swairish-header-bar-offer-notifications'); ?>">
                <div class="swx-signal-funnel__head"><span><?php esc_html_e('Last 30 days', 'swairish-header-bar-offer-notifications'); ?></span><strong><?php echo esc_html($ctr . '% CTR'); ?></strong></div>
                <div class="swx-signal-line"><span><?php esc_html_e('Seen', 'swairish-header-bar-offer-notifications'); ?></span><i style="--swx-signal:100%"></i><strong><?php echo esc_html(number_format_i18n($totals['impressions'])); ?></strong></div>
                <div class="swx-signal-line"><span><?php esc_html_e('Clicked', 'swairish-header-bar-offer-notifications'); ?></span><i style="--swx-signal:<?php echo esc_attr(max(3, min(100, $ctr))); ?>%"></i><strong><?php echo esc_html(number_format_i18n($totals['clicks'])); ?></strong></div>
                <div class="swx-signal-line"><span><?php esc_html_e('Dismissed', 'swairish-header-bar-offer-notifications'); ?></span><i style="--swx-signal:<?php echo esc_attr($totals['impressions'] ? max(3, min(100, round($totals['dismissals'] / $totals['impressions'] * 100, 1))) : 3); ?>%"></i><strong><?php echo esc_html(number_format_i18n($totals['dismissals'])); ?></strong></div>
            </div>
        </section>

        <section class="swx-stat-strip" aria-label="<?php esc_attr_e('Campaign summary', 'swairish-header-bar-offer-notifications'); ?>">
            <?php $this->metric(__('Live campaigns', 'swairish-header-bar-offer-notifications'), $published, __('Currently visible', 'swairish-header-bar-offer-notifications'), 'live'); ?>
            <?php $this->metric(__('Drafts', 'swairish-header-bar-offer-notifications'), $drafts, __('Waiting for review', 'swairish-header-bar-offer-notifications'), 'draft'); ?>
            <?php $this->metric(__('Impressions', 'swairish-header-bar-offer-notifications'), number_format_i18n($totals['impressions']), __('Last 30 days', 'swairish-header-bar-offer-notifications'), 'eye'); ?>
            <?php $this->metric(__('Clicks', 'swairish-header-bar-offer-notifications'), number_format_i18n($totals['clicks']), __('Last 30 days', 'swairish-header-bar-offer-notifications'), 'click'); ?>
        </section>

        <div class="swx-dashboard-grid">
            <div><?php $this->campaign_list(array_slice($campaigns, 0, 6), false, $report); ?></div>
            <aside class="swx-side-card">
                <div class="swx-card-heading"><div><span class="swx-eyebrow"><?php esc_html_e('Quick start', 'swairish-header-bar-offer-notifications'); ?></span><h2><?php esc_html_e('Launch from a proven format', 'swairish-header-bar-offer-notifications'); ?></h2></div></div>
                <?php $this->quick_start_link('flash_sale', __('Flash sale bar', 'swairish-header-bar-offer-notifications'), __('A bold, high-urgency offer.', 'swairish-header-bar-offer-notifications'), 'sale'); ?>
                <?php $this->quick_start_link('free_shipping', __('Free shipping bar', 'swairish-header-bar-offer-notifications'), __('Make the order threshold clear.', 'swairish-header-bar-offer-notifications'), 'bar'); ?>
                <?php $this->quick_start_link('first_order', __('Welcome discount', 'swairish-header-bar-offer-notifications'), __('Convert first-time visitors.', 'swairish-header-bar-offer-notifications'), 'spark'); ?>
            </aside>
        </div>
        <?php $this->pro_banner(); ?>
        <?php
        $this->shell_end();
    }

    public function campaigns() {
        $campaigns = $this->storage->campaigns(array('publish', 'draft'));
        $this->shell_start(
            __('Campaigns', 'swairish-header-bar-offer-notifications'),
            __('Manage every visitor-facing message from one clear queue.', 'swairish-header-bar-offer-notifications'),
            __('New campaign', 'swairish-header-bar-offer-notifications'),
            admin_url('admin.php?page=swairishx-builder')
        );
        $this->campaign_list($campaigns, true, $this->storage->report(30));
        $this->shell_end();
    }

    public function builder() {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only campaign identifier.
        $id = isset($_GET['campaign']) ? absint($_GET['campaign']) : 0;
        $config = $id ? $this->storage->get_campaign($id) : $this->storage->sanitize_campaign(array());
        $selected_preset = '';
        if (!$config) {
            $config = $this->storage->sanitize_campaign(array());
        }
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only preset selector.
        if (!$id && !empty($_GET['preset'])) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only preset selector.
            $preset = sanitize_key(wp_unslash($_GET['preset']));
            $offer_presets = $this->offer_presets();
            if (isset($offer_presets[$preset])) {
                $config = $this->storage->sanitize_campaign(array_merge($config, $offer_presets[$preset]['config']));
                $selected_preset = $preset;
            } elseif ($this->registry->has('notification', $preset)) {
                $config['type'] = $preset;
                $config['name'] = $this->registry->get('notification', $preset)['label'];
                if ('sales_alert' === $preset) {
                    $config['integration'] = 'woocommerce';
                    $config['headline'] = __('A new customer just ordered', 'swairish-header-bar-offer-notifications');
                    $config['message'] = __('{actor} purchased {subject}.', 'swairish-header-bar-offer-notifications');
                } elseif ('wordpress_review_alert' === $preset) {
                    $config['integration'] = 'wordpress_org';
                    $config['headline'] = __('Trusted by WordPress users', 'swairish-header-bar-offer-notifications');
                } else {
                    $config['headline'] = __('A useful offer for this visit', 'swairish-header-bar-offer-notifications');
                }
            }
        }

        $this->shell_start(
            $id ? __('Edit campaign', 'swairish-header-bar-offer-notifications') : __('Create campaign', 'swairish-header-bar-offer-notifications'),
            $id ? __('Refine the message, audience, or appearance without losing its history.', 'swairish-header-bar-offer-notifications') : __('Four focused steps from source to publish.', 'swairish-header-bar-offer-notifications')
        );
        ?>
        <form class="swx-builder" method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" data-swx-builder>
            <input type="hidden" name="action" value="swairishx_save_campaign">
            <input type="hidden" name="campaign_id" value="<?php echo esc_attr($id); ?>">
            <?php wp_nonce_field('swairishx_save_campaign'); ?>

            <div class="swx-builder__workspace">
                <div class="swx-builder-title">
                    <label for="swx-campaign-name"><?php esc_html_e('Campaign name', 'swairish-header-bar-offer-notifications'); ?></label>
                    <input id="swx-campaign-name" type="text" name="name" value="<?php echo esc_attr($config['name']); ?>" required placeholder="<?php esc_attr_e('e.g. Weekend hosting offer', 'swairish-header-bar-offer-notifications'); ?>">
                    <span class="swx-save-state"><i></i><?php echo 'publish' === $config['status'] ? esc_html__('Live campaign', 'swairish-header-bar-offer-notifications') : esc_html__('Draft campaign', 'swairish-header-bar-offer-notifications'); ?></span>
                </div>

                <nav class="swx-stepnav" aria-label="<?php esc_attr_e('Campaign setup', 'swairish-header-bar-offer-notifications'); ?>">
                    <?php $this->step_button(0, 'source', __('Type & source', 'swairish-header-bar-offer-notifications'), 'source'); ?>
                    <?php $this->step_button(1, 'content', __('Message', 'swairish-header-bar-offer-notifications'), 'message'); ?>
                    <?php $this->step_button(2, 'display', __('Audience', 'swairish-header-bar-offer-notifications'), 'target'); ?>
                    <?php $this->step_button(3, 'appearance', __('Appearance', 'swairish-header-bar-offer-notifications'), 'palette'); ?>
                </nav>

                <div class="swx-builder__panels">
                    <section class="swx-panel is-active" data-swx-panel="source" data-swx-step="0">
                        <?php $this->section_intro(__('Choose what visitors should notice', 'swairish-header-bar-offer-notifications'), __('Start with the outcome. The source determines where dynamic activity comes from.', 'swairish-header-bar-offer-notifications')); ?>
                        <?php $this->offer_preset_picker($selected_preset); ?>
                        <fieldset class="swx-type-picker">
                            <legend><?php esc_html_e('Notification type', 'swairish-header-bar-offer-notifications'); ?></legend>
                            <div class="swx-type-grid">
                                <?php foreach ($this->registry->all('notification') as $type_id => $definition) : ?>
                                    <label class="swx-type-card">
                                        <input type="radio" name="type" value="<?php echo esc_attr($type_id); ?>" <?php checked($config['type'], $type_id); ?>>
                                        <span class="swx-type-card__icon"><?php $this->print_icon($this->type_icon($type_id)); ?></span>
                                        <span><strong><?php echo esc_html($definition['label']); ?></strong><small><?php echo esc_html($this->type_description($type_id)); ?></small></span>
                                    </label>
                                <?php endforeach; ?>
                            </div>
                        </fieldset>
                        <div class="swx-section-card">
                            <div class="swx-section-card__title"><span class="swx-mini-icon"><?php $this->print_icon('plug'); ?></span><div><h3><?php esc_html_e('Content source', 'swairish-header-bar-offer-notifications'); ?></h3><p><?php esc_html_e('Use manual copy or pull activity from a connected WordPress tool.', 'swairish-header-bar-offer-notifications'); ?></p></div></div>
                            <?php $this->select('integration', __('Source', 'swairish-header-bar-offer-notifications'), $config['integration'], $this->registry->all('integration')); ?>
                            <div data-swx-source-identifier>
                                <?php $this->input('source_identifier', __('WordPress.org plugin slug', 'swairish-header-bar-offer-notifications'), $config['source_identifier'], 'text', __('Example: woocommerce. Only required for WordPress.org data.', 'swairish-header-bar-offer-notifications')); ?>
                            </div>
                        </div>
                    </section>

                    <section class="swx-panel" data-swx-panel="content" data-swx-step="1">
                        <?php $this->section_intro(__('Write the message people will act on', 'swairish-header-bar-offer-notifications'), __('Keep the headline specific, the supporting line useful, and the action unambiguous.', 'swairish-header-bar-offer-notifications')); ?>
                        <div class="swx-section-card swx-section-card--fields">
                            <?php $this->input('headline', __('Headline', 'swairish-header-bar-offer-notifications'), $config['headline'], 'text', __('The first line visitors notice.', 'swairish-header-bar-offer-notifications'), __('Weekend hosting offer', 'swairish-header-bar-offer-notifications')); ?>
                            <?php $this->textarea('message', __('Supporting message', 'swairish-header-bar-offer-notifications'), $config['message'], __('Dynamic sources support {actor}, {subject}, and {location}.', 'swairish-header-bar-offer-notifications')); ?>
                            <div class="swx-grid-two">
                                <?php $this->input('cta_label', __('Button label', 'swairish-header-bar-offer-notifications'), $config['cta_label'], 'text', '', __('View offer', 'swairish-header-bar-offer-notifications')); ?>
                                <?php $this->input('cta_url', __('Button URL', 'swairish-header-bar-offer-notifications'), $config['cta_url'], 'url', __('Leave empty when no action is needed.', 'swairish-header-bar-offer-notifications'), 'https://'); ?>
                            </div>
                            <div class="swx-subsection swx-subsection--stacked">
                                <div><h3><?php esc_html_e('Conversion helpers', 'swairish-header-bar-offer-notifications'); ?></h3><p><?php esc_html_e('Add a fixed-deadline timer or a one-click coupon without another plugin.', 'swairish-header-bar-offer-notifications'); ?></p></div>
                                <div class="swx-conversion-fields">
                                    <?php $this->checkbox('show_countdown', __('Show deadline countdown', 'swairish-header-bar-offer-notifications'), __('Counts down to the campaign End date set in Audience.', 'swairish-header-bar-offer-notifications'), $config['show_countdown']); ?>
                                    <div class="swx-grid-two">
                                        <?php $this->input('coupon_code', __('Coupon code', 'swairish-header-bar-offer-notifications'), $config['coupon_code'], 'text', __('Leave empty to hide the copy button.', 'swairish-header-bar-offer-notifications'), 'SAVE20'); ?>
                                        <?php $this->input('coupon_copied_text', __('Copied confirmation', 'swairish-header-bar-offer-notifications'), $config['coupon_copied_text'], 'text', __('Shown briefly after the visitor copies the code.', 'swairish-header-bar-offer-notifications'), __('Copied', 'swairish-header-bar-offer-notifications')); ?>
                                    </div>
                                </div>
                            </div>
                            <?php do_action('swairishx_builder_content_fields', $config); ?>
                            <div class="swx-media-field" data-swx-media-field>
                                <div class="swx-media-field__art<?php echo esc_attr(empty($config['image_url']) ? ' is-empty' : ''); ?>" data-swx-media-art>
                                    <img src="<?php echo esc_url($config['image_url']); ?>" alt="" data-swx-media-thumb <?php if (empty($config['image_url'])) : ?>hidden<?php endif; ?>>
                                    <span data-swx-media-empty><?php $this->print_icon('spark'); ?><small><?php esc_html_e('No image selected', 'swairish-header-bar-offer-notifications'); ?></small></span>
                                </div>
                                <div class="swx-media-field__controls">
                                    <div><strong><?php esc_html_e('Offer image', 'swairish-header-bar-offer-notifications'); ?></strong><small><?php esc_html_e('Use a compact square image. Preset artwork is included and you can replace it from Media Library.', 'swairish-header-bar-offer-notifications'); ?></small></div>
                                    <?php $this->input('image_url', __('Image URL', 'swairish-header-bar-offer-notifications'), $config['image_url'], 'url', __('Paste a direct HTTPS image link, or use Media Library below.', 'swairish-header-bar-offer-notifications'), 'https://example.com/offer-image.jpg'); ?>
                                    <div class="swx-media-field__actions"><button type="button" class="swx-button swx-button--quiet" data-swx-choose-image><?php esc_html_e('Choose or replace', 'swairish-header-bar-offer-notifications'); ?></button><button type="button" class="swx-text-button" data-swx-remove-image <?php if (empty($config['image_url'])) : ?>hidden<?php endif; ?>><?php esc_html_e('Remove', 'swairish-header-bar-offer-notifications'); ?></button></div>
                                    <div class="swx-grid-two">
                                        <?php $this->input('image_alt', __('Image description', 'swairish-header-bar-offer-notifications'), $config['image_alt'], 'text', __('Short alt text for accessibility.', 'swairish-header-bar-offer-notifications'), __('Gift box and shopping bag', 'swairish-header-bar-offer-notifications')); ?>
                                        <?php $this->select('image_position', __('Image position', 'swairish-header-bar-offer-notifications'), $config['image_position'], array('start' => array('label' => __('Before message', 'swairish-header-bar-offer-notifications')), 'end' => array('label' => __('After message', 'swairish-header-bar-offer-notifications')))); ?>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="swx-message-tip"><?php $this->print_icon('spark'); ?><div><strong><?php esc_html_e('Clarity check', 'swairish-header-bar-offer-notifications'); ?></strong><span><?php esc_html_e('Say what happened, why it matters, and what the visitor can do next.', 'swairish-header-bar-offer-notifications'); ?></span></div></div>
                    </section>

                    <section class="swx-panel" data-swx-panel="display" data-swx-step="2">
                        <?php $this->section_intro(__('Decide where and when it appears', 'swairish-header-bar-offer-notifications'), __('Start broad, then add exclusions only when the visitor context requires it.', 'swairish-header-bar-offer-notifications')); ?>
                        <div class="swx-section-card swx-section-card--fields">
                            <div class="swx-grid-two">
                                <?php $this->select('position', __('Display position', 'swairish-header-bar-offer-notifications'), $config['position'], apply_filters('swairishx_position_options', array('top' => array('label' => __('Top of page', 'swairish-header-bar-offer-notifications')), 'bottom' => array('label' => __('Bottom of page', 'swairish-header-bar-offer-notifications'))))); ?>
                                <?php $this->select('reappearance', __('After dismissal', 'swairish-header-bar-offer-notifications'), $config['reappearance'], array('refresh' => array('label' => __('Show again after refresh', 'swairish-header-bar-offer-notifications')), 'session' => array('label' => __('Hide for this browser session', 'swairish-header-bar-offer-notifications')), 'after_hours' => array('label' => __('Show again after a set time', 'swairish-header-bar-offer-notifications')), 'never' => array('label' => __('Do not show again', 'swairish-header-bar-offer-notifications')))); ?>
                            </div>
                            <div data-swx-dismiss-hours><?php $this->input('dismiss_hours', __('Reappear after', 'swairish-header-bar-offer-notifications'), $config['dismiss_hours'], 'number', __('Hours before showing it again. Used only for the timed option.', 'swairish-header-bar-offer-notifications')); ?></div>
                            <div class="swx-subsection"><div><h3><?php esc_html_e('Schedule', 'swairish-header-bar-offer-notifications'); ?></h3><p><?php esc_html_e('Leave dates empty to keep the campaign available continuously.', 'swairish-header-bar-offer-notifications'); ?></p></div><div class="swx-grid-two"><?php $this->input('start_at', __('Starts', 'swairish-header-bar-offer-notifications'), $config['start_at'], 'datetime-local'); ?><?php $this->input('end_at', __('Ends', 'swairish-header-bar-offer-notifications'), $config['end_at'], 'datetime-local'); ?></div></div>
                            <div class="swx-subsection"><div><h3><?php esc_html_e('Timing', 'swairish-header-bar-offer-notifications'); ?></h3><p><?php esc_html_e('Milliseconds. Use 0 for immediate or persistent behavior.', 'swairish-header-bar-offer-notifications'); ?></p></div><div class="swx-grid-two"><?php $this->input('delay_ms', __('Initial delay', 'swairish-header-bar-offer-notifications'), $config['delay_ms'], 'number'); ?><?php $this->input('auto_hide_ms', __('Auto-hide after', 'swairish-header-bar-offer-notifications'), $config['auto_hide_ms'], 'number'); ?></div></div>
                            <details class="swx-disclosure"><summary><?php esc_html_e('Page targeting', 'swairish-header-bar-offer-notifications'); ?><span><?php esc_html_e('Optional', 'swairish-header-bar-offer-notifications'); ?></span></summary><div class="swx-disclosure__body"><?php $this->textarea('include_paths', __('Show only on', 'swairish-header-bar-offer-notifications'), $config['include_paths'], __('One path per line. Use * as a wildcard. Empty means everywhere.', 'swairish-header-bar-offer-notifications')); ?><?php $this->textarea('exclude_paths', __('Never show on', 'swairish-header-bar-offer-notifications'), $config['exclude_paths'], __('One path pattern per line.', 'swairish-header-bar-offer-notifications')); ?></div></details>
                            <?php do_action('swairishx_builder_visibility_fields', $config); ?>
                        </div>
                    </section>

                    <section class="swx-panel" data-swx-panel="appearance" data-swx-step="3">
                        <?php $this->section_intro(__('Make it feel native to your site', 'swairish-header-bar-offer-notifications'), __('Choose a visual foundation, then tune only the colors that carry meaning.', 'swairish-header-bar-offer-notifications')); ?>
                        <div class="swx-section-card swx-section-card--fields">
                            <fieldset class="swx-theme-picker"><legend><?php esc_html_e('Theme', 'swairish-header-bar-offer-notifications'); ?></legend><div class="swx-theme-grid"><?php foreach ($this->registry->all('theme') as $theme_id => $definition) : ?><label class="swx-theme-card swx-theme-card--<?php echo esc_attr($theme_id); ?>"><input type="radio" name="theme" value="<?php echo esc_attr($theme_id); ?>" <?php checked($config['theme'], $theme_id); ?>><span class="swx-theme-swatch"><i></i><b></b></span><strong><?php echo esc_html($definition['label']); ?></strong></label><?php endforeach; ?></div></fieldset>
                            <div class="swx-color-row">
                                <?php $this->color_input('background', __('Background', 'swairish-header-bar-offer-notifications'), $config['background']); ?>
                                <?php $this->color_input('foreground', __('Text', 'swairish-header-bar-offer-notifications'), $config['foreground']); ?>
                                <?php $this->color_input('accent', __('Action', 'swairish-header-bar-offer-notifications'), $config['accent']); ?>
                            </div>
                            <div class="swx-toggle-list">
                                <?php $this->checkbox('sticky', __('Keep visible while scrolling', 'swairish-header-bar-offer-notifications'), __('Useful for short-lived offers and site-wide announcements.', 'swairish-header-bar-offer-notifications'), $config['sticky']); ?>
                                <?php $this->checkbox('close_button', __('Allow visitors to dismiss', 'swairish-header-bar-offer-notifications'), __('The dismissal duration is controlled in Audience.', 'swairish-header-bar-offer-notifications'), $config['close_button']); ?>
                                <?php $this->checkbox('tracking', __('Record local performance', 'swairish-header-bar-offer-notifications'), __('Store impressions, clicks, and dismissals in WordPress.', 'swairish-header-bar-offer-notifications'), $config['tracking']); ?>
                            </div>
                            <details class="swx-disclosure"><summary><?php esc_html_e('Campaign attribution', 'swairish-header-bar-offer-notifications'); ?><span>UTM</span></summary><div class="swx-disclosure__body swx-grid-two"><?php $this->input('utm_source', __('UTM source', 'swairish-header-bar-offer-notifications'), $config['utm_source']); ?><?php $this->input('utm_medium', __('UTM medium', 'swairish-header-bar-offer-notifications'), $config['utm_medium']); ?></div></details>
                            <?php do_action('swairishx_builder_design_fields', $config); ?>
                        </div>
                    </section>
                </div>

                <div class="swx-builder-actions">
                    <div class="swx-builder-actions__progress"><span data-swx-step-status><?php esc_html_e('Step 1 of 4', 'swairish-header-bar-offer-notifications'); ?></span><i><b data-swx-progress></b></i></div>
                    <div class="swx-builder-actions__buttons">
                        <button class="swx-button swx-button--quiet" type="button" data-swx-back disabled><?php $this->print_icon('back'); ?><?php esc_html_e('Back', 'swairish-header-bar-offer-notifications'); ?></button>
                        <button class="swx-button swx-button--primary" type="button" data-swx-next><?php esc_html_e('Continue', 'swairish-header-bar-offer-notifications'); ?><?php $this->print_icon('arrow'); ?></button>
                        <button class="swx-button swx-button--quiet is-final-action" name="status" value="draft" hidden><?php esc_html_e('Save draft', 'swairish-header-bar-offer-notifications'); ?></button>
                        <button class="swx-button swx-button--primary is-final-action" name="status" value="publish" hidden><?php esc_html_e('Publish campaign', 'swairish-header-bar-offer-notifications'); ?><?php $this->print_icon('arrow'); ?></button>
                    </div>
                </div>
            </div>

            <aside class="swx-preview-shell" aria-label="<?php esc_attr_e('Live preview', 'swairish-header-bar-offer-notifications'); ?>">
                <div class="swx-preview-shell__head"><div><span class="swx-live-dot"></span><strong><?php esc_html_e('Live preview', 'swairish-header-bar-offer-notifications'); ?></strong></div><div class="swx-device-switch" role="group" aria-label="<?php esc_attr_e('Preview size', 'swairish-header-bar-offer-notifications'); ?>"><button type="button" class="is-active" data-swx-device="desktop" aria-label="<?php esc_attr_e('Desktop preview', 'swairish-header-bar-offer-notifications'); ?>"><?php $this->print_icon('desktop'); ?></button><button type="button" data-swx-device="mobile" aria-label="<?php esc_attr_e('Mobile preview', 'swairish-header-bar-offer-notifications'); ?>"><?php $this->print_icon('mobile'); ?></button></div></div>
                <div class="swx-preview-stage" data-swx-preview-stage>
                    <div class="swx-preview-browser" data-swx-preview>
                        <div class="swx-preview-browser__chrome"><i></i><i></i><i></i><span>yourwebsite.com</span></div>
                        <div class="swx-preview-site"><div class="swx-preview-site__nav"><b></b><span></span><span></span><span></span></div><div class="swx-preview-site__hero"><i></i><b></b><b></b><span></span></div></div>
                        <div class="swx-preview-notice" data-swx-preview-notice>
                            <span class="swx-preview-notice__mark"><?php $this->print_icon('spark'); ?></span>
                            <img class="swx-preview-notice__image is-<?php echo esc_attr($config['image_position']); ?>" src="<?php echo esc_url($config['image_url']); ?>" alt="" data-swx-preview-image <?php if (empty($config['image_url'])) : ?>hidden<?php endif; ?>>
                            <div><strong data-swx-preview-headline><?php echo esc_html($config['headline'] ?: __('Weekend offer', 'swairish-header-bar-offer-notifications')); ?></strong><span data-swx-preview-message><?php echo esc_html($config['message'] ?: __('Make your announcement clear and useful.', 'swairish-header-bar-offer-notifications')); ?></span></div>
                            <time class="swx-preview-countdown" data-swx-preview-countdown <?php if (empty($config['show_countdown'])) : ?>hidden<?php endif; ?>>23:59:59</time>
                            <button class="swx-preview-coupon" type="button" data-swx-preview-coupon <?php if (empty($config['coupon_code'])) : ?>hidden<?php endif; ?>><?php echo esc_html($config['coupon_code']); ?></button>
                            <button type="button" data-swx-preview-cta><?php echo esc_html($config['cta_label'] ?: __('View offer', 'swairish-header-bar-offer-notifications')); ?></button>
                            <i class="swx-preview-notice__close">×</i>
                        </div>
                    </div>
                </div>
                <div class="swx-preview-summary"><div><span><?php esc_html_e('Type', 'swairish-header-bar-offer-notifications'); ?></span><strong data-swx-preview-type><?php echo esc_html($this->registry->get('notification', $config['type'])['label']); ?></strong></div><div><span><?php esc_html_e('Position', 'swairish-header-bar-offer-notifications'); ?></span><strong data-swx-preview-position><?php echo esc_html(ucfirst($config['position'])); ?></strong></div></div>
            </aside>
        </form>
        <?php
        $this->shell_end();
    }

    public function integrations() {
        $integrations = $this->registry->all('integration');
        $connected = 0;
        foreach ($integrations as $id => $definition) {
            if ('connected' === $this->integration_state($id, $definition)) {
                ++$connected;
            }
        }
        $this->shell_start(
            __('Integrations', 'swairish-header-bar-offer-notifications'),
            __('Connect activity sources, then choose them inside any campaign.', 'swairish-header-bar-offer-notifications')
        );
        ?>
        <div class="swx-integrations-head">
            <div><span class="swx-eyebrow"><?php esc_html_e('Source library', 'swairish-header-bar-offer-notifications'); ?></span><h2><?php
                /* translators: 1: Number of ready sources, 2: Total number of sources. */
                echo esc_html(sprintf(__('%1$d of %2$d sources ready', 'swairish-header-bar-offer-notifications'), $connected, count($integrations)));
            ?></h2><p><?php esc_html_e('Local integrations listen for WordPress events. The optional WordPress.org source runs only after an administrator configures it.', 'swairish-header-bar-offer-notifications'); ?></p></div>
            <label class="swx-search"><?php $this->print_icon('search'); ?><span class="screen-reader-text"><?php esc_html_e('Search integrations', 'swairish-header-bar-offer-notifications'); ?></span><input type="search" placeholder="<?php esc_attr_e('Search sources', 'swairish-header-bar-offer-notifications'); ?>" data-swx-integration-search></label>
        </div>
        <div class="swx-filter-pills" role="group" aria-label="<?php esc_attr_e('Filter integrations', 'swairish-header-bar-offer-notifications'); ?>"><button type="button" class="is-active" data-swx-integration-filter="all"><?php esc_html_e('All', 'swairish-header-bar-offer-notifications'); ?></button><button type="button" data-swx-integration-filter="connected"><?php esc_html_e('Ready', 'swairish-header-bar-offer-notifications'); ?></button><button type="button" data-swx-integration-filter="available"><?php esc_html_e('Available', 'swairish-header-bar-offer-notifications'); ?></button></div>
        <div class="swx-integration-grid" data-swx-integration-grid>
            <?php foreach ($integrations as $id => $definition) : $state = $this->integration_state($id, $definition); ?>
                <article class="swx-integration" data-swx-integration data-state="<?php echo esc_attr($state); ?>" data-name="<?php echo esc_attr(strtolower($definition['label'])); ?>">
                    <span class="swx-integration__mark swx-integration__mark--<?php echo esc_attr($id); ?>"><?php echo esc_html(strtoupper(substr($definition['label'], 0, 2))); ?></span>
                    <div class="swx-integration__copy"><h3><?php echo esc_html($definition['label']); ?></h3><p><?php echo esc_html($this->integration_description($id, $state)); ?></p></div>
                    <span class="swx-connection-state is-<?php echo esc_attr($state); ?>"><i></i><?php echo esc_html($this->state_label($state)); ?></span>
                </article>
            <?php endforeach; ?>
        </div>
        <div class="swx-no-results" data-swx-integration-empty hidden><?php esc_html_e('No sources match this filter.', 'swairish-header-bar-offer-notifications'); ?></div>
        <?php
        $this->shell_end();
    }

    public function settings() {
        $brand = get_option('swairishx_brand_name', 'Swairish Notifications');
        $this->shell_start(
            __('Settings', 'swairish-header-bar-offer-notifications'),
            __('Keep the workspace recognizable and understand exactly where data lives.', 'swairish-header-bar-offer-notifications')
        );
        ?>
        <div class="swx-settings-layout">
            <form class="swx-settings-card" method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                <input type="hidden" name="action" value="swairishx_save_settings">
                <?php wp_nonce_field('swairishx_save_settings'); ?>
                <div class="swx-card-heading"><div><span class="swx-eyebrow"><?php esc_html_e('Workspace', 'swairish-header-bar-offer-notifications'); ?></span><h2><?php esc_html_e('Dashboard identity', 'swairish-header-bar-offer-notifications'); ?></h2><p><?php esc_html_e('Change the name your team sees without changing plugin identity or attribution.', 'swairish-header-bar-offer-notifications'); ?></p></div></div>
                <?php $this->input('brand_name', __('Dashboard name', 'swairish-header-bar-offer-notifications'), $brand, 'text', __('Shown only inside the Swairish Notifications workspace.', 'swairish-header-bar-offer-notifications')); ?>
                <button class="swx-button swx-button--primary"><?php esc_html_e('Save workspace', 'swairish-header-bar-offer-notifications'); ?></button>
            </form>
            <aside class="swx-privacy-card">
                <span class="swx-privacy-card__icon"><?php $this->print_icon('shield'); ?></span>
                <span class="swx-eyebrow"><?php esc_html_e('Privacy-first by default', 'swairish-header-bar-offer-notifications'); ?></span>
                <h2><?php esc_html_e('Your campaign data stays in WordPress.', 'swairish-header-bar-offer-notifications'); ?></h2>
                <p><?php esc_html_e('Raw IP addresses are not stored. Local integrations react to events already happening on this site.', 'swairish-header-bar-offer-notifications'); ?></p>
                <dl><div><dt><?php esc_html_e('Core API', 'swairish-header-bar-offer-notifications'); ?></dt><dd><?php echo esc_html(SWAIRISHX_API_VERSION); ?></dd></div><div><dt><?php esc_html_e('Raw event retention', 'swairish-header-bar-offer-notifications'); ?></dt><dd><?php esc_html_e('90 days', 'swairish-header-bar-offer-notifications'); ?></dd></div><div><dt><?php esc_html_e('Campaign metrics', 'swairish-header-bar-offer-notifications'); ?></dt><dd><?php esc_html_e('730 days', 'swairish-header-bar-offer-notifications'); ?></dd></div></dl>
            </aside>
        </div>
        <div class="swx-settings-extensions"><?php do_action('swairishx_settings_sections'); ?></div>
        <?php
        $this->shell_end();
    }

    public function save_campaign() {
        if (!current_user_can($this->capability())) {
            wp_die(esc_html__('You cannot manage campaigns.', 'swairish-header-bar-offer-notifications'));
        }
        check_admin_referer('swairishx_save_campaign');
        $input = $this->campaign_request_data();
        $id = isset($_POST['campaign_id']) ? absint($_POST['campaign_id']) : 0;
        $saved = $this->storage->save_campaign($input, $id);
        if (is_wp_error($saved)) {
            wp_die(esc_html($saved->get_error_message()));
        }
        wp_safe_redirect(add_query_arg(array('page' => 'swairishx-builder', 'campaign' => $saved, 'updated' => 1), admin_url('admin.php')));
        exit;
    }

    /**
     * Read only supported campaign fields and sanitize them at the request boundary.
     *
     * @return array<string, mixed>
     */
    private function campaign_request_data() {
        $input = array();
        // The caller verifies swairishx_save_campaign immediately before this method runs.
        $request = wp_unslash($_POST); // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Every allowlisted field is sanitized below before use.

        foreach (array('name', 'source_identifier', 'headline', 'cta_label', 'coupon_code', 'coupon_copied_text', 'image_alt', 'utm_source', 'utm_medium') as $field) {
            if (isset($request[$field]) && !is_array($request[$field])) {
                $input[$field] = sanitize_text_field($request[$field]);
            }
        }

        foreach (array('status', 'type', 'integration', 'image_position', 'position', 'theme', 'reappearance') as $field) {
            if (isset($request[$field]) && !is_array($request[$field])) {
                $input[$field] = sanitize_key($request[$field]);
            }
        }

        if (isset($request['message']) && !is_array($request['message'])) {
            $input['message'] = wp_kses_post($request['message']);
        }

        foreach (array('cta_url', 'image_url') as $field) {
            if (isset($request[$field]) && !is_array($request[$field])) {
                $input[$field] = esc_url_raw($request[$field], array('http', 'https'));
            }
        }

        foreach (array('background', 'foreground', 'accent') as $field) {
            if (isset($request[$field]) && !is_array($request[$field])) {
                $input[$field] = sanitize_hex_color($request[$field]);
            }
        }

        foreach (array('dismiss_hours', 'delay_ms', 'auto_hide_ms') as $field) {
            if (isset($request[$field]) && !is_array($request[$field])) {
                $input[$field] = absint($request[$field]);
            }
        }

        foreach (array('start_at', 'end_at') as $field) {
            if (isset($request[$field]) && !is_array($request[$field])) {
                $input[$field] = sanitize_text_field($request[$field]);
            }
        }

        foreach (array('include_paths', 'exclude_paths') as $field) {
            if (isset($request[$field]) && !is_array($request[$field])) {
                $input[$field] = sanitize_textarea_field($request[$field]);
            }
        }

        foreach (array('sticky', 'close_button', 'tracking', 'show_countdown') as $field) {
            $input[$field] = isset($request[$field]) && !is_array($request[$field]) ? 1 : 0;
        }

        $input['status'] = isset($input['status']) ? $input['status'] : 'draft';

        /**
         * Allow add-ons to append their own already-sanitized campaign fields.
         *
         * @param array<string, mixed> $input Sanitized campaign request data.
         */
        return apply_filters('swairishx_campaign_request_data', $input);
    }

    public function set_campaign_status() {
        $id = isset($_GET['campaign']) ? absint($_GET['campaign']) : 0;
        if (!$id || !current_user_can('edit_post', $id)) {
            wp_die(esc_html__('You cannot update this campaign.', 'swairish-header-bar-offer-notifications'));
        }
        check_admin_referer('swairishx_set_campaign_status_' . $id);
        $status = isset($_GET['status']) ? sanitize_key(wp_unslash($_GET['status'])) : 'draft';
        $status = 'publish' === $status ? 'publish' : 'draft';
        wp_update_post(array('ID' => $id, 'post_status' => $status));
        wp_safe_redirect(add_query_arg(array('page' => 'swairishx-campaigns', 'updated' => 1), admin_url('admin.php')));
        exit;
    }

    public function duplicate_campaign() {
        $id = isset($_GET['campaign']) ? absint($_GET['campaign']) : 0;
        if (!$id || !current_user_can('edit_post', $id)) {
            wp_die(esc_html__('You cannot duplicate this campaign.', 'swairish-header-bar-offer-notifications'));
        }
        check_admin_referer('swairishx_duplicate_campaign_' . $id);
        $config = $this->storage->get_campaign($id);
        if (!$config) {
            wp_die(esc_html__('Campaign not found.', 'swairish-header-bar-offer-notifications'));
        }
        /* translators: %s: Original campaign name. */
        $config['name'] = sprintf(__('%s — Copy', 'swairish-header-bar-offer-notifications'), $config['name']);
        $config['status'] = 'draft';
        $copy = $this->storage->save_campaign($config);
        if (is_wp_error($copy)) {
            wp_die(esc_html($copy->get_error_message()));
        }
        wp_safe_redirect(add_query_arg(array('page' => 'swairishx-builder', 'campaign' => $copy, 'duplicated' => 1), admin_url('admin.php')));
        exit;
    }

    public function delete_campaign() {
        $id = isset($_GET['campaign']) ? absint($_GET['campaign']) : 0;
        if (!current_user_can('delete_post', $id)) {
            wp_die(esc_html__('You cannot delete this campaign.', 'swairish-header-bar-offer-notifications'));
        }
        check_admin_referer('swairishx_delete_campaign_' . $id);
        wp_trash_post($id);
        wp_safe_redirect(add_query_arg(array('page' => 'swairishx-campaigns', 'deleted' => 1), admin_url('admin.php')));
        exit;
    }

    public function save_settings() {
        if (!current_user_can($this->capability())) {
            wp_die(esc_html__('You cannot manage settings.', 'swairish-header-bar-offer-notifications'));
        }
        check_admin_referer('swairishx_save_settings');
        $brand = isset($_POST['brand_name']) ? sanitize_text_field(wp_unslash($_POST['brand_name'])) : 'Swairish Notifications';
        update_option('swairishx_brand_name', $brand ?: 'Swairish Notifications', false);
        wp_safe_redirect(admin_url('admin.php?page=swairishx-settings&updated=1'));
        exit;
    }

    public function shell_start($title, $description, $action_label = '', $action_url = '') {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing value.
        $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : 'swairishx';
        $brand = apply_filters('swairishx_brand_name', get_option('swairishx_brand_name', 'Swairish Notifications'));
        ?>
        <div class="wrap swairishx-admin">
            <header class="swx-appbar">
                <a class="swx-product" href="<?php echo esc_url(admin_url('admin.php?page=swairishx')); ?>"><span class="swx-product__mark">SX<i></i></span><span><strong><?php echo esc_html($brand); ?></strong><small><?php esc_html_e('Campaign workspace', 'swairish-header-bar-offer-notifications'); ?></small></span></a>
                <nav class="swx-context-nav" aria-label="<?php esc_attr_e('Swairish Notifications navigation', 'swairish-header-bar-offer-notifications'); ?>">
                    <?php $this->nav_link('swairishx', __('Overview', 'swairish-header-bar-offer-notifications'), $page, 'home'); ?>
                    <?php $this->nav_link('swairishx-campaigns', __('Campaigns', 'swairish-header-bar-offer-notifications'), $page, 'campaign'); ?>
                    <?php $this->nav_link('swairishx-integrations', __('Integrations', 'swairish-header-bar-offer-notifications'), $page, 'plug'); ?>
                    <?php foreach (apply_filters('swairishx_admin_navigation_items', array()) as $item) : $this->nav_link($item['slug'], $item['label'], $page, $item['icon']); endforeach; ?>
                    <?php $this->nav_link('swairishx-settings', __('Settings', 'swairish-header-bar-offer-notifications'), $page, 'settings'); ?>
                </nav>
            </header>
            <div class="swx-notice-drawer" data-swx-notice-drawer></div>
            <?php $this->feedback_notice(); ?>
            <header class="swx-pagehead"><div><span class="swx-pagehead__path"><?php esc_html_e('Swairish Notifications', 'swairish-header-bar-offer-notifications'); ?> /</span><h1><?php echo esc_html($title); ?></h1><p><?php echo esc_html($description); ?></p></div><?php if ($action_label && $action_url) : ?><a class="swx-button swx-button--primary" href="<?php echo esc_url($action_url); ?>"><?php echo esc_html($action_label); ?><?php $this->print_icon('arrow'); ?></a><?php endif; ?></header>
            <main class="swx-main">
        <?php
    }

    public function shell_end() {
        /* translators: %s: Plugin version. */
        ?></main><footer class="swx-app-footer"><span><?php echo esc_html(sprintf(__('Swairish Notifications %s', 'swairish-header-bar-offer-notifications'), SWAIRISHX_VERSION)); ?></span><a href="<?php echo esc_url(home_url('/privacy-policy/')); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Privacy', 'swairish-header-bar-offer-notifications'); ?></a></footer></div><?php
    }

    private function feedback_notice() {
        $message = '';
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only success flag after a verified redirect.
        if (isset($_GET['updated'])) {
            $message = __('Changes saved.', 'swairish-header-bar-offer-notifications');
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only success flag after a verified redirect.
        } elseif (isset($_GET['deleted'])) {
            $message = __('Campaign moved to the trash.', 'swairish-header-bar-offer-notifications');
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only success flag after a verified redirect.
        } elseif (isset($_GET['duplicated'])) {
            $message = __('Campaign duplicated as a draft.', 'swairish-header-bar-offer-notifications');
        }
        if ($message) {
            ?><div class="swx-feedback" role="status"><?php $this->print_icon('check'); ?><span><?php echo esc_html($message); ?></span></div><?php
        }
    }

    private function nav_link($slug, $label, $current, $icon) {
        $active = $slug === $current || ('swairishx-campaigns' === $slug && 'swairishx-builder' === $current);
        ?><a class="<?php echo esc_attr($active ? 'is-active' : ''); ?>" href="<?php echo esc_url(admin_url('admin.php?page=' . $slug)); ?>" <?php if ($active) : ?>aria-current="page"<?php endif; ?>><?php $this->print_icon($icon); ?><span><?php echo esc_html($label); ?></span></a><?php
    }

    private function metric($label, $value, $caption, $icon) {
        ?><article class="swx-metric"><span class="swx-metric__icon"><?php $this->print_icon($icon); ?></span><div><span><?php echo esc_html($label); ?></span><strong><?php echo esc_html($value); ?></strong><small><?php echo esc_html($caption); ?></small></div></article><?php
    }

    private function campaign_list($campaigns, $show_tools = false, $report = array()) {
        $stats = array();
        foreach ($report as $row) {
            $stats[absint($row['campaign_id'])] = $row;
        }
        ?>
        <section class="swx-campaign-card">
            <div class="swx-card-heading swx-card-heading--campaigns"><div><span class="swx-eyebrow"><?php echo $show_tools ? esc_html__('All campaigns', 'swairish-header-bar-offer-notifications') : esc_html__('Recent activity', 'swairish-header-bar-offer-notifications'); ?></span><h2><?php echo $show_tools ? esc_html__('Campaign queue', 'swairish-header-bar-offer-notifications') : esc_html__('Recent campaigns', 'swairish-header-bar-offer-notifications'); ?></h2></div><?php if (!$show_tools) : ?><a class="swx-text-link" href="<?php echo esc_url(admin_url('admin.php?page=swairishx-campaigns')); ?>"><?php esc_html_e('View all', 'swairish-header-bar-offer-notifications'); ?><?php $this->print_icon('arrow'); ?></a><?php endif; ?></div>
            <?php if ($show_tools && $campaigns) : ?><div class="swx-campaign-tools"><label class="swx-search"><?php $this->print_icon('search'); ?><span class="screen-reader-text"><?php esc_html_e('Search campaigns', 'swairish-header-bar-offer-notifications'); ?></span><input type="search" placeholder="<?php esc_attr_e('Search campaigns', 'swairish-header-bar-offer-notifications'); ?>" data-swx-campaign-search></label><div class="swx-filter-pills"><button type="button" class="is-active" data-swx-campaign-filter="all"><?php esc_html_e('All', 'swairish-header-bar-offer-notifications'); ?></button><button type="button" data-swx-campaign-filter="publish"><?php esc_html_e('Live', 'swairish-header-bar-offer-notifications'); ?></button><button type="button" data-swx-campaign-filter="draft"><?php esc_html_e('Draft', 'swairish-header-bar-offer-notifications'); ?></button></div></div><?php endif; ?>
            <?php if (!$campaigns) : ?>
                <div class="swx-empty"><span class="swx-empty__signal"><i></i><i></i><i></i></span><h3><?php esc_html_e('Your campaign queue is empty', 'swairish-header-bar-offer-notifications'); ?></h3><p><?php esc_html_e('Create one clear message and see it in context before anything goes live.', 'swairish-header-bar-offer-notifications'); ?></p><a class="swx-button swx-button--primary" href="<?php echo esc_url(admin_url('admin.php?page=swairishx-builder')); ?>"><?php esc_html_e('Create first campaign', 'swairish-header-bar-offer-notifications'); ?><?php $this->print_icon('arrow'); ?></a></div>
            <?php else : ?>
                <div class="swx-campaign-table" role="table" aria-label="<?php esc_attr_e('Campaigns', 'swairish-header-bar-offer-notifications'); ?>">
                    <div class="swx-campaign-table__head" role="row"><span><?php esc_html_e('Campaign', 'swairish-header-bar-offer-notifications'); ?></span><span><?php esc_html_e('Status', 'swairish-header-bar-offer-notifications'); ?></span><span><?php esc_html_e('30-day signal', 'swairish-header-bar-offer-notifications'); ?></span><span><?php esc_html_e('Modified', 'swairish-header-bar-offer-notifications'); ?></span><span></span></div>
                    <?php foreach ($campaigns as $campaign) :
                        $config = $this->storage->get_campaign($campaign->ID);
                        $definition = $this->registry->get('notification', isset($config['type']) ? $config['type'] : '');
                        $row = isset($stats[$campaign->ID]) ? $stats[$campaign->ID] : array('impressions' => 0, 'clicks' => 0);
                        $ctr = absint($row['impressions']) ? round(absint($row['clicks']) / absint($row['impressions']) * 100, 1) : 0;
                        $status_action = 'publish' === $campaign->post_status ? 'draft' : 'publish';
                        $status_url = wp_nonce_url(add_query_arg(array('action' => 'swairishx_set_campaign_status', 'campaign' => $campaign->ID, 'status' => $status_action), admin_url('admin-post.php')), 'swairishx_set_campaign_status_' . $campaign->ID);
                        $duplicate_url = wp_nonce_url(add_query_arg(array('action' => 'swairishx_duplicate_campaign', 'campaign' => $campaign->ID), admin_url('admin-post.php')), 'swairishx_duplicate_campaign_' . $campaign->ID);
                        $delete_url = wp_nonce_url(add_query_arg(array('action' => 'swairishx_delete_campaign', 'campaign' => $campaign->ID), admin_url('admin-post.php')), 'swairishx_delete_campaign_' . $campaign->ID);
                        ?>
                        <article class="swx-campaign-row" role="row" data-swx-campaign-row data-status="<?php echo esc_attr($campaign->post_status); ?>" data-name="<?php echo esc_attr(strtolower($campaign->post_title)); ?>">
                            <div class="swx-campaign-name" role="cell"><span class="swx-row__type"><?php $this->print_icon($this->type_icon(isset($config['type']) ? $config['type'] : '')); ?></span><div><h3><a href="<?php echo esc_url(add_query_arg(array('page' => 'swairishx-builder', 'campaign' => $campaign->ID), admin_url('admin.php'))); ?>"><?php echo esc_html($campaign->post_title); ?></a></h3><p><?php echo esc_html($definition && isset($definition['label']) ? $definition['label'] : __('Unknown type', 'swairish-header-bar-offer-notifications')); ?> · <?php echo esc_html(isset($config['position']) ? ucfirst($config['position']) : __('Top', 'swairish-header-bar-offer-notifications')); ?></p></div></div>
                            <div role="cell"><span class="swx-status <?php echo esc_attr('publish' === $campaign->post_status ? 'is-ready' : ''); ?>"><i></i><?php echo 'publish' === $campaign->post_status ? esc_html__('Live', 'swairish-header-bar-offer-notifications') : esc_html__('Draft', 'swairish-header-bar-offer-notifications'); ?></span></div>
                            <div class="swx-row-signal" role="cell"><strong><?php echo esc_html($ctr . '%'); ?></strong><span><?php
                                /* translators: 1: Impression count, 2: Click count. */
                                echo esc_html(sprintf(__('%1$s views · %2$s clicks', 'swairish-header-bar-offer-notifications'), number_format_i18n($row['impressions']), number_format_i18n($row['clicks'])));
                            ?></span></div>
                            <time role="cell" datetime="<?php echo esc_attr(get_the_modified_date('c', $campaign)); ?>"><?php echo esc_html(get_the_modified_date(get_option('date_format'), $campaign)); ?></time>
                            <div class="swx-row-actions" role="cell"><a class="swx-icon-button" href="<?php echo esc_url(add_query_arg(array('page' => 'swairishx-builder', 'campaign' => $campaign->ID), admin_url('admin.php'))); ?>" aria-label="<?php esc_attr_e('Edit campaign', 'swairish-header-bar-offer-notifications'); ?>"><?php $this->print_icon('edit'); ?></a><details><summary class="swx-icon-button" aria-label="<?php esc_attr_e('More campaign actions', 'swairish-header-bar-offer-notifications'); ?>"><?php $this->print_icon('more'); ?></summary><div><a href="<?php echo esc_url($status_url); ?>"><?php echo 'publish' === $campaign->post_status ? esc_html__('Pause campaign', 'swairish-header-bar-offer-notifications') : esc_html__('Publish campaign', 'swairish-header-bar-offer-notifications'); ?></a><a href="<?php echo esc_url($duplicate_url); ?>"><?php esc_html_e('Duplicate', 'swairish-header-bar-offer-notifications'); ?></a><a class="is-danger" href="<?php echo esc_url($delete_url); ?>" data-swx-delete><?php esc_html_e('Move to trash', 'swairish-header-bar-offer-notifications'); ?></a></div></details></div>
                        </article>
                    <?php endforeach; ?>
                </div>
                <div class="swx-no-results" data-swx-campaign-empty hidden><?php esc_html_e('No campaigns match this view.', 'swairish-header-bar-offer-notifications'); ?></div>
            <?php endif; ?>
        </section>
        <?php
    }

    private function quick_start_link($preset, $title, $description, $icon) {
        ?><a class="swx-quick-link" href="<?php echo esc_url(add_query_arg(array('page' => 'swairishx-builder', 'preset' => $preset), admin_url('admin.php'))); ?>"><span><?php $this->print_icon($icon); ?></span><div><strong><?php echo esc_html($title); ?></strong><small><?php echo esc_html($description); ?></small></div><?php $this->print_icon('arrow'); ?></a><?php
    }

    private function pro_banner() {
        if (defined('SWAIRISHX_PRO_VERSION')) {
            return;
        }
        ?>
        <aside class="swx-pro-banner" aria-label="<?php esc_attr_e('Swairish Pro', 'swairish-header-bar-offer-notifications'); ?>">
            <span class="swx-pro-banner__mark"><?php $this->print_icon('spark'); ?></span>
            <div><span class="swx-eyebrow"><?php esc_html_e('When campaigns need more depth', 'swairish-header-bar-offer-notifications'); ?></span><h2><?php esc_html_e('Recover inactive visitors and turn live growth into proof.', 'swairish-header-bar-offer-notifications'); ?></h2><p><?php esc_html_e('Swairish Pro adds Growth Alerts, flashing browser tabs, evergreen timers, advanced targeting, analytics, and more integrations as a separate add-on.', 'swairish-header-bar-offer-notifications'); ?></p></div>
            <a class="swx-button swx-button--primary" href="https://swadhinkhan.com/swairish-notificationx-header-bar-offer/" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Try Pro version', 'swairish-header-bar-offer-notifications'); ?><?php $this->print_icon('arrow'); ?></a>
        </aside>
        <?php
    }

    private function offer_preset_picker($selected = '') {
        ?>
        <fieldset class="swx-offer-presets">
            <legend><span><?php esc_html_e('Header offer presets', 'swairish-header-bar-offer-notifications'); ?></span><small><?php esc_html_e('Choose one to fill the message, CTA, position, and colors.', 'swairish-header-bar-offer-notifications'); ?></small></legend>
            <div class="swx-offer-preset-grid">
                <?php foreach ($this->offer_presets() as $preset_id => $preset) : ?>
                    <?php $preset_config = $preset['config']; ?>
                    <button
                        type="button"
                        class="swx-offer-preset<?php echo esc_attr($selected === $preset_id ? ' is-selected' : ''); ?>"
                        data-swx-offer-preset="<?php echo esc_attr($preset_id); ?>"
                        data-swx-preset-config="<?php echo esc_attr(wp_json_encode($preset_config)); ?>"
                        aria-pressed="<?php echo esc_attr($selected === $preset_id ? 'true' : 'false'); ?>"
                    >
                        <span class="swx-offer-preset__preview" style="--swx-preset-bg:<?php echo esc_attr($preset_config['background']); ?>;--swx-preset-fg:<?php echo esc_attr($preset_config['foreground']); ?>;--swx-preset-accent:<?php echo esc_attr($preset_config['accent']); ?>;">
                            <?php if (!empty($preset_config['image_url'])) : ?><img src="<?php echo esc_url($preset_config['image_url']); ?>" alt=""><?php else : ?><i><?php $this->print_icon($preset['icon']); ?></i><?php endif; ?>
                            <span><strong><?php echo esc_html($preset_config['headline']); ?></strong><small><?php echo esc_html($preset_config['message']); ?></small></span>
                            <b><?php echo esc_html($preset_config['cta_label']); ?></b>
                        </span>
                        <span class="swx-offer-preset__meta"><span><strong><?php echo esc_html($preset['label']); ?></strong><small><?php echo esc_html($preset['description']); ?></small></span><em aria-live="polite"><span><?php echo $selected === $preset_id ? esc_html__('Applied', 'swairish-header-bar-offer-notifications') : esc_html__('Use preset', 'swairish-header-bar-offer-notifications'); ?></span><?php $this->print_icon('check'); ?></em></span>
                    </button>
                <?php endforeach; ?>
            </div>
        </fieldset>
        <?php
    }

    private function offer_presets() {
        return array(
            'flash_sale' => array(
                'label' => __('Flash sale', 'swairish-header-bar-offer-notifications'),
                'description' => __('High urgency for a short promotion.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'sale',
                'config' => array('name' => __('Flash sale header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Flash sale: 30% off', 'swairish-header-bar-offer-notifications'), 'message' => __('Today only—use code FLASH30 at checkout.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Shop the sale', 'swairish-header-bar-offer-notifications'), 'coupon_code' => 'FLASH30', 'coupon_copied_text' => __('Copied', 'swairish-header-bar-offer-notifications'), 'position' => 'top', 'theme' => 'signal', 'background' => '#10261f', 'foreground' => '#f5fbf7', 'accent' => '#6ee7b7', 'sticky' => 1, 'close_button' => 1),
            ),
            'free_shipping' => array(
                'label' => __('Free shipping', 'swairish-header-bar-offer-notifications'),
                'description' => __('Make the qualifying order value obvious.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'bar',
                'config' => array('name' => __('Free shipping header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Free shipping unlocked', 'swairish-header-bar-offer-notifications'), 'message' => __('Free delivery on orders over $50.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Start shopping', 'swairish-header-bar-offer-notifications'), 'position' => 'top', 'theme' => 'paper', 'background' => '#f5efe4', 'foreground' => '#2b241b', 'accent' => '#ef9b63', 'sticky' => 1, 'close_button' => 1),
            ),
            'first_order' => array(
                'label' => __('First order', 'swairish-header-bar-offer-notifications'),
                'description' => __('A welcoming incentive for new visitors.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'spark',
                'config' => array('name' => __('First order welcome header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Welcome—save 15% on your first order', 'swairish-header-bar-offer-notifications'), 'message' => __('Use code WELCOME15 at checkout.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Claim 15% off', 'swairish-header-bar-offer-notifications'), 'coupon_code' => 'WELCOME15', 'coupon_copied_text' => __('Copied', 'swairish-header-bar-offer-notifications'), 'position' => 'top', 'theme' => 'paper', 'background' => '#e8f5ef', 'foreground' => '#173b2d', 'accent' => '#79dcb4', 'sticky' => 1, 'close_button' => 1),
            ),
            'weekend_deal' => array(
                'label' => __('Weekend deal', 'swairish-header-bar-offer-notifications'),
                'description' => __('A compact offer with a clear deadline.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'live',
                'config' => array('name' => __('Weekend deal header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Weekend special: Buy 2, get 1 free', 'swairish-header-bar-offer-notifications'), 'message' => __('Offer ends Sunday at midnight.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Build your bundle', 'swairish-header-bar-offer-notifications'), 'position' => 'top', 'theme' => 'contrast', 'background' => '#171d2b', 'foreground' => '#f8fafc', 'accent' => '#f0c75e', 'sticky' => 1, 'close_button' => 1),
            ),
            'new_launch' => array(
                'label' => __('Product launch', 'swairish-header-bar-offer-notifications'),
                'description' => __('Give a new release a confident entrance.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'spark',
                'config' => array('name' => __('Product launch header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Just launched: Meet our newest release', 'swairish-header-bar-offer-notifications'), 'message' => __('Be first to explore what’s new.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('See what’s new', 'swairish-header-bar-offer-notifications'), 'position' => 'top', 'theme' => 'contrast', 'background' => '#12203a', 'foreground' => '#f7fbff', 'accent' => '#7dd3fc', 'sticky' => 1, 'close_button' => 1),
            ),
            'bundle_save' => array(
                'label' => __('Bundle and save', 'swairish-header-bar-offer-notifications'),
                'description' => __('Explain a multi-product saving quickly.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'sale',
                'config' => array('name' => __('Bundle offer header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Bundle more. Save 25%.', 'swairish-header-bar-offer-notifications'), 'message' => __('Choose any three products and save automatically.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Create a bundle', 'swairish-header-bar-offer-notifications'), 'position' => 'top', 'theme' => 'contrast', 'background' => '#3b174f', 'foreground' => '#fff8ff', 'accent' => '#e9a8ff', 'sticky' => 1, 'close_button' => 1),
            ),
            'early_access' => array(
                'label' => __('Early access', 'swairish-header-bar-offer-notifications'),
                'description' => __('Reward members before the public launch.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'star',
                'config' => array('name' => __('Early access header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Early access is open', 'swairish-header-bar-offer-notifications'), 'message' => __('Members get first pick before public release.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Get early access', 'swairish-header-bar-offer-notifications'), 'position' => 'top', 'theme' => 'paper', 'background' => '#f1efe9', 'foreground' => '#292722', 'accent' => '#d7d0be', 'sticky' => 1, 'close_button' => 1),
            ),
            'seasonal_offer' => array(
                'label' => __('Seasonal offer', 'swairish-header-bar-offer-notifications'),
                'description' => __('Warm, editorial treatment for seasonal sales.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'star',
                'config' => array('name' => __('Seasonal offer header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Seasonal offer: Up to 40% off', 'swairish-header-bar-offer-notifications'), 'message' => __('Fresh picks, limited quantities.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Explore the offer', 'swairish-header-bar-offer-notifications'), 'position' => 'top', 'theme' => 'contrast', 'background' => '#7b2d26', 'foreground' => '#fff9f4', 'accent' => '#ffc77d', 'sticky' => 1, 'close_button' => 1),
            ),
            'product_spotlight' => array(
                'label' => __('Product spotlight', 'swairish-header-bar-offer-notifications'),
                'description' => __('Put a featured product front and center.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'sale',
                'config' => array('name' => __('Product spotlight header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('The drop everyone asked for is here', 'swairish-header-bar-offer-notifications'), 'message' => __('Limited launch stock—discover the new collection.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Shop the drop', 'swairish-header-bar-offer-notifications'), 'image_url' => SWAIRISHX_URL . 'assets/images/presets/product-spotlight.png', 'image_alt' => __('Parcel box and shopping bag', 'swairish-header-bar-offer-notifications'), 'image_position' => 'start', 'position' => 'top', 'theme' => 'signal', 'background' => '#173b2f', 'foreground' => '#fffaf0', 'accent' => '#f2c86b', 'sticky' => 1, 'close_button' => 1),
            ),
            'saas_lifetime_deal' => array(
                'label' => __('SaaS lifetime deal', 'swairish-header-bar-offer-notifications'),
                'description' => __('A clear one-time software launch offer.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'spark',
                'config' => array('name' => __('SaaS lifetime deal header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Lifetime access. One simple payment.', 'swairish-header-bar-offer-notifications'), 'message' => __('Launch pricing ends when this release window closes.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Get lifetime access', 'swairish-header-bar-offer-notifications'), 'image_url' => SWAIRISHX_URL . 'assets/images/presets/saas-lifetime-deal.png', 'image_alt' => __('Software dashboard and infinity symbol', 'swairish-header-bar-offer-notifications'), 'image_position' => 'start', 'position' => 'top', 'theme' => 'contrast', 'background' => '#10261f', 'foreground' => '#f7fff9', 'accent' => '#ff8266', 'sticky' => 1, 'close_button' => 1),
            ),
            'course_enrollment' => array(
                'label' => __('Course enrollment', 'swairish-header-bar-offer-notifications'),
                'description' => __('Open enrollment with a learning-first visual.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'star',
                'config' => array('name' => __('Course enrollment header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Enrollment is now open', 'swairish-header-bar-offer-notifications'), 'message' => __('Join the next cohort and learn at your own pace.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('View the course', 'swairish-header-bar-offer-notifications'), 'image_url' => SWAIRISHX_URL . 'assets/images/presets/course-enrollment.png', 'image_alt' => __('Open book and graduation cap', 'swairish-header-bar-offer-notifications'), 'image_position' => 'start', 'position' => 'top', 'theme' => 'paper', 'background' => '#f7f0df', 'foreground' => '#24342d', 'accent' => '#ff8367', 'sticky' => 1, 'close_button' => 1),
            ),
            'hosting_deal' => array(
                'label' => __('Hosting deal', 'swairish-header-bar-offer-notifications'),
                'description' => __('Promote faster hosting with a strong visual cue.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'chart',
                'config' => array('name' => __('Hosting deal header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Move to faster cloud hosting', 'swairish-header-bar-offer-notifications'), 'message' => __('Save 35% today and get free assisted migration.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('See hosting plans', 'swairish-header-bar-offer-notifications'), 'image_url' => SWAIRISHX_URL . 'assets/images/presets/hosting-deal.png', 'image_alt' => __('Cloud and server stack', 'swairish-header-bar-offer-notifications'), 'image_position' => 'start', 'position' => 'top', 'theme' => 'signal', 'background' => '#0d2e2b', 'foreground' => '#f5fffb', 'accent' => '#f6c65d', 'sticky' => 1, 'close_button' => 1),
            ),
            'webinar_registration' => array(
                'label' => __('Webinar registration', 'swairish-header-bar-offer-notifications'),
                'description' => __('Turn an upcoming live session into action.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'video',
                'config' => array('name' => __('Webinar registration header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Live workshop seats are open', 'swairish-header-bar-offer-notifications'), 'message' => __('Reserve your place and get the replay afterward.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Reserve my seat', 'swairish-header-bar-offer-notifications'), 'image_url' => SWAIRISHX_URL . 'assets/images/presets/webinar-registration.png', 'image_alt' => __('Presentation screen and calendar', 'swairish-header-bar-offer-notifications'), 'image_position' => 'end', 'position' => 'top', 'theme' => 'paper', 'background' => '#eef7f1', 'foreground' => '#19352b', 'accent' => '#ff8266', 'sticky' => 1, 'close_button' => 1),
            ),
            'app_launch' => array(
                'label' => __('App launch', 'swairish-header-bar-offer-notifications'),
                'description' => __('Drive downloads for a new mobile release.', 'swairish-header-bar-offer-notifications'),
                'icon' => 'spark',
                'config' => array('name' => __('App launch header', 'swairish-header-bar-offer-notifications'), 'type' => 'notification_bar', 'integration' => 'manual', 'headline' => __('Our new app is ready to download', 'swairish-header-bar-offer-notifications'), 'message' => __('Get the fastest way to manage everything on the go.', 'swairish-header-bar-offer-notifications'), 'cta_label' => __('Download the app', 'swairish-header-bar-offer-notifications'), 'image_url' => SWAIRISHX_URL . 'assets/images/presets/app-launch.png', 'image_alt' => __('Smartphone with launch rocket', 'swairish-header-bar-offer-notifications'), 'image_position' => 'end', 'position' => 'top', 'theme' => 'contrast', 'background' => '#172b26', 'foreground' => '#fbfff9', 'accent' => '#f2c86b', 'sticky' => 1, 'close_button' => 1),
            ),
        );
    }

    private function report_totals($report) {
        $totals = array('impressions' => 0, 'clicks' => 0, 'dismissals' => 0);
        foreach ($report as $row) {
            foreach ($totals as $key => $value) {
                $totals[$key] += absint($row[$key]);
            }
        }
        return $totals;
    }

    private function step_button($index, $id, $label, $icon) {
        ?><button type="button" class="<?php echo esc_attr(0 === $index ? 'is-active' : ''); ?>" data-swx-tab="<?php echo esc_attr($id); ?>" data-swx-step-index="<?php echo esc_attr($index); ?>"><span><?php $this->print_icon($icon); ?></span><span><small><?php /* translators: %d: Setup step number. */ echo esc_html(sprintf(__('Step %d', 'swairish-header-bar-offer-notifications'), $index + 1)); ?></small><strong><?php echo esc_html($label); ?></strong></span><i><?php $this->print_icon('check'); ?></i></button><?php
    }

    private function section_intro($title, $description) {
        ?><div class="swx-section-intro"><h2><?php echo esc_html($title); ?></h2><p><?php echo esc_html($description); ?></p></div><?php
    }

    private function input($name, $label, $value, $type = 'text', $help = '', $placeholder = '') {
        ?><label class="swx-field"><span><?php echo esc_html($label); ?></span><input type="<?php echo esc_attr($type); ?>" name="<?php echo esc_attr($name); ?>" value="<?php echo esc_attr($value); ?>" <?php if ($placeholder) : ?>placeholder="<?php echo esc_attr($placeholder); ?>"<?php endif; ?> <?php if ('number' === $type) : ?>min="0"<?php endif; ?>><?php if ($help) : ?><small><?php echo esc_html($help); ?></small><?php endif; ?></label><?php
    }

    private function textarea($name, $label, $value, $help = '') {
        ?><label class="swx-field"><span><?php echo esc_html($label); ?></span><textarea name="<?php echo esc_attr($name); ?>" rows="4"><?php echo esc_textarea($value); ?></textarea><?php if ($help) : ?><small><?php echo esc_html($help); ?></small><?php endif; ?></label><?php
    }

    private function select($name, $label, $value, $options) {
        ?><label class="swx-field"><span><?php echo esc_html($label); ?></span><select name="<?php echo esc_attr($name); ?>"><?php foreach ($options as $id => $definition) : ?><option value="<?php echo esc_attr($id); ?>" <?php selected($value, $id); ?>><?php echo esc_html(isset($definition['label']) ? $definition['label'] : $id); ?></option><?php endforeach; ?></select></label><?php
    }

    private function checkbox($name, $label, $description, $checked) {
        ?><label class="swx-toggle"><span><strong><?php echo esc_html($label); ?></strong><small><?php echo esc_html($description); ?></small></span><input type="checkbox" name="<?php echo esc_attr($name); ?>" value="1" <?php checked($checked); ?>><i aria-hidden="true"></i></label><?php
    }

    private function color_input($name, $label, $value) {
        ?><label class="swx-color-field"><span><?php echo esc_html($label); ?></span><span><input type="color" name="<?php echo esc_attr($name); ?>" value="<?php echo esc_attr($value); ?>"><code data-swx-color-value="<?php echo esc_attr($name); ?>"><?php echo esc_html(strtoupper($value)); ?></code></span></label><?php
    }

    private function integration_state($id, $definition) {
        $checks = array(
            'manual' => true,
            'wordpress_comments' => true,
            'wordpress_org' => true,
            'woocommerce' => class_exists('WooCommerce'),
            'easy_digital_downloads' => function_exists('EDD'),
            'givewp' => class_exists('Give'),
            'tutor_lms' => function_exists('tutor'),
            'contact_form_7' => defined('WPCF7_VERSION'),
            'ninja_forms' => defined('NF_PLUGIN_VERSION'),
            'wpforms' => function_exists('wpforms'),
        );
        return !empty($checks[$id]) ? 'connected' : 'available';
    }

    private function integration_description($id, $state) {
        if ('manual' === $id) {
            return __('Write a fixed message without another plugin.', 'swairish-header-bar-offer-notifications');
        }
        if ('wordpress_org' === $id) {
            return __('Sync plugin ratings and active-install milestones.', 'swairish-header-bar-offer-notifications');
        }
        if ('wordpress_comments' === $id) {
            return __('Show approved comments as authentic activity.', 'swairish-header-bar-offer-notifications');
        }
        return 'connected' === $state ? __('Active on this site and ready for campaigns.', 'swairish-header-bar-offer-notifications') : __('Install and activate the source plugin to connect it.', 'swairish-header-bar-offer-notifications');
    }

    private function state_label($state) {
        if ('connected' === $state) {
            return __('Ready', 'swairish-header-bar-offer-notifications');
        }
        return __('Available', 'swairish-header-bar-offer-notifications');
    }

    private function type_description($type) {
        $descriptions = array(
            'notification_bar' => __('Site-wide offer or announcement', 'swairish-header-bar-offer-notifications'),
            'sales_alert' => __('Recent purchase social proof', 'swairish-header-bar-offer-notifications'),
            'discount_alert' => __('Promotion with clear urgency', 'swairish-header-bar-offer-notifications'),
            'blog_comments_alert' => __('Recent reader engagement', 'swairish-header-bar-offer-notifications'),
            'wordpress_review_alert' => __('Plugin rating and review proof', 'swairish-header-bar-offer-notifications'),
            'wordpress_download_count_alert' => __('Active install milestone', 'swairish-header-bar-offer-notifications'),
        );
        return isset($descriptions[$type]) ? $descriptions[$type] : __('Advanced visitor notification', 'swairish-header-bar-offer-notifications');
    }

    private function type_icon($type) {
        if (false !== strpos($type, 'bar') || false !== strpos($type, 'offer') || false !== strpos($type, 'announcement')) {
            return 'bar';
        }
        if (false !== strpos($type, 'sale') || false !== strpos($type, 'commerce') || false !== strpos($type, 'discount')) {
            return 'sale';
        }
        if (false !== strpos($type, 'review') || false !== strpos($type, 'rating')) {
            return 'star';
        }
        if (false !== strpos($type, 'download')) {
            return 'chart';
        }
        if (false !== strpos($type, 'comment') || false !== strpos($type, 'email')) {
            return 'message';
        }
        if (false !== strpos($type, 'video')) {
            return 'video';
        }
        return 'spark';
    }

    /**
     * Output a private, hard-coded interface icon through a strict SVG allowlist.
     *
     * @param string $name Icon identifier.
     */
    private function print_icon($name) {
        echo wp_kses(
            $this->icon($name),
            array(
                'svg' => array(
                    'viewbox' => true,
                    'aria-hidden' => true,
                    'focusable' => true,
                    'fill' => true,
                    'stroke' => true,
                    'stroke-width' => true,
                    'stroke-linecap' => true,
                    'stroke-linejoin' => true,
                ),
                'path' => array('d' => true),
                'circle' => array('cx' => true, 'cy' => true, 'r' => true),
                'rect' => array('x' => true, 'y' => true, 'width' => true, 'height' => true, 'rx' => true),
            )
        );
    }

    private function icon($name) {
        $paths = array(
            'home' => '<path d="M3 11.5 12 4l9 7.5"/><path d="M5.5 10.5V20h13v-9.5"/><path d="M9.5 20v-6h5v6"/>',
            'campaign' => '<path d="M4 13.5V10l13-5v13L4 13.5Z"/><path d="M7 14.5 8.5 20h3L10 15.5"/><path d="M17 9c2 1 2 4 0 5"/>',
            'plug' => '<path d="m8 12 8-8"/><path d="m14 3 7 7"/><path d="m5 15 4 4"/><path d="M2.5 21.5 8 16"/><path d="M9 10 4 15l5 5 5-5"/>',
            'settings' => '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6v.2h-4V21a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14H2.8v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1A1.7 1.7 0 0 0 9 4.6 1.7 1.7 0 0 0 10 3v-.2h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9 1.7 1.7 0 0 0 1.6 1h.2v4H21a1.7 1.7 0 0 0-1.6 1Z"/>',
            'help' => '<circle cx="12" cy="12" r="9"/><path d="M9.8 9a2.4 2.4 0 1 1 3.5 2.1c-.9.5-1.3 1-1.3 2"/><path d="M12 17h.01"/>',
            'arrow' => '<path d="M5 12h14"/><path d="m14 7 5 5-5 5"/>',
            'back' => '<path d="M19 12H5"/><path d="m10 7-5 5 5 5"/>',
            'live' => '<circle cx="12" cy="12" r="3"/><path d="M5.6 5.6a9 9 0 0 0 0 12.8M18.4 5.6a9 9 0 0 1 0 12.8"/>',
            'draft' => '<path d="M5 3h10l4 4v14H5z"/><path d="M14 3v5h5"/><path d="M8 13h8M8 17h5"/>',
            'eye' => '<path d="M2.5 12s3.5-6 9.5-6 9.5 6 9.5 6-3.5 6-9.5 6-9.5-6-9.5-6Z"/><circle cx="12" cy="12" r="2.5"/>',
            'click' => '<path d="m7 3 9 9-4 1 3 6-2 1-3-6-3 3Z"/>',
            'source' => '<circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="12" cy="18" r="2"/><path d="m7.7 7.1 3.2 8.9M16.3 7.1 13.1 16"/>',
            'message' => '<path d="M4 5h16v12H8l-4 3Z"/><path d="M8 9h8M8 13h5"/>',
            'target' => '<circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="4"/><path d="M12 2v3M22 12h-3M12 22v-3M2 12h3"/>',
            'palette' => '<path d="M12 3a9 9 0 1 0 0 18h1.5a2 2 0 0 0 0-4H12a1.5 1.5 0 0 1 0-3h4a5 5 0 0 0 5-5c0-3.3-4-6-9-6Z"/><circle cx="7.5" cy="9" r="1"/><circle cx="11" cy="6.5" r="1"/><circle cx="15" cy="7" r="1"/>',
            'check' => '<path d="m5 12 4 4L19 6"/>',
            'spark' => '<path d="m12 3 1.5 5.5L19 10l-5.5 1.5L12 17l-1.5-5.5L5 10l5.5-1.5Z"/><path d="m19 16 .7 2.3L22 19l-2.3.7L19 22l-.7-2.3L16 19l2.3-.7Z"/>',
            'bar' => '<rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 9h18"/><path d="M7 7h7"/>',
            'sale' => '<path d="M4 7h16l-1 13H5Z"/><path d="M8 9V6a4 4 0 0 1 8 0v3"/><path d="M9 14h6"/>',
            'star' => '<path d="m12 3 2.8 5.7 6.2.9-4.5 4.4 1.1 6.2-5.6-3-5.6 3 1.1-6.2L3 9.6l6.2-.9Z"/>',
            'chart' => '<path d="M4 20V10M10 20V4M16 20v-7M22 20H2"/>',
            'video' => '<rect x="3" y="5" width="18" height="14" rx="2"/><path d="m10 9 5 3-5 3Z"/>',
            'shield' => '<path d="M12 3 20 6v5c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10V6Z"/><path d="m8.5 12 2.2 2.2 4.8-5"/>',
            'search' => '<circle cx="10.5" cy="10.5" r="6.5"/><path d="m16 16 5 5"/>',
            'desktop' => '<rect x="3" y="4" width="18" height="13" rx="2"/><path d="M8 21h8M12 17v4"/>',
            'mobile' => '<rect x="7" y="2" width="10" height="20" rx="2"/><path d="M11 18h2"/>',
            'edit' => '<path d="m4 16-.7 4.7L8 20l11-11-4-4Z"/><path d="m13.5 6.5 4 4"/>',
            'more' => '<circle cx="5" cy="12" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/>',
        );
        $path = isset($paths[$name]) ? $paths[$name] : $paths['spark'];
        return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">' . $path . '</svg>';
    }

    private function capability() {
        return apply_filters('swairishx_manage_capability', 'manage_options');
    }
}
