<?php
/**
 * Front-end tour rendering and shortcode.
 *
 * @package BW_Onboarding_Guide
 */

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

class BW_Frontend {

    private static $instance = null;
    private $guides_output   = array();

    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) );
        add_action( 'wp_footer', array( $this, 'output_tour_data' ), 99 );
        add_shortcode( 'bw_onboarding_guide', array( $this, 'shortcode' ) );
    }

    /**
     * Enqueue front-end assets on pages where guides are active.
     */
    public function enqueue_assets() {
        $guides = $this->get_active_guides();
        if ( empty( $guides ) ) {
            return;
        }

        wp_enqueue_style(
            'bw-tour-css',
            BW_ONBOARDING_URL . 'assets/css/bw-tour.css',
            array(),
            BW_ONBOARDING_VERSION
        );

        wp_enqueue_script(
            'bw-tour-js',
            BW_ONBOARDING_URL . 'assets/js/bw-tour.js',
            array( 'jquery' ),
            BW_ONBOARDING_VERSION,
            true
        );

        // Pass settings and guide data to JS
        $settings = array(
            'primaryColor'   => get_option( 'bw_onboarding_primary_color', '#2B2663' ),
            'accentColor'    => get_option( 'bw_onboarding_accent_color', '#1fa88e' ),
            'allowRestart'   => get_option( 'bw_onboarding_allow_restart', '1' ),
            'animationSpeed' => intval( get_option( 'bw_onboarding_animation_speed', 400 ) ),
            'overlayOpacity' => intval( get_option( 'bw_onboarding_overlay_opacity', 70 ) ),
            'ajaxUrl'        => admin_url( 'admin-ajax.php' ),
            'nonce'          => wp_create_nonce( 'bw_onboarding_nonce' ),
            'isLoggedIn'     => is_user_logged_in(),
            'currentUrl'     => $this->get_current_path(),
            'guides'         => $this->format_guides_for_js( $guides ),
        );

        wp_localize_script( 'bw-tour-js', 'bwOnboardingData', $settings );

        // Inject custom CSS variables
        $custom_css = sprintf(
            ':root { --bw-primary: %s; --bw-accent: %s; --bw-overlay-opacity: %s; --bw-animation-speed: %sms; }',
            esc_attr( $settings['primaryColor'] ),
            esc_attr( $settings['accentColor'] ),
            esc_attr( $settings['overlayOpacity'] / 100 ),
            esc_attr( $settings['animationSpeed'] )
        );
        wp_add_inline_style( 'bw-tour-css', $custom_css );
    }

    /**
     * Get active guides for the current page and user context.
     */
    private function get_active_guides() {
        $args = array(
            'post_type'      => 'bw_guide',
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'meta_query'     => array(),
        );

        $guides = get_posts( $args );
        $active = array();

        foreach ( $guides as $guide ) {
            if ( $this->should_show_guide( $guide ) ) {
                $active[] = $guide;
            }
        }

        return $active;
    }

    /**
     * Determine if a guide should be shown to the current user on the current page.
     */
    private function should_show_guide( $guide ) {
        $show_to    = get_post_meta( $guide->ID, '_bw_show_to', true ) ?: 'logged_in';
        $show_once  = get_post_meta( $guide->ID, '_bw_show_once', true );
        $trigger_url = get_post_meta( $guide->ID, '_bw_trigger_url', true );
        $auto_start = get_post_meta( $guide->ID, '_bw_auto_start', true );

        // Check audience
        if ( 'logged_in' === $show_to && ! is_user_logged_in() ) {
            return false;
        }
        if ( 'logged_out' === $show_to && is_user_logged_in() ) {
            return false;
        }

        // Check trigger URL (only for auto-start guides)
        if ( $auto_start && ! empty( $trigger_url ) ) {
            $current_path = $this->get_current_path();
            $trigger_path = untrailingslashit( $trigger_url );
            $current_clean = untrailingslashit( $current_path );

            if ( $trigger_path !== $current_clean ) {
                return false;
            }
        }

        // Check if already completed (logged-in users only; visitors handled in JS via localStorage)
        if ( $show_once && is_user_logged_in() ) {
            $completed = get_user_meta( get_current_user_id(), 'bw_onboarding_completed', true );
            if ( is_array( $completed ) && isset( $completed[ $guide->ID ] ) ) {
                // Still include in output so JS can offer restart if allowed
                // but mark as completed
                return true;
            }
        }

        return true;
    }

    /**
     * Format guides for JavaScript consumption.
     */
    private function format_guides_for_js( $guides ) {
        $output = array();

        foreach ( $guides as $guide ) {
            $steps = get_post_meta( $guide->ID, '_bw_steps', true );
            if ( ! is_array( $steps ) || empty( $steps ) ) {
                continue;
            }

            $completed = false;
            if ( is_user_logged_in() ) {
                $user_completed = get_user_meta( get_current_user_id(), 'bw_onboarding_completed', true );
                $completed = is_array( $user_completed ) && isset( $user_completed[ $guide->ID ] );
            }

            $output[] = array(
                'id'        => $guide->ID,
                'title'     => $guide->post_title,
                'autoStart' => get_post_meta( $guide->ID, '_bw_auto_start', true ) === '1',
                'showOnce'  => get_post_meta( $guide->ID, '_bw_show_once', true ) === '1',
                'completed' => $completed,
                'steps'     => array_map( function( $step ) {
                    return array(
                        'title'    => $step['title'],
                        'content'  => $step['content'],
                        'selector' => $step['target_selector'],
                        'position' => $step['position'],
                        'url'      => $step['url'],
                        'btnLabel' => $step['button_label'],
                        'tip'      => $step['tip'],
                    );
                }, $steps ),
            );
        }

        return $output;
    }

    /**
     * Get the current request path.
     */
    private function get_current_path() {
        $path = wp_parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
        return $path ? $path : '/';
    }

    /**
     * Output tour data in the footer (fallback if localize didn't fire).
     */
    public function output_tour_data() {
        // The data is already passed via wp_localize_script.
        // This hook is reserved for any additional HTML the tour needs.
    }

    /**
     * Shortcode: [bw_onboarding_guide id="123"]
     *
     * Renders a "Start Tour" button that triggers the specified guide.
     */
    public function shortcode( $atts ) {
        $atts = shortcode_atts( array(
            'id'    => 0,
            'label' => __( 'Start Tour', 'bw-onboarding-guide' ),
            'class' => '',
        ), $atts, 'bw_onboarding_guide' );

        $guide_id = intval( $atts['id'] );
        if ( ! $guide_id ) {
            return '';
        }

        // Verify the guide exists and is published
        $guide = get_post( $guide_id );
        if ( ! $guide || 'publish' !== $guide->post_status || 'bw_guide' !== $guide->post_type ) {
            return '';
        }

        // Ensure assets are enqueued
        if ( ! wp_script_is( 'bw-tour-js', 'enqueued' ) ) {
            $this->enqueue_assets();
        }

        $extra_class = $atts['class'] ? ' ' . esc_attr( $atts['class'] ) : '';

        return sprintf(
            '<button type="button" class="bw-start-tour-btn%s" data-bw-guide-id="%d" onclick="bwOnboarding.start(%d)">%s</button>',
            $extra_class,
            $guide_id,
            $guide_id,
            esc_html( $atts['label'] )
        );
    }
}
