<?php

/**
 * TrackSharp Loader
 * 
 * Central autoloader and dependency injection container.
 *
 * @package TrackSharp
 */
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
class TrackSharp_Loader {
    /** @var TrackSharp_Consent */
    private $consent;

    /** @var TrackSharp_Hasher */
    private $hasher;

    /** @var TrackSharp_Events_Log */
    private $events_log;

    /** @var TrackSharp_GA4 */
    private $ga4;

    /** @var TrackSharp_Meta */
    private $meta;

    /** @var TrackSharp_REST */
    private $rest;

    /** @var TrackSharp_WooCommerce */
    private $woocommerce;

    /** @var TrackSharp_Admin */
    private $admin;

    /** @var TrackSharp_Pricing_Page */
    private $pricing_page;

    /** @var TrackSharp_License_Page */
    private $license_page;

    /**
     * Initialize the plugin.
     *
     * @return void
     */
    public function init() {
        $this->load_dependencies();
        $this->instantiate_classes();
        $this->register_hooks();
    }

    /**
     * Load all class files.
     *
     * @return void
     */
    private function load_dependencies() {
        $includes_path = TRACKSHARP_PLUGIN_DIR . 'includes/';
        $admin_path = TRACKSHARP_PLUGIN_DIR . 'includes/admin/';
        // Core classes (Free features)
        require_once $includes_path . 'class-tracksharp-consent.php';
        require_once $includes_path . 'class-tracksharp-events-log.php';
        require_once $includes_path . 'class-tracksharp-ga4.php';
        require_once $includes_path . 'class-tracksharp-rest.php';
        require_once $includes_path . 'class-tracksharp-woocommerce.php';
        // Admin classes (Free)
        require_once $admin_path . 'class-tracksharp-settings.php';
        require_once $admin_path . 'class-tracksharp-wizard.php';
        require_once $admin_path . 'class-tracksharp-dashboard.php';
        require_once $admin_path . 'class-tracksharp-events-page.php';
        require_once $admin_path . 'class-tracksharp-admin.php';
        // Using Freemius default pricing/license pages instead of custom ones
    }

    /**
     * Instantiate all classes with dependency injection.
     *
     * @return void
     */
    private function instantiate_classes() {
        // Core services (Free)
        $this->consent = new TrackSharp_Consent();
        $this->events_log = new TrackSharp_Events_Log();
        $this->ga4 = new TrackSharp_GA4();
        // Pro services:
        // - code exists only in premium builds (Freemius-stripped from free).
        // - runtime activation depends on license state.
        if ( TrackSharp_Features::is_pro_active() ) {
            $this->hasher = new TrackSharp_Hasher();
            $this->meta = new TrackSharp_Meta();
        } else {
            $this->hasher = null;
            $this->meta = null;
        }
        // REST API
        $this->rest = new TrackSharp_REST(
            $this->consent,
            $this->hasher,
            $this->ga4,
            $this->meta,
            $this->events_log
        );
        // WooCommerce integration
        $this->woocommerce = new TrackSharp_WooCommerce(
            $this->consent,
            $this->hasher,
            $this->ga4,
            $this->meta,
            $this->events_log
        );
        // Admin pages
        $settings = new TrackSharp_Settings($this->ga4, $this->meta, $this->events_log);
        $wizard = new TrackSharp_Wizard($this->ga4, $this->meta);
        $dashboard = new TrackSharp_Dashboard($this->events_log);
        $events_page = new TrackSharp_Events_Page($this->events_log);
        // Using Freemius default pricing/license pages
        $this->admin = new TrackSharp_Admin(
            $this->events_log,
            $settings,
            $wizard,
            $dashboard,
            $events_page
        );
    }

    /**
     * Register all WordPress hooks.
     *
     * @return void
     */
    private function register_hooks() {
        // REST API
        add_action( 'rest_api_init', [$this->rest, 'register_routes'] );
        // WooCommerce
        $this->woocommerce->register_hooks();
        // Referral preservation (TAGGRS method 4)
        add_action( 'wp_head', [$this, 'capture_initial_referrer'], 1 );
        // Admin
        if ( is_admin() ) {
            $this->admin->register_hooks();
            // Using Freemius default pricing/license pages
        }
        // Frontend script
        add_action( 'wp_enqueue_scripts', [$this, 'enqueue_frontend_script'], 20 );
        add_action( 'wp_enqueue_scripts', [$this, 'enqueue_checkout_pre_redirect_audit'], 21 );
        // Cron
        add_action( 'tracksharp_prune_events', [$this->events_log, 'cron_prune_events'] );
        add_action( 'tracksharp_ga4_purchase_fallback', [$this->woocommerce, 'send_ga4_purchase_fallback'] );
        // Consent filters
        add_filter( 'tracksharp_ga4_requires_marketing', '__return_false' );
        add_filter(
            'tracksharp_tracker_is_consent_granted',
            [$this->consent, 'allow_stats_anonymous_for_ga4'],
            10,
            2
        );
    }

    /**
     * Enqueue the frontend tracking script.
     *
     * @return void
     */
    public function enqueue_frontend_script() {
        if ( is_admin() ) {
            return;
        }
        $asset_path = TRACKSHARP_PLUGIN_DIR . 'assets/tracksharp-tracker.js';
        $ver = ( file_exists( $asset_path ) ? filemtime( $asset_path ) : time() );
        wp_register_script(
            'tracksharp-tracker',
            TRACKSHARP_PLUGIN_URL . 'assets/tracksharp-tracker.js',
            [],
            $ver,
            false
        );
        // Default consent (deny)
        $consent = [
            'ad_storage'         => 'denied',
            'ad_user_data'       => 'denied',
            'ad_personalization' => 'denied',
        ];
        $consent = apply_filters( 'tracksharp_tracker_frontend_consent', $consent );
        // Build product payload for PDPs
        $product_payload = null;
        if ( function_exists( 'is_product' ) && is_product() && function_exists( 'wc_get_product' ) ) {
            global $product;
            $p = null;
            if ( is_object( $product ) && method_exists( $product, 'get_id' ) ) {
                $p = $product;
            } else {
                $pid = 0;
                if ( is_numeric( $product ) ) {
                    $pid = (int) $product;
                }
                if ( !$pid && function_exists( 'get_queried_object_id' ) ) {
                    $pid = (int) get_queried_object_id();
                }
                if ( $pid ) {
                    $p = wc_get_product( $pid );
                }
            }
            if ( $p && is_object( $p ) && method_exists( $p, 'get_id' ) ) {
                $price = ( function_exists( 'wc_get_price_including_tax' ) ? (float) wc_get_price_including_tax( $p ) : (float) $p->get_price() );
                $product_payload = [
                    'item_id'   => (string) $p->get_id(),
                    'item_name' => $p->get_name(),
                    'price'     => $price,
                ];
            }
        }
        // Expose config
        wp_localize_script( 'tracksharp-tracker', 'TRACKSHARP_TRACKER', [
            'ga4_mid'                 => trim( get_option( 'tracksharp_ga4_measurement_id', '' ) ),
            'ga4_purchase_event_name' => TrackSharp_Features::ga4_purchase_event_name(),
            'ga4_attribution_mode'    => TrackSharp_Features::ga4_attribution_mode(),
            'meta_pixel_id'           => ( TrackSharp_Features::is_meta_available() ? trim( get_option( 'tracksharp_meta_pixel_id', '' ) ) : '' ),
            'rest_url'                => esc_url_raw( rest_url( 'tracksharp/v1/p' ) ),
            'session_cookie_name'     => 'ws_session_id',
            'consent'                 => $consent,
            'is_product'              => ( function_exists( 'is_product' ) ? is_product() : false ),
            'product'                 => $product_payload,
            'currency'                => ( function_exists( 'get_woocommerce_currency' ) ? get_woocommerce_currency() : 'EUR' ),
            'consent_fallback'        => get_option( 'tracksharp_consent_fallback', 'grant_immediately' ),
            'nonce'                   => wp_create_nonce( 'wp_rest' ),
        ] );
        wp_localize_script( 'tracksharp-tracker', 'TRACKSHARP_SERVER_CONSENT', [
            'meta' => $this->consent->server_consent_granted_for( 'meta' ),
            'ga4'  => $this->consent->server_consent_granted_for( 'ga4' ),
        ] );
        wp_enqueue_script( 'tracksharp-tracker' );
        wp_add_inline_script( 'tracksharp-tracker', 'console.log("[WS] tracksharp-tracker enqueued v=' . esc_js( $ver ) . '");', 'before' );
    }

    /**
     * Enqueue checkout pre-redirect audit script.
     *
     * @return void
     */
    public function enqueue_checkout_pre_redirect_audit() {
        if ( is_admin() || !function_exists( 'is_checkout' ) || !is_checkout() ) {
            return;
        }
        if ( !wp_script_is( 'tracksharp-tracker', 'enqueued' ) ) {
            return;
        }
        $js = '(function(){';
        $js .= 'if (!window.jQuery) return;';
        $js .= 'jQuery(document.body).on("checkout_place_order_success", function(e, result){';
        $js .= 'try {';
        $js .= 'var url = (result && result.redirect) || "";';
        $js .= 'var m = url && (url.match(/(?:order-received|order-pay)\\/\\/(\\d+)\\//) || url.match(/[?&]order=(\\d+)/));';
        $js .= 'var orderId = m ? m[1] : null;';
        $js .= 'if (!orderId || !window.TrackSharpTracker || typeof window.TrackSharpTracker.postEvent !== "function") return;';
        $js .= 'window.TrackSharpTracker.postEvent("purchase_pre", {';
        $js .= 'ecom: { transaction_id: String(orderId) },';
        $js .= '__skip_server: true';
        $js .= '});';
        $js .= '} catch(_){}';
        $js .= '});';
        $js .= '})();';
        wp_add_inline_script( 'tracksharp-tracker', $js, 'after' );
    }

    /**
     * Plugin activation handler.
     *
     * @return void
     */
    public static function activate() {
        // Create database table
        TrackSharp_Events_Log::create_table();
        // Set default options
        if ( get_option( 'tracksharp_consent_fallback', null ) === null ) {
            add_option( 'tracksharp_consent_fallback', 'grant_immediately' );
        }
        // Redirect to wizard after activation
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only check during activation redirect logic.
        if ( !is_network_admin() && !isset( $_GET['activate-multi'] ) ) {
            add_option( 'tracksharp_do_activation_redirect', 1 );
        }
        // Schedule cron
        if ( !wp_next_scheduled( 'tracksharp_prune_events' ) ) {
            wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'tracksharp_prune_events' );
        }
    }

    /**
     * Capture initial referrer high in the head.
     *
     * @return void
     */
    public function capture_initial_referrer() {
        $js = '(function(){';
        $js .= 'try {';
        $js .= 'var ref = document.referrer;';
        $js .= 'var host = location.hostname;';
        $js .= 'if (ref && ref.indexOf(host) === -1) {';
        $js .= 'if (!sessionStorage.getItem("ws_initial_referrer")) {';
        $js .= 'sessionStorage.setItem("ws_initial_referrer", ref);';
        $js .= '}';
        $js .= '}';
        $js .= '} catch(_){}';
        $js .= '})();';
        echo '<script>' . $js . '</script>' . "\n";
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

}
