<?php
/**
 * Authorize.net Credit Card Block Integration
 *
 * Integrates the Authorize.net Credit Card payment method with WooCommerce Blocks.
 *
 * @package Authorize_Net_Payments_For_Woocommerce
 * @subpackage Authorize_Net_Payments_For_Woocommerce/includes
 */

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

use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType;
use Automattic\WooCommerce\Blocks\Payments\PaymentResult;
use Automattic\WooCommerce\Blocks\Payments\PaymentContext;

/**
 * Class Anet_Credit_Card_Block
 *
 * Extends WooCommerce Blocks' AbstractPaymentMethodType to support Authorize.net Credit Card payments.
 */
class Anet_Credit_Card_Block extends AbstractPaymentMethodType
{
    /**
     * Payment method name.
     *
     * @var string
     */
    protected $name = ANET_CREDIT_CARD_GATEWAY_ID;
    /**
     * Constructor.
     */
    public function __construct()
    {
        /**
         * Hook into WooCommerce Blocks checkout process to inject Authorize.net error handling.
         */
        add_action('woocommerce_rest_checkout_process_payment_with_context', [$this, 'add_anet_error'], 8, 2);
    }
    /**
     * Initializes the payment method type.
     */
    public function initialize()
    {
        $this->settings = get_option('woocommerce_anet_settings', []);
        // Hook to enqueue styles and scripts.
        add_action('wp_enqueue_scripts', [$this, 'enqueue_styles']);
    }
    /**
     * Returns if this payment method should be active. If false, the scripts will not be enqueued.
     *
     * @return boolean
     */
    public function is_active()
    {
        $is_active = !empty($this->settings['enabled']) && ANET_YES === $this->settings['enabled'];
        return $is_active;
    }
    /**
     * Enqueues the appropriate stylesheet based on the active theme.
     *
     * @return void
     */
    public function enqueue_styles()
    {
        if (!is_checkout() && !is_cart()) {
            return;
        } 
        $current_theme = wp_get_theme();
        $theme_name = $current_theme->get('Name');
        if (ANET_ASTRA_THEME === $theme_name) {
            wp_enqueue_style(
                'wc-anet-blocks-checkout-style',
                plugins_url('../assets/css/anet-astra-block-checkout.css', __FILE__),
                [],
                ANET_PLUGIN_VERSION
            );
        } else {
            wp_enqueue_style(
                'wc-anet-blocks-checkout-style',
                plugins_url('../assets/css/anet-default-block-checkout.css', __FILE__),
                [],
                ANET_PLUGIN_VERSION
            );
        }
    }
    /**
     * Returns an array of scripts/handles to be registered for this payment method.
     *
     * @return array
     */
    public function get_payment_method_script_handles()
    {
        $asset_path   = plugin_dir_path(__FILE__) . '/../build/index-anet-credit-card-block-asset.php';
        $version      = ANET_PLUGIN_VERSION;
        $dependencies = [];
        if (file_exists($asset_path)) {
            $asset        = require $asset_path;
            $version      = is_array($asset) && isset($asset['version']) ? $asset['version'] : $version;
            $dependencies = is_array($asset) && isset($asset['dependencies']) ? $asset['dependencies'] : $dependencies;
        }else{
            Anet_Setting_Helper::log('Asset file not found: ' . $asset_path, ANET_PAYMENT_TYPE_CREDIT_CARD, 'warning');
        }
        $js_params = $this->get_gateway_javascript_params();
        if (! empty($js_params['client_key'])) {
            wp_enqueue_script('anet-accept', $js_params['accept_js_url'], $dependencies, null, true); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
            $dependencies = array_merge(['anet-accept'], $dependencies);
        }
        // Get WooCommerce version and determine which JS file to load.
        $js_file_path = plugin_dir_path(__FILE__) . '/../build/index-anet-credit-card-block.js';
        if (!file_exists($js_file_path)) {
            Anet_Setting_Helper::log('JavaScript file not found: ' . $js_file_path, ANET_PAYMENT_TYPE_CREDIT_CARD, 'warning');
            // Return empty array to prevent script registration if JS file is missing.
            return [];
        }
        wp_register_script(
            'anet-blocks-integration',
            plugins_url('../build/index-anet-credit-card-block.js', __FILE__),
            $dependencies,
            $version,
            true
        );
        wp_set_script_translations(
            'anet-blocks-integration',
            'authorize-net-payments-for-woocommerce'
        );
        return ['anet-blocks-integration'];
    }
    /**
     * Returns an array of key=>value pairs of data made available to the payment methods script.
     *
     * @return array
     */
    public function get_payment_method_data()
    {
        $anet_subscription = new Anet_Subscriptions();
        $is_subscription_order = $anet_subscription->is_subscription_active && (WC_Subscriptions_Cart::cart_contains_subscription() || wcs_cart_contains_renewal() || WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment);
        return array_replace_recursive(
            $this->get_gateway_javascript_params(),
            [
                'title'       => $this->get_title(),
                'description' => $this->get_description(),
                'supports'    => $this->get_supported_features(),
                'tokenization' => $this->get_tokenization() === ANET_YES && !($is_subscription_order),
                'is_subscription_order' => $is_subscription_order,
                'validate_configuration_key' => $this->get_validate_credit_card_configuration_key(),
                'woocommerce_version' => $this->get_woocommerce_version()
            ]
        );
    }
    /**
     * Returns the Authorize Payment Gateway JavaScript configuration object.
     *
     * @return array  the JS configuration from the Authorize Payment Gateway.
     */
    private function get_gateway_javascript_params()
    {
        $js_configuration = [];
        $gateways = WC()->payment_gateways->get_available_payment_gateways();
        if (isset($gateways[ANET_CREDIT_CARD_GATEWAY_ID])) {
            $js_configuration = $gateways[ANET_CREDIT_CARD_GATEWAY_ID]->javascript_params();
        }
        /**
         * Filter the JavaScript configuration parameters for the Authorize.net Credit Card gateway.
         *
         * @since 1.0.0
         * 
         * @param array $js_configuration The configuration array to be passed to the frontend.
         */
        return apply_filters(
            'anet_wc_params',
            $js_configuration
        );
    }
    /**
     * Returns the title string to use in the UI (customizable via admin settings screen).
     *
     * @return string
     */
    private function get_title()
    {
        $title = isset($this->settings['title']) ? $this->settings['title'] : __('Credit Card Block Authorize.net', 'authorize-net-payments-for-woocommerce');
        return $title;
    }
    /**
     * Returns whether tokenization is enabled for the payment method.
     *
     * @return bool
     */
    private function get_tokenization()
    {
        $tokenization = isset($this->settings['tokenization']) ? $this->settings['tokenization'] : false;
        return $tokenization;
    }
    /**
     * Returns the description string to use in the UI.
     *
     * @return string
     */
    private function get_description()
    {
        $description = isset($this->settings['description']) ? $this->settings['description'] : __('Pay securely using your credit card via Authorize.net.', 'authorize-net-payments-for-woocommerce');
        return $description;
    }
    /**
     * Returns the Key Configuration string to use in the UI.
     *
     * @return string
     */
    private function get_validate_credit_card_configuration_key()
    {
        $flag = true;
        $gateways = WC()->payment_gateways->get_available_payment_gateways();
        if (isset($gateways[ANET_CREDIT_CARD_GATEWAY_ID])) {
            $gateway = $gateways[ANET_CREDIT_CARD_GATEWAY_ID];
            if (empty($gateway->client_key) || empty($gateway->login_id) || empty($gateway->transaction_key)) {
                $flag = false;
            } else {
                $helper = new Anet_Api_Helper(ANET_PAYMENT_TYPE_CREDIT_CARD);
                $helper->set_credentials($gateway->login_id, $gateway->transaction_key, $gateway->testmode);
                $flag = $helper->is_authentication_valid();
            }
        } else {
            $flag = false;
        }
        return $flag;
    }
    /**
     * Returns an array of supported features.
     *
     * @return array
     */
    public function get_supported_features()
    {
        $gateways = WC()->payment_gateways->get_available_payment_gateways();
        if (isset($gateways[ANET_CREDIT_CARD_GATEWAY_ID])) {
            $gateway = $gateways[ANET_CREDIT_CARD_GATEWAY_ID];
            return array_filter($gateway->supports, [$gateway, 'supports']);
        }
        return [];
    }
    /**
     * Get WooCommerce version using multiple fallback methods.
     *
     * @return string WooCommerce version number.
     */
    private function get_woocommerce_version()
    {
        // Method 1: Use WC() function (most reliable).
        if (function_exists('WC') && is_object(WC()) && property_exists(WC(), 'version')) {
            return WC()->version;
        }
        // Method 2: Use WC_VERSION constant.
        if (defined('WC_VERSION')) {
            return WC_VERSION;
        }
        // Method 3: Use WordPress option.
        $version = get_option('woocommerce_version');
        if ($version) {
            return $version;
        }
        // Method 4: Parse plugin data as last resort.
        if (!function_exists('get_plugin_data')) {
            require_once(ABSPATH . 'wp-admin/includes/plugin.php');
        }
        $anet_wc_plugin_file = WP_PLUGIN_DIR . '/woocommerce/woocommerce.php';
        if (file_exists($anet_wc_plugin_file)) {
            $plugin_data = get_plugin_data($anet_wc_plugin_file);
            if (isset($plugin_data['Version'])) {
                return $plugin_data['Version'];
            }
        }
        // Default fallback.
        return '0.0.0';
    }
    /**
     * Add Authorize.net error response to block checkout.
     *
     * @param PaymentContext $context Holds context for the payment.
     * @param PaymentResult  $result  Result object for the payment.
     */
    public function add_anet_error(PaymentContext $context, PaymentResult &$result)
    {
        if (ANET_CREDIT_CARD_GATEWAY_ID === $context->payment_method) {
            add_action(
                'wc_gateway_authorize_net_process_payment_error',
                function ($error) use (&$result) {
                    $payment_details                 = $result->payment_details;
                    $payment_details['errorMessage'] = wp_strip_all_tags($error->getMessage());
                    $result->set_payment_details($payment_details);
                }
            );
        }
    }
}
