<?php
/**
 * WooCommerce Blocks Integration for ShippingGuard.
 *
 * Handles compatibility with the block-based (Gutenberg) Cart and Checkout pages.
 * The Store API extension allows WC Blocks to recalculate and re-render totals
 * when the protection toggle is changed.
 */

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

class ShippingGuard_Blocks {

    public function init() {
        if ( did_action( 'woocommerce_blocks_loaded' ) ) {
            $this->register_block_integration();
            $this->register_store_api_extension();
        } else {
            add_action( 'woocommerce_blocks_loaded', array( $this, 'register_block_integration' ) );
            add_action( 'woocommerce_blocks_loaded', array( $this, 'register_store_api_extension' ) );
        }

        // Enqueue block-specific frontend assets on cart/checkout pages
        add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_block_assets' ), 20 );
    }

    // -----------------------------------------------------------------------
    // Block Integration (script registration)
    // -----------------------------------------------------------------------
    public function register_block_integration() {
        if ( ! class_exists( 'Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface' ) ) {
            return;
        }

        require_once SHIPPINGGUARD_PATH . 'includes/class-shippingguard-blocks-integration.php';

        add_action( 'woocommerce_blocks_cart_block_registration', function( $reg ) {
            $reg->register( new ShippingGuard_Blocks_Integration() );
        } );
        add_action( 'woocommerce_blocks_checkout_block_registration', function( $reg ) {
            $reg->register( new ShippingGuard_Blocks_Integration() );
        } );
    }

    // -----------------------------------------------------------------------
    // Store API Extension — registers our namespace so WC Blocks can:
    //   1) Send extension data to the /cart/extensions endpoint
    //   2) Trigger fee recalculation via woocommerce_cart_calculate_fees
    // -----------------------------------------------------------------------
    public function register_store_api_extension() {
        if ( ! function_exists( 'woocommerce_store_api_register_endpoint_data' ) ) {
            return;
        }

        // Register endpoint data so WC Blocks knows about our namespace
        woocommerce_store_api_register_endpoint_data( array(
            'endpoint'        => 'cart',
            'namespace'       => 'shippingguard',
            'data_callback'   => array( $this, 'store_api_data_callback' ),
            'schema_callback' => array( $this, 'store_api_schema_callback' ),
            'schema_type'     => 'array',
        ) );

        // Register the update callback — called when POST /cart/extensions with our namespace
        if ( function_exists( 'woocommerce_store_api_register_update_callback' ) ) {
            woocommerce_store_api_register_update_callback( array(
                'namespace' => 'shippingguard',
                'callback'  => array( $this, 'store_api_update_callback' ),
            ) );
        }
    }

    public function store_api_data_callback() {
        $session_value = isset( WC()->session ) 
            ? WC()->session->get( 'shippingguard_fee_enabled', 'yes' ) 
            : 'yes';

        return array(
            'protection_enabled' => $session_value,
        );
    }

    public function store_api_schema_callback() {
        return array(
            'protection_enabled' => array(
                'description' => __( 'Whether shipping protection is enabled.', 'shippingguard' ),
                'type'        => 'string',
                'context'     => array( 'view', 'edit' ),
                'readonly'    => true,
            ),
        );
    }

    /**
     * Called when the /cart/extensions endpoint is POSTed to with our namespace.
     * This runs inside a WC Blocks request, which automatically recalculates
     * and returns updated cart totals (including our fee from add_fee hook).
     */
    public function store_api_update_callback( $data ) {
        if ( isset( $data['enabled'] ) && isset( WC()->session ) ) {
            $enabled = $data['enabled'] ? 'yes' : 'no';
            WC()->session->set( 'shippingguard_fee_enabled', $enabled );
        }
    }

    // -----------------------------------------------------------------------
    // Enqueue frontend assets
    // -----------------------------------------------------------------------
    public function enqueue_block_assets() {
        if ( ! is_cart() && ! is_checkout() ) {
            return;
        }
        if ( 'yes' !== get_option( 'shippingguard_is_enabled', 'yes' ) ) {
            return;
        }

        $cart_total  = WC()->cart ? WC()->cart->get_cart_contents_total() : 0;
        $fee_enabled = ( isset( WC()->session ) ) ? WC()->session->get( 'shippingguard_fee_enabled', 'yes' ) : 'yes';
        $fee_amount  = $this->calculate_fee( $cart_total );

        wp_enqueue_style(
            'shippingguard-frontend',
            SHIPPINGGUARD_URL . 'assets/style.css',
            array(),
            SHIPPINGGUARD_VERSION
        );

        wp_enqueue_script(
            'shippingguard-blocks',
            SHIPPINGGUARD_URL . 'assets/blocks-integration.js',
            array( 'jquery' ),
            SHIPPINGGUARD_VERSION,
            true
        );

        // Get the WC Store API nonce — needed for /cart/extensions endpoint
        $store_api_nonce = '';
        if ( function_exists( 'wc_create_nonce' ) ) {
            $store_api_nonce = wc_create_nonce( 'wc_store_api' );
        } elseif ( class_exists( '\Automattic\WooCommerce\StoreApi\Authentication' ) ) {
            $store_api_nonce = wp_create_nonce( 'wc_store_api' );
        }

        wp_localize_script( 'shippingguard-blocks', 'sg_block_params', array(
            'ajax_url'           => admin_url( 'admin-ajax.php' ),
            'nonce'              => wp_create_nonce( 'shippingguard_nonce' ),
            'store_api_nonce'    => $store_api_nonce,
            'store_api_url'      => rest_url( 'wc/store/v1/cart/extensions' ),
            'cart_url'           => rest_url( 'wc/store/v1/cart' ),
            'fee_enabled'        => $fee_enabled,
            'fee_amount'         => wc_price( $fee_amount ),
            'fee_raw'            => $fee_amount,
            'protection_name'    => get_option( 'shippingguard_protection_name', 'Shipping Protection' ),
            'checkout_label'     => get_option( 'shippingguard_checkout_label', 'Protect your order from damage, loss or theft' ),
            'protection_icon'    => get_option( 'shippingguard_protection_icon', '' ),
            'show_on_cart'       => get_option( 'shippingguard_show_on_cart', 'yes' ),
            'show_on_checkout'   => get_option( 'shippingguard_show_on_checkout', 'yes' ),
            'update_ship_nonce'  => wp_create_nonce( 'update-shipping-method' ),
        ) );
    }

    // -----------------------------------------------------------------------
    // Fee calculation (shared)
    // -----------------------------------------------------------------------
    private function calculate_fee( $cart_total ) {
        $pricing_method = get_option( 'shippingguard_pricing_method', 'fixed' );
        $fee_amount = 0;

        if ( 'fixed' === $pricing_method ) {
            $fee_amount = floatval( get_option( 'shippingguard_fixed_fee', '2.99' ) );
        } elseif ( 'percentage' === $pricing_method ) {
            $percentage = floatval( get_option( 'shippingguard_percentage_fee', '2' ) );
            $fee_amount = ( $cart_total * $percentage ) / 100;
            $max_cap    = floatval( get_option( 'shippingguard_max_cap', '5' ) );
            if ( $max_cap > 0 && $fee_amount > $max_cap ) {
                $fee_amount = $max_cap;
            }
        } elseif ( 'tier' === $pricing_method ) {
            $tier_rules = get_option( 'shippingguard_tier_rules', array(
                array( 'min' => 0,   'max' => 50,  'fee' => 1 ),
                array( 'min' => 50,  'max' => 100, 'fee' => 2 ),
                array( 'min' => 100, 'max' => '',  'fee' => 3 ),
            ) );
            foreach ( $tier_rules as $rule ) {
                $min = floatval( $rule['min'] );
                $max = $rule['max'] === '' ? PHP_FLOAT_MAX : floatval( $rule['max'] );
                if ( $cart_total >= $min && $cart_total <= $max ) {
                    $fee_amount = floatval( $rule['fee'] );
                    break;
                }
            }
        }

        return $fee_amount;
    }
}
