<?php
namespace Lean_CSNS;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Handles URL generation and share request processing
 */
class URL_Handler {
    
    /**
     * Singleton instance
     * 
     * @var URL_Handler
     */
    private static $instance = null;
    
    /**
     * Get singleton instance
     * 
     * @return URL_Handler
     */
    public static function get_instance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Private constructor to prevent direct instantiation
     */
    private function __construct() {
        $this->init();
    }
    
    /**
     * Initialize URL handler with WordPress hooks
     */
    private function init() {
        add_action('init', [$this, 'register_rewrite_rules']);
        add_filter('query_vars', [$this, 'add_query_vars']);
        add_action('template_redirect', [$this, 'handle_share_request']);
    }
    
    /**
     * Register rewrite rules for pretty URLs
     */
    public function register_rewrite_rules() {
        // Only register if permalinks are enabled
        if (get_option('permalink_structure')) {
            add_rewrite_rule(
                '^share-cart/([a-zA-Z0-9]+)/?$',
                'index.php?lean_csns_share=$matches[1]',
                'top'
            );
        }
    }
    
    /**
     * Add custom query variables
     * 
     * @param array $vars Existing query vars
     * @return array Modified query vars
     */
    public function add_query_vars($vars) {
        $vars[] = 'lean_csns_share';
        return $vars;
    }
    
    /**
     * Handle share request and load shared cart
     */
    public function handle_share_request() {
        // Check both lean_csns_share and share parameters for backwards compatibility
        $token = get_query_var('lean_csns_share');
        
        // Fallback to 'share' parameter if lean_csns_share is not set
        if (empty($token) && isset($_GET['share'])) {
            $token = sanitize_text_field(wp_unslash($_GET['share']));
        }
        
        if ($token) {
            $this->load_shared_cart($token);
        }
    }
    
    /**
     * Load shared cart by token
     * 
     * @param string $token Share token
     */
    public function load_shared_cart($token) {
        $cart_entry = Database::get_instance()->get_cart_by_token($token);
        
        if (!$cart_entry) {
            wc_add_notice(__('Shared cart not found.', 'lean-cart-share-and-save'), 'error');
            wp_redirect(wc_get_cart_url());
            exit;
        }
        
        // Check if expired
        if ($cart_entry->expires_at && strtotime($cart_entry->expires_at) < time()) {
            wc_add_notice(__('This shared cart has expired.', 'lean-cart-share-and-save'), 'error');
            wp_redirect(wc_get_cart_url());
            exit;
        }
        
        // CS4: Neutral gate — pro can block access (e.g. password protection) by hooking this filter.
        // If access is denied the hook must render a response and call exit itself.
        // The false-return path below is a safety net only.
        $can_access = apply_filters( 'lean_csns_can_access_shared_cart', true, $cart_entry, $token );
        if ( ! $can_access ) {
            wp_redirect( wc_get_cart_url() );
            exit;
        }

        $cart_handler = Cart_Handler::get_instance();

        // Non-empty live cart => let the shopper choose Replace vs Merge before we touch it.
        // Empty cart takes the fast path (load directly), identical to previous behavior.
        if ( ! WC()->cart->is_empty() ) {
            $action = isset( $_GET['lean_csns_cart_action'] ) ? sanitize_key( wp_unslash( $_GET['lean_csns_cart_action'] ) ) : '';
            $nonce  = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : '';

            $valid_choice = in_array( $action, [ 'replace', 'merge' ], true )
                && wp_verify_nonce( $nonce, 'lean_csns_cart_conflict_' . $token );

            // No valid choice yet => show the interstitial and stop (renders + exit).
            if ( ! $valid_choice ) {
                $this->render_cart_conflict_prompt( $token );
                exit;
            }

            $success = $cart_handler->restore_cart_from_data( $cart_entry->cart_data, $action );
        } else {
            $success = $cart_handler->restore_cart_from_data( $cart_entry->cart_data, 'replace' );
        }

        if ($success) {
            // Decode meta from the already-fetched row — used for display only (custom_message etc).
            // Never pass the full decoded array to update_cart_meta() because a null/stale decode
            // would silently wipe every other meta key (custom_message, password, etc.).
            $meta_data = json_decode( $cart_entry->meta_data, true ) ?: [];

            // Only write the two fields we own — merge keeps every other key safe.
            Database::get_instance()->update_cart_meta_by_token( $token, [
                'retrieved_count' => ( $meta_data['retrieved_count'] ?? 0 ) + 1,
                'last_retrieved'  => gmdate( 'Y-m-d H:i:s' ),
            ] );

            $block_notices = [];

            // Show sender's personal message if the feature is enabled and a message was saved.
            if ( lean_csns_get_option( 'cart_share.enable_custom_message', true ) && ! empty( $meta_data['custom_message'] ) ) {
                $msg = esc_html( $meta_data['custom_message'] );
                wc_add_notice( $msg, 'notice' );
                $block_notices[] = [ 'type' => 'info', 'message' => $msg ];
            }

            $success_msg = esc_html__( 'Shared cart loaded successfully!', 'lean-cart-share-and-save' );
            wc_add_notice( $success_msg, 'success' );
            $block_notices[] = [ 'type' => 'success', 'message' => $success_msg ];

            // Store for block cart — wc_add_notice() is ignored by the Cart Block.
            if ( WC()->session ) {
                WC()->session->set( 'lean_csns_block_notices', $block_notices );
            }
        } else {
            wc_add_notice(__('Failed to load shared cart.', 'lean-cart-share-and-save'), 'error');
        }
        
        wp_redirect(wc_get_cart_url());
        exit;
    }

    /**
     * Show the Replace-or-Merge interstitial when the shopper already has a non-empty cart.
     * Builds two nonce-signed links back to this same share URL and includes the template.
     *
     * @param string $token Share token.
     */
    private function render_cart_conflict_prompt( $token ) {
        $share_url   = $this->generate_share_url( $token );
        $nonce       = wp_create_nonce( 'lean_csns_cart_conflict_' . $token );
        $replace_url = add_query_arg( [ 'lean_csns_cart_action' => 'replace', '_wpnonce' => $nonce ], $share_url );
        $merge_url   = add_query_arg( [ 'lean_csns_cart_action' => 'merge',   '_wpnonce' => $nonce ], $share_url );

        $template = LEAN_CSNS_PL_DIR . 'templates/cart-conflict-prompt.php';
        if ( file_exists( $template ) ) {
            include $template;
        }
    }

    /**
     * Generate share URL for a token
     *
     * @param string $token Share token
     * @return string Share URL
     */
    public function generate_share_url($token) {
        // Get URL format from cart_share settings
        $url_format = lean_csns_get_option('cart_share.url_format', 'auto');
        
        if ($url_format === 'auto' && $this->are_custom_endpoints_working()) {
            return home_url("/share-cart/{$token}");
        }
        
        // Fallback to query parameter using registered query var
        return add_query_arg('lean_csns_share', $token, wc_get_cart_url());
    }
    
    /**
     * Check if custom endpoints are working (permalinks enabled)
     *
     * @return bool Whether custom endpoints work
     */
    private function are_custom_endpoints_working() {
        return !empty(get_option('permalink_structure'));
    }
}

// Initialize singleton instance
URL_Handler::get_instance();