<?php
/**
 * REST API Tracking Engine for Opens and Clicks.
 * Secured via Stateless Cryptographic Hashes.
 */

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

class PexEmail_Tracking {

    public function init() {
        add_action( 'rest_api_init', [ $this, 'register_tracking_routes' ] );
    }

    public static function generate_tracking_hash( $campaign_id, $recipient_id ) {
        return substr( wp_hash( $campaign_id . 'pexally' . $recipient_id ), 0, 10 );
    }

    public function register_tracking_routes() {
        register_rest_route( 'pex-campaign/v1', '/track/open/(?P<campaign_id>\d+)/(?P<recipient_id>\d+)/(?P<hash>[a-zA-Z0-9]+)', [
            'methods'             => 'GET',
            'callback'            => [ $this, 'track_open' ],
            'permission_callback' => '__return_true' 
        ] );

        register_rest_route( 'pex-campaign/v1', '/track/click/(?P<campaign_id>\d+)/(?P<recipient_id>\d+)/(?P<hash>[a-zA-Z0-9]+)', [
            'methods'             => 'GET',
            'callback'            => [ $this, 'track_click' ],
            'permission_callback' => '__return_true'
        ] );
    }

    private function verify_hash( $campaign_id, $recipient_id, $provided_hash ) {
        $expected_hash = self::generate_tracking_hash( $campaign_id, $recipient_id );
        return hash_equals( $expected_hash, $provided_hash );
    }

    public function track_open( WP_REST_Request $request ) {
        if ( ! defined( 'DONOTCACHEPAGE' ) ) { 
            define( 'DONOTCACHEPAGE', true ); 
        }
        
        global $wpdb;
        $campaign_id  = intval( $request->get_param( 'campaign_id' ) );
        $recipient_id = intval( $request->get_param( 'recipient_id' ) );
        $hash         = sanitize_text_field( $request->get_param( 'hash' ) );

        if ( $campaign_id > 0 && $recipient_id > 0 && $this->verify_hash( $campaign_id, $recipient_id, $hash ) ) {
            $wpdb->update( 
                $wpdb->prefix . 'pexemail_recipients', 
                [ 'opened' => 1 ], 
                [ 'id' => $recipient_id ],
                [ '%d' ],
                [ '%d' ]
            );
            $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}pexemail_campaigns SET opens = COALESCE(opens, 0) + 1 WHERE id = %d", $campaign_id ) );
        }

        header( 'Content-Type: image/gif' );
        header( 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0' );
        header( 'Pragma: no-cache' );
        header( 'Expires: 0' );
        
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        echo base64_decode( 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' );
        exit;
    }

    public function track_click( WP_REST_Request $request ) {
        if ( ! defined( 'DONOTCACHEPAGE' ) ) { 
            define( 'DONOTCACHEPAGE', true ); 
        }
        
        global $wpdb;
        $campaign_id  = intval( $request->get_param( 'campaign_id' ) );
        $recipient_id = intval( $request->get_param( 'recipient_id' ) );
        $hash         = sanitize_text_field( $request->get_param( 'hash' ) );
        
        // FIX: Rely on WordPress REST API native param extraction which handles URL decoding automatically
        $url_param = $request->get_param( 'url' );
        $url = ! empty( $url_param ) ? $url_param : '';

        if ( $campaign_id > 0 && $recipient_id > 0 && ! empty( $url ) && $this->verify_hash( $campaign_id, $recipient_id, $hash ) ) {
            $wpdb->update( 
                $wpdb->prefix . 'pexemail_recipients', 
                [ 'clicked' => 1, 'opened' => 1 ], 
                [ 'id' => $recipient_id ],
                [ '%d', '%d' ],
                [ '%d' ]
            );
            $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}pexemail_campaigns SET clicks = COALESCE(clicks, 0) + 1 WHERE id = %d", $campaign_id ) );
        }

        $redirect_url = esc_url_raw( $url );
        if ( empty( $redirect_url ) ) {
            $redirect_url = home_url(); 
        }
        
        header( 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0' );
        header( 'Pragma: no-cache' );
        header( 'Expires: 0' );
        
        wp_redirect( $redirect_url, 302 );
        exit;
    }
}