<?php
declare(strict_types=1);

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

/**
 * Free shipping progress bar element renderer (shared).
 *
 * Phase 1, step 14.
 *
 * Renders a progress bar that fills as the cart subtotal approaches
 * the configured free-shipping threshold.
 *
 * Pre-extraction the two renderers were both quite different in
 * content but identical in DOM shape:
 *
 *   - **Frontend** rendered the live version: REST polling against
 *     `/cart`, formatted currency, dynamic text-before/after swap,
 *     `instinctor:cart:updated` event listener. Plus a real bug
 *     where `textEl.style.color = textColor;` appeared BEFORE the
 *     `var textEl = ...` declaration — `textEl` undefined at that
 *     line → the IIFE threw on first execution → no bar ever
 *     rendered. Bug exists on every live page that uses this block.
 *     Fixed during extraction (moved the color assignment AFTER
 *     the querySelector).
 *
 *   - **Editor** rendered the demo state: static 40% fill, hardcoded
 *     subtotal preview using a fraction of the threshold, no JS
 *     wiring (editor preview iframe doesn't talk to the real cart).
 *
 * Both render the same .impulse-shipping-bar-wrap / -text / -track
 * / -fill structure with identical styling. The shared function
 * branches on $isEditor for the body content + JS emission.
 */
function impulse_element_render_shipping($el, array $settings, string $context): string {
    if (is_object($el)) $el = (array) $el;
    $elId     = preg_replace('/[^A-Za-z0-9_-]/', '', (string) ($el['id'] ?? '0'));
    $isEditor = ($context === 'editor');

    $textBefore = (string) ($settings['text_before'] ?? 'Add {amount} more for free shipping!');
    $textAfter  = (string) ($settings['text_after']  ?? "You've unlocked free shipping!");
    $barColor   = (string) ($settings['bar_color']   ?? '#555555');
    $textColor  = (string) ($settings['text_color']  ?? '#ffffff');
    $threshold  = !empty($settings['threshold']) ? floatval($settings['threshold']) : null;
    $height     = intval($settings['bar_height']    ?? 8);
    $radius     = intval($settings['border_radius'] ?? 20);
    $fontSize   = intval($settings['font_size']     ?? 14);

    $sbId = 'impulse-sb-' . $elId;
    $elSel = '#' . $sbId;

    // Editor: static demo at 40% fill so the user can preview the look.
    if ($isEditor) {
        $demoThreshold = $threshold !== null ? $threshold : 75;
        $demoPct = 40;
        $demoText = str_replace('{amount}', '$' . number_format($demoThreshold * 0.6, 2), $textBefore);
        ob_start();
        echo '<div id="' . esc_attr($sbId) . '" class="impulse-shipping-bar-wrap">';
        echo '<div class="impulse-shipping-bar-text" style="font-size:' . esc_attr((string) $fontSize) . 'px;color:' . esc_attr($textColor) . ';margin-bottom:8px;text-align:center;font-weight:500">' . esc_html($demoText) . '</div>';
        echo '<div class="impulse-shipping-bar-track" style="background:rgba(255,255,255,0.15);height:' . esc_attr((string) $height) . 'px;border-radius:' . esc_attr((string) $radius) . 'px;overflow:hidden">';
        echo '<div class="impulse-shipping-bar-fill" style="background:repeating-linear-gradient(135deg,' . esc_attr($barColor) . ' 0px,' . esc_attr($barColor) . ' 20px,rgba(0,0,0,0.15) 20px,rgba(0,0,0,0.15) 40px);height:100%;border-radius:' . esc_attr((string) $radius) . 'px;width:' . esc_attr((string) $demoPct) . '%;transition:width 0.4s ease-in-out"></div>';
        echo '</div></div>';
        return ob_get_clean();
    }

    // Frontend — full reactive bar bound to the cart REST endpoint.
    $symbol = '$'; $position = 'left'; $rate = 1;
    if (class_exists('\\Instinctor\\Core\\Config')) {
        $symbol   = \Instinctor\Core\Config::get('instinctor_currency_symbol',   '$');
        $position = \Instinctor\Core\Config::get('instinctor_currency_position', 'left');
    }
    $apiUrl = function_exists('rest_url')          ? rest_url('instinctor/v1/') : '/wp-json/instinctor/v1/';
    $nonce  = function_exists('wp_create_nonce')   ? wp_create_nonce('wp_rest') : '';

    ob_start();
    ?>
    <div id="<?php echo esc_attr($sbId); ?>" class="impulse-shipping-bar-wrap" style="visibility:hidden">
        <div class="impulse-shipping-bar-text" style="font-size:<?php echo intval($fontSize); ?>px;color:<?php echo esc_attr($textColor); ?>;margin-bottom:8px;text-align:center;font-weight:500"></div>
        <div class="impulse-shipping-bar-track" style="background:rgba(255,255,255,0.15);height:<?php echo intval($height); ?>px;border-radius:<?php echo intval($radius); ?>px;overflow:hidden">
            <div class="impulse-shipping-bar-fill" style="background:repeating-linear-gradient(135deg,<?php echo esc_attr($barColor); ?> 0px,<?php echo esc_attr($barColor); ?> 20px,rgba(0,0,0,0.15) 20px,rgba(0,0,0,0.15) 40px);height:100%;border-radius:<?php echo intval($radius); ?>px;width:0%;transition:width 0.6s cubic-bezier(0.4,0,0.2,1)"></div>
        </div>
    </div>
    <script>
    (function(){
        var apiUrl=<?php echo wp_json_encode($apiUrl); ?>;
        var nonce=<?php echo wp_json_encode($nonce); ?>;
        var symbol=<?php echo wp_json_encode($symbol); ?>;
        var position=<?php echo wp_json_encode($position); ?>;
        var rate=<?php echo floatval($rate); ?>;
        var override=<?php echo $threshold !== null ? floatval($threshold) : 'null'; ?>;
        var textBefore=<?php echo function_exists('wp_json_encode') ? wp_json_encode($textBefore) : wp_json_encode($textBefore); ?>;
        var textAfter=<?php echo function_exists('wp_json_encode') ? wp_json_encode($textAfter) : wp_json_encode($textAfter); ?>;
        var textColor=<?php echo function_exists('wp_json_encode') ? wp_json_encode($textColor) : wp_json_encode($textColor); ?>;
        var wrap=document.getElementById(<?php echo wp_json_encode($sbId); ?>);
        if(!wrap)return;
        var textEl=wrap.querySelector('.impulse-shipping-bar-text');
        var fill=wrap.querySelector('.impulse-shipping-bar-fill');
        // Pre-extraction this assignment appeared BEFORE the querySelector
        // line above — textEl was undefined and the IIFE threw, so no
        // page using this block ever painted the bar. Fixed during
        // extraction (2.1.237).
        if (textEl) textEl.style.color = textColor;
        function fmt(amount){var v=(parseFloat(amount)*rate).toFixed(2);return position==='right'||position==='right_space'?v+symbol:symbol+v;}
        function render(subtotal,threshold){
            if(threshold===null||threshold<=0){wrap.style.display='none';return;}
            wrap.style.display='';
            wrap.style.visibility='visible';
            var pct=Math.min(100,Math.round((subtotal/threshold)*100));
            fill.style.width=pct+'%';
            if(subtotal>=threshold){
                textEl.textContent=textAfter;
                textEl.classList.add('achieved');
            }else{
                var remaining=fmt(threshold-subtotal);
                textEl.textContent=textBefore.replace('{amount}',remaining);
                textEl.classList.remove('achieved');
            }
        }
        function update(){
            if(override===null){wrap.style.display='none';return;}
            fetch(apiUrl+'cart',{headers:{'X-WP-Nonce':nonce}})
                .then(function(r){return r.json();})
                .then(function(d){var sub=0;if(d.data&&d.data.totals)sub=parseFloat(d.data.totals.subtotal)||0;render(sub,override);})
                .catch(function(){render(0,override);});
        }
        update();
        document.addEventListener('instinctor:cart:updated',update);
    })();
    </script>
    <?php
    $html = ob_get_clean();

    // Inline CSS — achieved state + responsive font/height/radius.
    if (function_exists('wp_add_inline_style')) {
        wp_add_inline_style('instinctor-page-inline', '#' . $sbId . ' .impulse-shipping-bar-text.achieved{font-weight:600;opacity:0.8}');
        if (function_exists('impulse_responsive_css')) {
            $resp  = impulse_responsive_css($settings, $elSel . ' .impulse-shipping-bar-text',  ['font_size'     => ['font-size',     'px']]);
            $resp .= impulse_responsive_css($settings, $elSel . ' .impulse-shipping-bar-track', ['bar_height'    => ['height',        'px'], 'border_radius' => ['border-radius', 'px']]);
            $resp .= impulse_responsive_css($settings, $elSel . ' .impulse-shipping-bar-fill',  ['border_radius' => ['border-radius', 'px']]);
            if ($resp) wp_add_inline_style('instinctor-page-inline', $resp);
        }
    }

    return $html;
}
