<?php
/**
 * Chat-screen pointer overlay.
 *
 * Renders a curved animated SVG arrow that points from the active "chat
 * screen" toward the floating chat trigger at bottom-right. Visible only
 * when:
 *   - The page has a section with `chat_marker=1` (sets data-chat-marker)
 *   - That section is currently `.impulse-screen-active`
 *
 * Mirrors the pattern in impulse-hero-sandbox.php: idempotent emission via
 * a $GLOBALS flag, MutationObserver-driven body class toggle, fixed
 * overlay layered above content but below the chat widget (z-index 998).
 *
 * @package Instinctor
 * @since 2.1.785
 */

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

function impulse_render_chat_pointer(array $page_settings): void {
    // Only emit once per page render.
    if (!empty($GLOBALS['impulse_chat_pointer_emitted'])) return;
    $GLOBALS['impulse_chat_pointer_emitted'] = true;

    // The pointer is purely a visual cue for the chat widget — no point
    // rendering it when chat is disabled. ChatService.php gates the widget
    // on `instinctor_chat_enabled`; mirror that gate here.
    $chatEnabled = true;
    if (class_exists('\\Instinctor\\Core\\Config')) {
        $chatEnabled = (string) \Instinctor\Core\Config::get('instinctor_chat_enabled', '1') !== '0';
    }
    if (!$chatEnabled) return;

    // Per-page gate (default-off): the widget itself only renders when the
    // page explicitly enables chat, so the pointer must match - an arrow
    // pointing at a widget that is not there is worse than nothing.
    $pvOn = false;
    foreach (['chat_visible', 'chat_visible_desktop', 'chat_visible_mobile'] as $pvKey) {
        $pv = $page_settings[$pvKey] ?? null;
        if ($pv === 1 || $pv === '1' || $pv === true) { $pvOn = true; break; }
    }
    if (!$pvOn) return;

    // The overlay is layered above content but BELOW the chat widget
    // (#instinctor-chat z-index:999999) so the arrow's tip visually
    // terminates at the trigger but never blocks clicks on it.
    //
    // The curve starts at viewport-center-low (where the chat screen's
    // CTA typically lives) and bends down-right to the chat trigger.
    // Path coordinates use viewBox 0 0 100 100, so the arrow scales
    // smoothly with viewport size; CSS pins the SVG to the bottom-right
    // quadrant of the viewport, occupying ~60vw × 60vh. That's enough
    // room for a comfortable arc without crowding the screen content.
    $_cpCss = '.impulse-chat-pointer{position:fixed;right:0;bottom:0;width:60vw;height:60vh;max-width:600px;max-height:520px;pointer-events:none;z-index:998;opacity:0;visibility:hidden;transition:opacity 460ms ease-in-out,visibility 0s linear 460ms}'
       // .impulse-on-chat-screen — set by the JS below when the active
       // section has data-chat-marker. Fade in + draw the dash path,
       // then fade out cleanly when the user moves on.
       . 'body.impulse-on-chat-screen .impulse-chat-pointer{opacity:1;visibility:visible;transition:opacity 460ms ease-in-out 200ms,visibility 0s}'
       // Path stroke colour respects light/dark surroundings via CSS
       // var; default is muted white so it shows on dark hero scenes.
       // Pages with bright backgrounds can override --impulse-chat-pointer-color
       // at the body level if they need a darker stroke.
       . '.impulse-chat-pointer svg{width:100%;height:100%;display:block;color:var(--impulse-chat-pointer-color,rgba(255,255,255,0.7));filter:drop-shadow(0 1px 2px rgba(0,0,0,0.35))}'
       . '.impulse-chat-pointer-path{fill:none;stroke:currentColor;stroke-width:1.2;stroke-linecap:round;stroke-dasharray:140;stroke-dashoffset:140}'
       . 'body.impulse-on-chat-screen .impulse-chat-pointer-path{animation:impulse-chat-pointer-draw 1100ms cubic-bezier(0.4,0,0.2,1) 360ms forwards}'
       . '@keyframes impulse-chat-pointer-draw{from{stroke-dashoffset:140}to{stroke-dashoffset:0}}'
       // Label sits just above the path's mid-point, slightly tilted to
       // follow the arc. Fades in alongside the path.
       . '.impulse-chat-pointer-label{position:absolute;right:42%;bottom:48%;font-size:11px;letter-spacing:2px;text-transform:uppercase;color:var(--impulse-chat-pointer-color,rgba(255,255,255,0.78));font-weight:600;opacity:0;transform:rotate(18deg) translateY(8px);transition:opacity 460ms ease-in-out,transform 460ms ease-in-out;text-shadow:0 1px 2px rgba(0,0,0,0.4)}'
       . 'body.impulse-on-chat-screen .impulse-chat-pointer-label{opacity:1;transform:rotate(18deg) translateY(0);transition:opacity 460ms ease-in-out 980ms,transform 460ms ease-in-out 980ms}';
    if (function_exists('wp_add_inline_style')) wp_add_inline_style('instinctor-page-inline', $_cpCss);

    // Path explanation:
    //   M 8 12   start at upper-left of the SVG box (which sits in
    //            the lower-right viewport quadrant, so this maps to
    //            ~mid-viewport center-low).
    //   Q 60 30  control point near top-right — pulls the curve
    //            outward then down toward the corner.
    //   95 92    endpoint near the SVG bottom-right corner, where
    //            the chat trigger sits (#instinctor-chat anchors at
    //            right:20px;bottom:24px in chat-widget.css).
    // The marker triangle at the path's end completes the arrow head.
    echo '<div class="impulse-chat-pointer" aria-hidden="true">'
       . '<svg viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet" xmlns="http://www.w3.org/2000/svg">'
       . '<defs><marker id="impulse-chat-arrowhead" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">'
       . '<path d="M0,0 L10,5 L0,10 z" fill="currentColor"/>'
       . '</marker></defs>'
       . '<path class="impulse-chat-pointer-path" d="M 8 12 Q 60 30 92 90" marker-end="url(#impulse-chat-arrowhead)"/>'
       . '</svg>'
       . '<span class="impulse-chat-pointer-label">Ask anything</span>'
       . '</div>';

    // ── JS: toggle body.impulse-on-chat-screen ─────────────────────
    //
    // Same observation pattern as impulse-hero-sandbox.php — wrap
    // ImpulseScreens.goToScreen / jumpToScreen AND install a
    // MutationObserver on .impulse-screen-active for the internal
    // wheel/keyboard/drag paths that bypass the public API.
    //
    // The fallback selector for the editor iframe (.impulse-el wrapper
    // around section) matches the hero-sandbox script — both contexts
    // need this for the pointer to flicker in/out as the user navigates.
    $_cpJs = '(function(){'
       . 'var _cpTries=0;'
       . 'function _cpToggle(el){try{if(!el){document.body.classList.remove("impulse-on-chat-screen");return;}var hasMark=el.hasAttribute("data-chat-marker")||!!el.querySelector("[data-chat-marker]");document.body.classList.toggle("impulse-on-chat-screen",hasMark);}catch(_e){}}'
       . 'function _cpWrapScreens(){var IS=window.ImpulseScreens;if(!IS){if(++_cpTries<=60)setTimeout(_cpWrapScreens,50);return;}if(IS._cpWrapped)return;["goToScreen","jumpToScreen"].forEach(function(name){var o=IS[name];if(typeof o!=="function")return;IS[name]=function(idx){try{var w=document.querySelector(".impulse-screen-wrapper");var sel=":scope > .impulse-screen";if(!w){w=document.querySelector(".impulse-content-wrapper");sel=":scope > .impulse-el[data-type=\\"section\\"]";}if(w){var sc=w.querySelectorAll(sel);if(sc[idx])_cpToggle(sc[idx]);}}catch(_e){}return o.apply(this,arguments);};});IS._cpWrapped=true;}'
       . 'function _cpObserveActive(){try{if(window._cpObserverInstalled)return;var w=document.querySelector(".impulse-screen-wrapper");var sel=":scope > .impulse-screen";if(!w){w=document.querySelector(".impulse-content-wrapper");sel=":scope > .impulse-el[data-type=\\"section\\"]";}if(!w){if(++_cpTries<=60)setTimeout(_cpObserveActive,50);return;}var sections=w.querySelectorAll(sel);if(!sections.length){if(++_cpTries<=60)setTimeout(_cpObserveActive,50);return;}var mo=new MutationObserver(function(muts){for(var i=0;i<muts.length;i++){var m=muts[i];if(m.attributeName!=="class")continue;if(m.target.classList.contains("impulse-screen-active")){_cpToggle(m.target);}}});sections.forEach(function(s){mo.observe(s,{attributes:true,attributeFilter:["class"]});});window._cpObserverInstalled=true;'
       . 'var existing=w.querySelector(".impulse-screen-active");if(existing)_cpToggle(existing);'
       . '}catch(_e){}}'
       . 'if(document.readyState==="loading"){document.addEventListener("DOMContentLoaded",function(){_cpWrapScreens();_cpObserveActive();});}else{_cpWrapScreens();_cpObserveActive();}'
       . '})();';
    if (function_exists('wp_add_inline_script')) wp_add_inline_script('instinctor-frontend-js', $_cpJs, 'after');
}
