<?php
/**
 * PS_Consent_Manager — plugin-wide consent + telemetry handler
 *
 * SHARED CODEBASE z PRO v3.5.0 ACTIVATOR/class-activator.php (commit f496d71).
 * Adaptation: cp + sed namespace (inpost_* → parcsepa_*, InPost_Activator → PS_Consent_Manager).
 * NO new business logic — FREE consents to API connection, telemetry, optional email.
 *
 * NOTE for WP.org reviewer: methods process_personal_data() + process_company_data()
 * remain in this file as DEAD CODE for parity with PRO codebase. They are NEVER called
 * in FREE because step-personal.php and step-company.php are NOT shipped (FREE uses
 * single-screen consent-notice.php, not 6-step wizard). PHP ignores unused methods.
 *
 * @package ParcelSelector
 */

// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}

class Parcselect_Consent_Manager {
    
    /**
     * Singleton instance
     * @var PS_Consent_Manager
     */
    private static $instance = null;
    
    /**
     * Current wizard step
     * @var int
     */
    private $current_step = 1;
    
    /**
     * Total wizard steps
     * @var int
     */
    private $total_steps = 6;
    
    /**
     * Get singleton instance
     * 
     * @return PS_Consent_Manager
     */
    public static function get_instance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Constructor - register hooks
     */
    private function __construct() {
        // Register activation hook redirect
        // Handle POST form submissions from wizard steps 2, 3, 4
        add_action('admin_init', [$this, 'handle_wizard_post']);
        // Handle one-click anonymous (Free Basic) activation

        // Register admin menu

        // Register AJAX handlers
        add_action('wp_ajax_parcselect_collect_diagnostics', [$this, 'ajax_collect_diagnostics']);

        // v4.2.9: WP.org compliance — block ALL phone-home to parcelselector.com BEFORE consent.
        // Pattern: WP-native pre_http_request filter (https://developer.wordpress.org/reference/hooks/pre_http_request/)
        // ALLOW: localhost (Oracle on same server, data never leaves shop), 3rd party APIs (Solana RPC, CoinGecko, etc.)
        // ALLOW (v4.3.0): infrastructure subdomains map./oracle./cdn./api. — NOT telemetry, required for plugin operation.
        // BLOCK: parcelselector.com (root) + www.parcelselector.com calls until parcselect_consent_given option is true.
        add_filter('pre_http_request', [$this, 'maybe_block_phone_home'], 5, 3);

        // v4.3.0: Wire-up consent notice in admin (template existed since v4.2.0 but not rendered)
        add_action('admin_notices', [$this, 'maybe_render_consent_notice']);

        // Enqueue assets
    }

    /**
     * v4.3.0: Render consent notice in admin if not yet given.
     * Notice template: admin-panel/notices/consent-notice.php
     */
    public function maybe_render_consent_notice() {
        if ( ! current_user_can('manage_options') ) {
            return;
        }
        if ( get_option('parcselect_consent_given') ) {
            return; // already given
        }
        if ( get_user_meta( get_current_user_id(), 'parcselect_consent_notice_dismissed', true ) ) {
            return; // user dismissed for this session
        }
        $tpl = plugin_dir_path( __FILE__ ) . '../admin-panel/notices/consent-notice.php';
        if ( file_exists( $tpl ) ) {
            include $tpl;
        }
    }

    /**
     * v4.2.9: Pre-http_request filter — block parcelselector.com phone-home BEFORE user consent.
     *
     * @param false|array|WP_Error $preempt Whether to preempt the request (false = let WP handle).
     * @param array                $args    Request args.
     * @param string               $url     Request URL.
     * @return false|array|WP_Error
     */
    public function maybe_block_phone_home($preempt, $args, $url) {
        if ($preempt !== false) {
            return $preempt; // already pre-empted by another filter
        }
        $host = strtolower( (string) wp_parse_url( $url, PHP_URL_HOST ) );
        if ( '' === $host ) {
            return false; // malformed url — let WP handle
        }
        // ALLOW: localhost (Oracle gunicorn on same server — data NEVER leaves shop)
        if ( '127.0.0.1' === $host || 'localhost' === $host || '::1' === $host ) {
            return false;
        }
        // ALLOW (v4.3.0): infrastructure subdomains — required for plugin operation, NOT telemetry.
        // map.parcelselector.com   = paczkomat directory proxy (read-only point lookups)
        // oracle.parcelselector.com = Solana label oracle (HMAC-signed)
        // cdn.parcelselector.com   = static assets (flags, icons)
        // api.parcelselector.com   = carrier matrix endpoint
        $infrastructure = [
            'map.parcelselector.com',
            'oracle.parcelselector.com',
            'cdn.parcelselector.com',
            'api.parcelselector.com',
        ];
        if ( in_array( $host, $infrastructure, true ) ) {
            return false;
        }
        // CHECK: only OUR root domain requires consent (telemetry/marketing/diagnostics)
        if ( 'parcelselector.com' !== $host && 'www.parcelselector.com' !== $host ) {
            return false; // 3rd party (Solana RPC, CoinGecko, blockscout, etc.) — disclosed in readme.txt
        }
        // OUR root domain — require consent
        if ( get_option('parcselect_consent_given') ) {
            return false;
        }
        // BLOCK
        return new WP_Error(
            'parcselect_consent_required',
            __( 'parcelselector.com communication blocked: user consent not granted (Settings → Privacy).', 'parcel-selector' )
        );
    }
    
    /**
     * Redirect to wizard after activation (only once)
     * NOTE: Auto-redirect is DISABLED by default to not interfere with Quick Shipping module
     * To enable: add_filter('parcselect_enable_activation_redirect', '__return_true');
     */
    public function maybe_redirect_to_wizard() {
        if ( ! current_user_can('manage_options') || wp_doing_ajax() || isset($_GET['activate-multi']) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- reading URL flag after activation redirect, capability-checked.
            return;
        }

        // After plugin activation: redirect to Settings with welcome notice.
        if ( get_transient('parcselect_activation_redirect') ) {
            delete_transient('parcselect_activation_redirect');
            wp_safe_redirect( admin_url('admin.php?page=parcelselector-settings&ps_welcome=1') );
            exit;
        }

        // FREE auto-activation: do NOT force redirect to wizard when not activated yet
        // (the retry cron will complete activation asynchronously).
    }
    
    
    




    

    /**
     * Handle POST form submissions from wizard steps 2, 3, 4.
     * Runs on admin_init — processes the form, then redirects (POST-redirect-GET).
     */
    public function handle_wizard_post() {
        if ( ! isset( $_POST['ps_wizard_step'] ) ) {
            return;
        }
        if ( ! current_user_can( 'manage_options' ) ) {
            return;
        }

        $step = absint( $_POST['ps_wizard_step'] );
        if ( $step < 2 || $step > 4 ) {
            return;
        }

        // Verify nonce
        $nonce_action = 'ps_wizard_step_' . $step;
        if ( ! isset( $_POST['ps_wizard_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['ps_wizard_nonce'] ) ), $nonce_action ) ) {
            wp_die( esc_html__( 'Security check failed.', 'parcel-selector' ) );
        }

        // Build redirect base URL from hidden context fields
        $page    = isset( $_POST['ps_page'] )    ? sanitize_key( wp_unslash( $_POST['ps_page'] ) )    : 'parcelselector-settings';
        $tab     = isset( $_POST['ps_tab'] )     ? sanitize_key( wp_unslash( $_POST['ps_tab'] ) )     : 'activator';
        $upgrade = isset( $_POST['ps_upgrade'] ) && '1' === $_POST['ps_upgrade'];
        $rerun   = isset( $_POST['ps_rerun'] )   && '1' === $_POST['ps_rerun'];

        if ( 'parcelselector-settings' === $page ) {
            $base = admin_url( 'admin.php?page=parcelselector-settings&tab=' . $tab );
        } else {
            $base = admin_url( 'admin.php?page=' . $page );
        }
        if ( $upgrade ) { $base .= '&upgrade=1'; }
        if ( $rerun   ) { $base .= '&rerun=1';   }

        // Process the step
        switch ( $step ) {
            case 2:
                $data   = [
                    'admin_name'  => isset( $_POST['admin_name'] )  ? sanitize_text_field( wp_unslash( $_POST['admin_name'] ) )  : '',
                    'admin_email' => isset( $_POST['admin_email'] ) ? sanitize_email( wp_unslash( $_POST['admin_email'] ) )       : '',
                    'admin_phone' => isset( $_POST['admin_phone'] ) ? sanitize_text_field( wp_unslash( $_POST['admin_phone'] ) )  : '',
                ];
                $result     = $this->process_personal_data( $data );
                $next_step  = 3;
                break;

            case 3:
                $country        = isset( $_POST['company_country'] )        ? sanitize_text_field( wp_unslash( $_POST['company_country'] ) )        : '';
                $country_custom = isset( $_POST['company_country_custom'] ) ? sanitize_text_field( wp_unslash( $_POST['company_country_custom'] ) ) : '';
                // If user selected "OTHER" and typed a custom ISO code, use it instead
                if ( 'OTHER' === $country && '' !== $country_custom ) {
                    $country = strtoupper( substr( $country_custom, 0, 5 ) );
                }
                $data   = [
                    'company_name'    => isset( $_POST['company_name'] )    ? sanitize_text_field( wp_unslash( $_POST['company_name'] ) )    : '',
                    'company_address' => isset( $_POST['company_address'] ) ? sanitize_text_field( wp_unslash( $_POST['company_address'] ) ) : '',
                    'company_city'    => isset( $_POST['company_city'] )    ? sanitize_text_field( wp_unslash( $_POST['company_city'] ) )    : '',
                    'company_postal'  => isset( $_POST['company_postal'] )  ? sanitize_text_field( wp_unslash( $_POST['company_postal'] ) )  : '',
                    'company_country' => $country,
                    'company_tax_id'  => isset( $_POST['company_tax_id'] )  ? sanitize_text_field( wp_unslash( $_POST['company_tax_id'] ) )  : '',
                ];
                $result     = $this->process_company_data( $data );
                $next_step  = 4;
                break;

            case 4:
                $data   = [
                    'terms_accepted'      => isset( $_POST['terms_accepted'] )      ? '1' : '',
                    'privacy_accepted'    => isset( $_POST['privacy_accepted'] )    ? '1' : '',
                    'diagnostics_consent' => isset( $_POST['diagnostics_consent'] ) ? '1' : '',
                ];
                $result     = $this->process_consent( $data );
                $next_step  = 5;
                break;

            default:
                return;
        }

        if ( $result['success'] ) {
            wp_safe_redirect( $base . '&step=' . $next_step );
            exit;
        } else {
            // Store error in transient, go back to same step with error notice
            set_transient( 'parcselect_wizard_error_' . get_current_user_id(), $result['message'], 60 );
            wp_safe_redirect( $base . '&step=' . $step );
            exit;
        }
    }

    
    
    
    /**
     * Process consent (Step 4)
     * 
     * @param array $data Form data
     * @return array Result
     */
    private function process_consent($data) {
        // Terms and Privacy are REQUIRED
        if (empty($data['terms_accepted']) || empty($data['privacy_accepted'])) {
            return [
                'success' => false,
                'message' => __('You must accept Terms of Service and Privacy Policy to continue.', 'parcel-selector'),
            ];
        }
        
        update_option('parcselect_activation_consent', [
            'terms_accepted' => true,
            'terms_accepted_at' => current_time('mysql'),
            'terms_version' => '1.0',
            'privacy_accepted' => true,
            'privacy_accepted_at' => current_time('mysql'),
            'privacy_version' => '1.0',
            'diagnostics_consent' => !empty($data['diagnostics_consent']),
            'diagnostics_consent_at' => !empty($data['diagnostics_consent']) ? current_time('mysql') : null,
            'source' => 'wizard',
        ]);

        // WP.org compliance: mark consent as given so silent activation can proceed.
        update_option( 'parcselect_consent_given', true );

        return ['success' => true];
    }
    
    
    /**
     * AJAX handler - Collect diagnostics
     */
    public function ajax_collect_diagnostics() {
        check_ajax_referer('parcselect_consent_nonce', 'nonce');
        
        require_once plugin_dir_path(__FILE__) . 'class-ps-data-collector.php';
        $collector = new Parcselect_Data_Collector();
        
        $diagnostics = $collector->collect_all();
        
        wp_send_json_success($diagnostics);
    }
}

// Initialize
Parcselect_Consent_Manager::get_instance();
