<?php
/**
 * Plugin Name: Stablezact Crypto Payments for WooCommerce
 * Plugin URI: https://docs.stablezact.com
 * Description: An entirely new payment infrastructure, built with blockchain technology, to simplify global crypto transactions.
 * Version: 1.1.9
 * Author: Stablezact
 * Author URI: https://stablezact.com
 * License: GPL-2.0+
 * Text Domain: stablezact-crypto-payments
 * Requires at least: 6.4
 * Tested up to: 7.1
 * Requires PHP: 7.4
 * WC requires at least: 8.0
 * WC tested up to: 10.9
 */

// Declare compatibility with WooCommerce features
add_action('before_woocommerce_init', function() {
    if (class_exists('\Automattic\WooCommerce\Utilities\FeaturesUtil')) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
    }
});

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

/**
 * Debug logging helper - only logs when WP_DEBUG and plugin debug mode are enabled.
 *
 * @param string $message The message to log.
 * @param string $level   Log level: 'info', 'warning', 'error'.
 */
function stablezact_log( $message, $level = 'info' ) {
	$settings = get_option( 'woocommerce_stablezact_settings', array() );
	$debug_enabled = isset( $settings['debug'] ) && 'yes' === $settings['debug'];

	// Only log if WordPress debug is on AND plugin debug is enabled
	if ( defined( 'WP_DEBUG' ) && WP_DEBUG && $debug_enabled ) {
		$prefix = 'Stablezact [' . strtoupper( $level ) . ']: ';
		// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Diagnostic logging gated behind WP_DEBUG and the plugin's own debug setting.
		error_log( $prefix . $message );
	}
}

// Define plugin constants
define( 'STABLEZACT_VERSION', '1.1.9' );
define( 'STABLEZACT_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'STABLEZACT_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'STABLEZACT_PLUGIN_FILE', __FILE__ );

// Fallback transaction fee rate, used only when the merchant's own rate is not
// available from the API. The authoritative value is customFeePercentage on the
// merchant account; this is what the UI shows until that has been fetched.
define( 'STABLEZACT_DEFAULT_FEE_PERCENTAGE', 0.01 );

// Make sure WooCommerce is active
function stablezact_check_woocommerce() {
    if (class_exists('WooCommerce')) {
        return true;
    }
    
    // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- 'active_plugins' is a WordPress core filter, not one defined by this plugin.
    if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
        return true;
    }
    
    if (is_multisite()) {
        $plugins = get_site_option('active_sitewide_plugins');
        if (isset($plugins['woocommerce/woocommerce.php'])) {
            return true;
        }
    }
    
    return false;
}

/**
 * Add plugin action links.
 */
function stablezact_plugin_action_links( $links ) {
    $plugin_links = array(
        '<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=checkout&section=stablezact' ) ) . '">' . esc_html__( 'Settings', 'stablezact-crypto-payments' ) . '</a>',
    );
    return array_merge( $plugin_links, $links );
}
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'stablezact_plugin_action_links' );



// Initialize the plugin
Stablezact::instance();

class Stablezact {
    
    /**
     * Plugin version.
     *
     * @var string
     */
    public $version = '1.1.7';

    /**
     * The single instance of the class.
     *
     * @var Stablezact
     */
    protected static $_instance = null;

    /**
     * Main Stablezact Instance.
     *
     * Ensures only one instance of Stablezact is loaded or can be loaded.
     *
     * @return Stablezact - Main instance
     */
    public static function instance() {
        if ( is_null( self::$_instance ) ) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * Stablezact Constructor.
     */
    public function __construct() {
        $this->define_constants();
        $this->includes();
        $this->init_hooks();
    }

    /**
     * Hook into actions and filters.
     */
    private function init_hooks() {
        add_action( 'init', array( $this, 'init' ), 0 );
        add_action( 'plugins_loaded', array( $this, 'init_gateway_class' ) );
        add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateway_class' ) );
        
        // Plugin activation/deactivation hooks
        register_activation_hook( __FILE__, array( $this, 'plugin_activation' ) );
        register_deactivation_hook( __FILE__, array( $this, 'plugin_deactivation' ) );
        
        // Admin hooks for onboarding
        add_action( 'admin_init', array( $this, 'handle_onboarding_redirect' ) );
        add_action( 'admin_notices', array( $this, 'show_onboarding_notice' ) );
        add_action( 'wp_ajax_stablezact_dismiss_notice', array( $this, 'dismiss_onboarding_notice' ) );
        add_action( 'wp_ajax_stablezact_complete_onboarding', array( $this, 'complete_onboarding' ) );
    }

    /**
     * Define Stablezact Constants.
     */
    private function define_constants() {
        $this->define( 'STABLEZACT_ABSPATH', dirname( STABLEZACT_PLUGIN_FILE ) . '/' );
        $this->define( 'STABLEZACT_PLUGIN_BASENAME', plugin_basename( STABLEZACT_PLUGIN_FILE ) );
        $this->define( 'STABLEZACT_VERSION', $this->version );
    }

    /**
     * Define constant if not already set.
     *
     * @param string $name  Constant name.
     * @param string $value Constant value.
     */
    private function define( $name, $value ) {
        // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.VariableConstantNameFound -- Generic internal helper; every constant passed in is already prefixed with STABLEZACT_.
        if ( ! defined( $name ) ) {
            define( $name, $value );
        }
        // phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.VariableConstantNameFound
    }

    /**
     * Include required core files used in admin and on the frontend.
     */
    public function includes() {
        // Always include API class
        include_once dirname( __FILE__ ) . '/includes/class-stablezact-api.php';
        
        // Include admin class if in admin
        if ( is_admin() ) {
            include_once dirname( __FILE__ ) . '/includes/class-stablezact-admin.php';
        }
        
        // Include other classes that don't depend on WooCommerce
        if ( file_exists( dirname( __FILE__ ) . '/includes/class-stablezact-template-loader.php' ) ) {
            include_once dirname( __FILE__ ) . '/includes/class-stablezact-template-loader.php';
        }
    }

    /**
     * Init Stablezact when WordPress Initialises.
     */
    public function init() {
        // Before init action.
        do_action( 'stablezact_before_init' );

        // Set up localisation.
        $this->load_plugin_textdomain();

        // Init action.
        do_action( 'stablezact_init' );
    }

    /**
     * Load Localisation files.
     */
    public function load_plugin_textdomain() {
        $locale = is_admin() && function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale();
        // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- 'plugin_locale' is a WordPress core filter used per the standard manual-textdomain-loading pattern.
        $locale = apply_filters( 'plugin_locale', $locale, 'stablezact-crypto-payments' );

        unload_textdomain( 'stablezact-crypto-payments' );
        load_textdomain( 'stablezact-crypto-payments', WP_LANG_DIR . '/stablezact-crypto-payments/stablezact-crypto-payments-' . $locale . '.mo' );
    }

    /**
     * Add the gateway to WC Available Gateways.
     * 
     * @param array $gateways All available WC gateways.
     * @return array
     */
    public function add_gateway_class( $gateways ) {
        $gateways[] = 'Stablezact_Gateway';
        return $gateways;
    }

    /**
     * Init the gateway class.
     */
    public function init_gateway_class() {
        if ( class_exists( 'WooCommerce' ) ) {
            // Include gateway class now that WooCommerce is loaded
            include_once dirname( __FILE__ ) . '/includes/class-stablezact-gateway.php';
            
            // Include blocks support if available
            if ( class_exists( 'Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType' ) ) {
                include_once dirname( __FILE__ ) . '/includes/class-stablezact-blocks-support.php';
                add_action(
                    'woocommerce_blocks_payment_method_type_registration',
                    function( Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry ) {
                        $payment_method_registry->register( new Stablezact_Blocks_Support() );
                    }
                );
            }
            
            // Initialize admin if needed
            if ( is_admin() ) {
                new Stablezact_Admin();
            }
            
            // Add checkout scripts
            add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_checkout_scripts' ) );
            
            // Add AJAX handlers
            add_action( 'wp_ajax_stablezact_process_payment', array( $this, 'ajax_process_payment' ) );
            add_action( 'wp_ajax_nopriv_stablezact_process_payment', array( $this, 'ajax_process_payment' ) );
            add_action( 'wp_ajax_stablezact_connect_wallet', array( $this, 'ajax_connect_wallet' ) );
            add_action( 'wp_ajax_nopriv_stablezact_connect_wallet', array( $this, 'ajax_connect_wallet' ) );
            add_action( 'wp_ajax_stablezact_cancel_payment', array( $this, 'ajax_cancel_payment' ) );
            add_action( 'wp_ajax_nopriv_stablezact_cancel_payment', array( $this, 'ajax_cancel_payment' ) );
            add_action( 'wp_ajax_stablezact_create_blocks_order', array( $this, 'ajax_create_blocks_order' ) );
            add_action( 'wp_ajax_nopriv_stablezact_create_blocks_order', array( $this, 'ajax_create_blocks_order' ) );
            
        } else {
            add_action( 'admin_notices', array( $this, 'woocommerce_missing_notice' ) );
        }
    }

    /**
     * WooCommerce fallback notice.
     */
    public function woocommerce_missing_notice() {
        /* translators: 1. URL link. */
        echo '<div class="error"><p><strong>' . sprintf( esc_html__( 'Stablezact requires WooCommerce to be installed and active. You can download %s here.', 'stablezact-crypto-payments' ), '<a href="https://woocommerce.com/" target="_blank">WooCommerce</a>' ) . '</strong></p></div>';
    }

    /**
     * Plugin activation hook.
     */
    public function plugin_activation() {
        // Set flag for onboarding
        update_option( 'stablezact_needs_onboarding', true );
        update_option( 'stablezact_activation_redirect', true );
        
        // Create default settings
        $default_settings = array(
            'enabled' => 'yes',
            'title' => 'Pay with Cryptocurrency',
            'description' => 'Pay securely using cryptocurrency through Stablezact.',
            'testmode' => 'yes',
            'debug' => 'no',
            'payment_timeout' => '300',
            'webhook_secret' => wp_generate_password(32, false),
            'callback_url' => home_url('/wc-api/stablezact')
        );
        
        update_option( 'woocommerce_stablezact_settings', $default_settings );
    }

    /**
     * Plugin deactivation hook.
     */
    public function plugin_deactivation() {
        // Clean up onboarding flags
        delete_option( 'stablezact_needs_onboarding' );
        delete_option( 'stablezact_activation_redirect' );
        delete_option( 'stablezact_onboarding_dismissed' );
    }

    /**
     * Handle onboarding redirect after activation.
     */
    public function handle_onboarding_redirect() {
        if ( get_option( 'stablezact_activation_redirect' ) ) {
            delete_option( 'stablezact_activation_redirect' );
            
            if ( ! get_option( 'stablezact_onboarding_dismissed' ) ) {
                wp_safe_redirect( admin_url( 'admin.php?page=stablezact-onboarding' ) );
                exit;
            }
        }
    }

    /**
     * Show onboarding notice.
     */
    public function show_onboarding_notice() {
        if ( get_option( 'stablezact_needs_onboarding' ) && ! get_option( 'stablezact_onboarding_dismissed' ) ) {
            $settings_url = admin_url( 'admin.php?page=wc-settings&tab=checkout&section=stablezact' );
            $onboarding_url = admin_url( 'admin.php?page=stablezact-onboarding' );
            
            echo '<div class="notice notice-info stablezact-onboarding-notice" style="position: relative; padding: 20px; border-left: 4px solid #0073aa;">';
            echo '<h3 style="margin-top: 0;">' . esc_html__( 'Welcome to Stablezact!', 'stablezact-crypto-payments' ) . '</h3>';
            echo '<p>' . esc_html__( 'Thank you for installing Stablezact! To start accepting cryptocurrency payments, you need to connect your Stablezact merchant account.', 'stablezact-crypto-payments' ) . '</p>';
            echo '<p>';
            echo '<a href="' . esc_url( $onboarding_url ) . '" class="button button-primary" style="margin-right: 10px;">' . esc_html__( 'Connect Stablezact Account', 'stablezact-crypto-payments' ) . '</a>';
            echo '<a href="' . esc_url( $settings_url ) . '" class="button">' . esc_html__( 'Manual Setup', 'stablezact-crypto-payments' ) . '</a>';
            echo '<button type="button" class="notice-dismiss" onclick="stablezactDismissNotice()"><span class="screen-reader-text">' . esc_html__( 'Dismiss this notice.', 'stablezact-crypto-payments' ) . '</span></button>';
            echo '</p>';
            echo '</div>';

            // Attach the dismissal handler as an inline script on a registered (src-less)
            // handle instead of echoing a raw inline script, per the wp_enqueue policy.
            $dismiss_nonce = wp_create_nonce( 'stablezact_dismiss_notice' );
            $dismiss_js    = 'function stablezactDismissNotice() {'
                . 'jQuery.post(ajaxurl, { action: "stablezact_dismiss_notice", nonce: ' . wp_json_encode( $dismiss_nonce ) . ' });'
                . 'jQuery(".stablezact-onboarding-notice").fadeOut();'
                . '}';
            wp_register_script( 'stablezact-onboarding-notice', false, array( 'jquery' ), STABLEZACT_VERSION, true );
            wp_enqueue_script( 'stablezact-onboarding-notice' );
            wp_add_inline_script( 'stablezact-onboarding-notice', $dismiss_js );
        }
    }

    /**
     * Dismiss onboarding notice.
     */
    public function dismiss_onboarding_notice() {
        if ( ! current_user_can( 'manage_woocommerce' ) ) {
            wp_send_json_error( 'Permission denied' );
        }

        if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'stablezact_dismiss_notice' ) ) {
            wp_send_json_error( 'Invalid nonce' );
        }

        update_option( 'stablezact_onboarding_dismissed', true );
        wp_send_json_success();
    }

    /**
     * Complete onboarding process.
     */
    public function complete_onboarding() {
        if ( ! current_user_can( 'manage_woocommerce' ) ) {
            wp_send_json_error( 'Permission denied' );
        }

        if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'stablezact_onboarding' ) ) {
            wp_send_json_error( 'Invalid nonce' );
        }

        $email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Password intentionally not sanitized to preserve special characters
        $password = isset( $_POST['password'] ) ? wp_unslash( $_POST['password'] ) : '';
        $action_type = isset( $_POST['action_type'] ) ? sanitize_text_field( wp_unslash( $_POST['action_type'] ) ) : ''; // 'login' or 'register'

        if ( empty( $email ) || empty( $password ) ) {
            wp_send_json_error( 'Email and password are required' );
        }

        try {
            if ( $action_type === 'register' ) {
                $response = $this->register_merchant( $email, $password );
                
                // Handle registration response
                if ( $response && isset( $response['merchant'] ) ) {
                    // Registration successful - save credentials and show verification message
                    $this->save_merchant_credentials( $email, $response['merchant'] );
                    
                    $message = isset( $response['message'] ) ? $response['message'] : 'Registration successful! Please check your email to verify your account.';
                    
                    wp_send_json_success( array(
                        'message' => $message,
                        'requires_verification' => true,
                        'redirect' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=stablezact' )
                    ) );
                } else {
                    wp_send_json_error( 'Registration failed - invalid response' );
                }
                
            } else {
                $response = $this->login_merchant( $email, $password );
                
                // Handle login response
                if ( isset( $response['verified'] ) && $response['verified'] === false ) {
                    // Account exists but email not verified
                    $message = isset( $response['msg'] ) ? $response['msg'] : 'Email not verified. Please check your email for the verification link.';
                    wp_send_json_error( $message );
                    
                } elseif ( $response && isset( $response['merchant'] ) ) {
                    // Login successful and verified
                    $this->save_merchant_credentials( $email, $response['merchant'] );
                    
                    wp_send_json_success( array(
                        'message' => __( 'Successfully connected to Stablezact!', 'stablezact-crypto-payments' ),
                        'redirect' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=stablezact' )
                    ) );
                } else {
                    wp_send_json_error( 'Login failed - invalid response' );
                }
            }
        } catch ( Exception $e ) {
            wp_send_json_error( $e->getMessage() );
        }
    }

    /**
     * Save merchant credentials to WooCommerce settings.
     */
    private function save_merchant_credentials( $email, $merchant_data ) {
        $current_settings = get_option( 'woocommerce_stablezact_settings', array() );

        $updated_settings = array_merge( $current_settings, array(
            'merchant_email' => $email,
            'public_key' => $merchant_data['publicKey'],
            'enabled' => 'yes'
        ) );

        // Save webhook secret if provided
        if ( isset( $merchant_data['webhookSecret'] ) ) {
            $updated_settings['webhook_secret'] = $merchant_data['webhookSecret'];
        }

        update_option( 'woocommerce_stablezact_settings', $updated_settings );

        // Mark onboarding as complete
        delete_option( 'stablezact_needs_onboarding' );
        update_option( 'stablezact_onboarding_dismissed', true );
    }

    /**
     * Register new merchant with Stablezact.
     */
    private function register_merchant( $email, $password ) {
        $response = wp_remote_post( 'https://hub.stablezact.com/api/merchants/register', array(
            'headers' => array(
                'Content-Type' => 'application/json',
            ),
            'body' => json_encode( array(
                'email' => $email,
                'password' => $password,
                'businessName' => get_bloginfo( 'name' ),
                'website' => get_site_url(),
                'registrationSource' => 'woocommerce'
            ) ),
            'timeout' => 30
        ) );

        if ( is_wp_error( $response ) ) {
            throw new Exception( esc_html( $response->get_error_message() ) );
        }

        $body = json_decode( wp_remote_retrieve_body( $response ), true );
        $code = wp_remote_retrieve_response_code( $response );

        if ( $code !== 200 && $code !== 201 ) {
            throw new Exception( esc_html( $body['message'] ?? 'Registration failed' ) );
        }

        return $body;
    }

    /**
     * Login merchant with Stablezact.
     */
    private function login_merchant( $email, $password ) {
        $response = wp_remote_post( 'https://hub.stablezact.com/api/merchants/login', array(
            'headers' => array(
                'Content-Type' => 'application/json',
            ),
            'body' => json_encode( array(
                'email' => $email,
                'password' => $password,
            ) ),
            'timeout' => 30
        ) );

        if ( is_wp_error( $response ) ) {
            throw new Exception( esc_html( $response->get_error_message() ) );
        }

        $body = json_decode( wp_remote_retrieve_body( $response ), true );
        $code = wp_remote_retrieve_response_code( $response );

        // Handle different response scenarios
        if ( $code === 200 ) {
            // Check if response indicates unverified email
            if ( isset( $body['verified'] ) && $body['verified'] === false ) {
                // Return the response as-is for handling in complete_onboarding
                return $body;
            }
            // Normal successful login
            return $body;
        } else {
            // Error response
            $error_message = $body['message'] ?? $body['msg'] ?? 'Login failed';
            throw new Exception( esc_html( $error_message ) );
        }
    }

    /**
     * Enqueue checkout scripts and styles.
     */
    public function enqueue_checkout_scripts() {
        // CoinleyVanilla SDK scripts are now loaded by the gateway class
        // This method is kept for backwards compatibility but no longer enqueues old scripts

        // The gateway class (class-stablezact-gateway.php) handles:
        // - CoinleyVanilla SDK from CDN
        // - payment-modal.js
        // - All required styles
    }

    /**
     * AJAX handler for payment processing.
     */
    public function ajax_process_payment() {
        if ( class_exists( 'Stablezact_Gateway' ) ) {
            $gateway = new Stablezact_Gateway();
            $gateway->handle_payment_processing();
        } else {
            wp_send_json_error( 'Gateway class not available' );
        }
    }

    /**
     * AJAX handler for wallet connection.
     */
    public function ajax_connect_wallet() {
        if ( class_exists( 'Stablezact_Gateway' ) ) {
            $gateway = new Stablezact_Gateway();
            $gateway->handle_wallet_connection();
        } else {
            wp_send_json_error( 'Gateway class not available' );
        }
    }

    /**
     * AJAX handler for payment cancellation.
     */
    public function ajax_cancel_payment() {
        if ( class_exists( 'Stablezact_Gateway' ) ) {
            $gateway = new Stablezact_Gateway();
            $gateway->handle_payment_cancellation();
        } else {
            wp_send_json_error( 'Gateway class not available' );
        }
    }

    /**
     * AJAX handler for blocks order creation.
     */
    public function ajax_create_blocks_order() {
        if ( class_exists( 'Stablezact_Gateway' ) ) {
            $gateway = new Stablezact_Gateway();
            $gateway->handle_blocks_order_creation();
        } else {
            wp_send_json_error( 'Gateway class not available' );
        }
    }
}

/**
 * Send order emails asynchronously after payment processing.
 * This runs 5 seconds after checkout to avoid blocking the checkout response.
 */
function stablezact_send_order_emails_handler( $order_id ) {
    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        return;
    }

    // Trigger customer processing order email
    WC()->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger( $order_id );

    // Trigger new order admin email
    WC()->mailer()->emails['WC_Email_New_Order']->trigger( $order_id );
}
add_action( 'stablezact_send_order_emails', 'stablezact_send_order_emails_handler' );
