<?php
namespace Lean_CSNS;

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

/**
 * Handles cart serialization, restoration, sharing, and saving operations
 */
class Cart_Handler {
    
    /**
     * Singleton instance
     * 
     * @var Cart_Handler
     */
    private static $instance = null;
    
    /**
     * Get singleton instance
     * 
     * @return Cart_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 cart handler
     */
    private function init() {
        // Cart handler initialization hooks if needed
    }
    
    /**
     * Serialize current WooCommerce cart
     * 
     * @return string|null Serialized cart data or null if cart is empty
     */
    public function serialize_current_cart() {
        $cart = WC()->cart;
        
        if (!$cart || $cart->is_empty()) {
            return null;
        }
        
        $cart_data = [
            'products' => [],
            'coupons' => []
        ];
        
        // Get all cart items (minimal approach)
        foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
            $product_data = [
                'product_id' => $cart_item['product_id'],
                'variation_id' => $cart_item['variation_id'] ?? null,
                'quantity' => $cart_item['quantity']
            ];
            
            // Add variation data if it's a variable product
            if (!empty($cart_item['variation'])) {
                $product_data['variation_data'] = $cart_item['variation'];
            }
            
            // Add any custom cart item data
            if (!empty($cart_item['cart_item_data'])) {
                $product_data['cart_item_data'] = $cart_item['cart_item_data'];
            }
            
            $cart_data['products'][] = $product_data;
        }
        
        // Get applied coupons
        $cart_data['coupons'] = $cart->get_applied_coupons();
        
        return wp_json_encode($cart_data);
    }
    
    /**
     * Restore cart from serialized data
     * 
     * @param string $cart_data_json Serialized cart data
     * @return bool Success status
     */
    public function restore_cart_from_data($cart_data_json, $mode = 'replace') {
        $cart_data = json_decode($cart_data_json, true);

        if (!$cart_data) {
            return false;
        }

        // 'replace' wipes the live cart first; 'merge' keeps it and stacks quantities on top.
        if ($mode !== 'merge') {
            WC()->cart->empty_cart();
        }

        // Add products to cart
        foreach ($cart_data['products'] as $product_data) {
            $product_id = $product_data['product_id'];
            $variation_id = $product_data['variation_id'] ?? 0;
            $quantity = $product_data['quantity'];
            $variation_data = $product_data['variation_data'] ?? [];
            $cart_item_data = $product_data['cart_item_data'] ?? [];

            // Check if product still exists and is purchasable
            $product = wc_get_product($variation_id ?: $product_id);
            if (!$product || !$product->is_purchasable()) {
                continue; // Skip unavailable products
            }

            // Merge mode: same item already in cart? Bump its quantity instead of adding a second line.
            if ($mode === 'merge') {
                $cart_id = WC()->cart->generate_cart_id($product_id, $variation_id, $variation_data, $cart_item_data);
                $existing = WC()->cart->get_cart_item($cart_id);
                if ($existing) {
                    WC()->cart->set_quantity($cart_id, $existing['quantity'] + $quantity);
                    continue;
                }
            }

            // Add to cart (replace mode, or merge mode with a not-yet-present item)
            WC()->cart->add_to_cart(
                $product_id,
                $quantity,
                $variation_id,
                $variation_data,
                $cart_item_data
            );
        }
        
        // Apply coupons
        if (!empty($cart_data['coupons'])) {
            foreach ($cart_data['coupons'] as $coupon_code) {
                WC()->cart->apply_coupon($coupon_code);
            }
        }
        
        // Calculate totals
        WC()->cart->calculate_totals();
        
        return true;
    }
    
    /**
     * Share current cart
     * 
     * @return array Response array with success status and data
     */
    public function share_cart() {
        $cart_data = $this->serialize_current_cart();
        
        if (!$cart_data) {
            return ['success' => false, 'message' => __('Cart is empty', 'lean-cart-share-and-save')];
        }
        
        $token = $this->generate_unique_token();
        $expires_at = $this->calculate_expiry_date();
        
        $data = [
            'user_id' => get_current_user_id() ?: null,
            'cart_data' => $cart_data,
            'share_token' => $token,
            'save_name' => null,
            'type' => 'share',
            'expires_at' => $expires_at,
            'meta_data' => wp_json_encode(['retrieved_count' => 0])
        ];
        
        $result = Database::get_instance()->insert_cart($data);
        
        if ($result) {
            $url_handler = URL_Handler::get_instance();
            return [
                'success' => true,
                'url' => $url_handler->generate_share_url($token),
                'token' => $token
            ];
        }
        
        return ['success' => false, 'message' => __('Failed to share cart', 'lean-cart-share-and-save')];
    }
    
    /**
     * Save current cart for logged-in user
     * 
     * @param string $name Cart save name
     * @return array Response array with success status and message
     */
    public function save_cart($name) {
        if (!is_user_logged_in()) {
            return ['success' => false, 'message' => __('Please log in to save cart', 'lean-cart-share-and-save')];
        }
        
        $cart_data = $this->serialize_current_cart();
        
        if (!$cart_data) {
            return ['success' => false, 'message' => __('Cart is empty', 'lean-cart-share-and-save')];
        }
        
        $token = $this->generate_unique_token();
        
        $data = [
            'user_id' => get_current_user_id(),
            'cart_data' => $cart_data,
            'share_token' => $token,
            'save_name' => sanitize_text_field($name),
            'type' => 'save',
            'expires_at' => null,
            'meta_data' => wp_json_encode(['last_accessed' => gmdate('Y-m-d H:i:s')])
        ];
        
        $result = Database::get_instance()->insert_cart($data);
        
        return [
            'success' => $result ? true : false,
            'message' => $result ? __('Cart saved successfully!', 'lean-cart-share-and-save') : __('Failed to save cart', 'lean-cart-share-and-save')
        ];
    }
    
    /**
     * Calculate expiry date based on settings
     * 
     * @return string|null Expiry date in MySQL format or null for no expiry
     */
    private function calculate_expiry_date() {
        $expiry_days = lean_csns_get_option('cart_share.expiry_days', '0');
        $days = intval($expiry_days);
        
        // 0 means never expire
        if ($days <= 0) {
            return null;
        }
        
        return gmdate('Y-m-d H:i:s', strtotime("+{$days} days"));
    }

    /**
     * Generate unique token for cart sharing
     * 
     * @return string Unique token
     */
    private function generate_unique_token() {
        do {
            $token = wp_generate_password(10, false, false);
        } while (Database::get_instance()->get_cart_by_token($token));
        
        return $token;
    }
}

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