<?php

namespace WooNooW\Frontend;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

/**
 * Cart Controller - Customer-facing cart API
 * Handles cart operations for customer-spa
 */
class CartController
{

    /**
     * Initialize controller
     */
    public static function init()
    {
        // Bypass cookie authentication for cart endpoints to allow guest users
        add_filter('rest_authentication_errors', function ($result) {
            // If already authenticated or error, return as is
            if (!empty($result)) {
                return $result;
            }

            // Check if this is a cart endpoint
            $request_uri = $_SERVER['REQUEST_URI'] ?? '';
            if (strpos($request_uri, '/woonoow/v1/cart') !== false) {
                return true; // Allow access
            }

            return $result;
        }, 100);
    }

    /**
     * Register REST API routes
     */
    public static function register_routes()
    {
        $namespace = 'woonoow/v1';

        // Get cart
        $result = register_rest_route($namespace, '/cart', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'get_cart'],
            'permission_callback' => '__return_true',
        ]);

        // Add to cart
        $result = register_rest_route($namespace, '/cart/add', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'add_to_cart'],
            'permission_callback' => function () {
                // Allow both logged-in and guest users
                return true;
            },
            'args' => [
                'product_id' => [
                    'required' => true,
                    'validate_callback' => function ($param) {
                        return is_numeric($param);
                    },
                ],
                'quantity' => [
                    'default' => 1,
                    'sanitize_callback' => 'absint',
                ],
                'variation_id' => [
                    'default' => 0,
                    'sanitize_callback' => 'absint',
                ],
            ],
        ]);

        // Update cart item
        register_rest_route($namespace, '/cart/update', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'update_cart'],
            'permission_callback' => function () {
                return true;
            },
            'args' => [
                'cart_item_key' => [
                    'required' => true,
                    'sanitize_callback' => 'sanitize_text_field',
                ],
                'quantity' => [
                    'required' => true,
                    'sanitize_callback' => 'absint',
                ],
            ],
        ]);

        // Remove from cart
        register_rest_route($namespace, '/cart/remove', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'remove_from_cart'],
            'permission_callback' => function () {
                return true;
            },
            'args' => [
                'cart_item_key' => [
                    'required' => true,
                    'sanitize_callback' => 'sanitize_text_field',
                ],
            ],
        ]);

        // Apply coupon
        register_rest_route($namespace, '/cart/apply-coupon', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'apply_coupon'],
            'permission_callback' => function () {
                return true;
            },
            'args' => [
                'coupon_code' => [
                    'required' => true,
                    'sanitize_callback' => 'sanitize_text_field',
                ],
            ],
        ]);

        // Clear cart
        register_rest_route($namespace, '/cart/clear', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'clear_cart'],
            'permission_callback' => function () {
                return true;
            },
        ]);

        // Remove coupon
        register_rest_route($namespace, '/cart/remove-coupon', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'remove_coupon'],
            'permission_callback' => function () {
                return true;
            },
            'args' => [
                'coupon_code' => [
                    'required' => true,
                    'type' => 'string',
                ],
            ],
        ]);
    }

    /**
     * Get cart contents
     */
    public static function get_cart(WP_REST_Request $request)
    {
        // Initialize WooCommerce session and cart for REST API requests
        if (!WC()->session) {
            WC()->initialize_session();
        }
        if (!WC()->cart) {
            WC()->initialize_cart();
        }
        // Set session cookie for guest users to persist cart
        if (!WC()->session->has_session()) {
            WC()->session->set_customer_session_cookie(true);
        }

        return new WP_REST_Response(self::format_cart(), 200);
    }

    /**
     * Add item to cart
     */
    public static function add_to_cart(WP_REST_Request $request)
    {
        $product_id = $request->get_param('product_id');
        $quantity = $request->get_param('quantity') ?: 1; // Default to 1
        $variation_id = $request->get_param('variation_id');

        // Initialize WooCommerce session and cart for REST API requests
        if (!WC()->session) {
            WC()->initialize_session();
        }
        if (!WC()->cart) {
            WC()->initialize_cart();
        }
        // CRITICAL: Set session cookie for guest users to persist cart
        if (!WC()->session->has_session()) {
            WC()->session->set_customer_session_cookie(true);
        }

        // Validate product
        $product = wc_get_product($product_id);
        if (!$product) {
            return new WP_Error('invalid_product', 'Product not found', ['status' => 404]);
        }

        // For variable products, get attributes from request or variation
        $variation_attributes = [];
        if ($variation_id > 0) {
            $variation = wc_get_product($variation_id);
            if (!$variation) {
                return new WP_Error('invalid_variation', "Variation not found", ['status' => 404]);
            }

            if ($variation->get_parent_id() != $product_id) {
                return new WP_Error('invalid_variation', "Variation does not belong to this product", ['status' => 400]);
            }

            if (!$variation->is_in_stock()) {
                return new WP_Error('variation_not_available', "This variation is out of stock", ['status' => 400]);
            }

            // Build attributes from request parameters (like WooCommerce does)
            // Check for attribute_* parameters in the request
            $params = $request->get_params();
            foreach ($params as $key => $value) {
                if (strpos($key, 'attribute_') === 0) {
                    $variation_attributes[sanitize_title($key)] = wc_clean($value);
                }
            }

            // If no attributes in request, get from variation meta directly
            if (empty($variation_attributes)) {
                $parent = wc_get_product($product_id);
                foreach ($parent->get_attributes() as $attr_name => $attribute) {
                    if (!$attribute->get_variation())
                        continue;

                    $meta_key = 'attribute_' . $attr_name;
                    $value = get_post_meta($variation_id, $meta_key, true);

                    if (!empty($value)) {
                        $variation_attributes[$meta_key] = $value;
                    } else {
                        // Value is empty ("Any" variation) - check if frontend sent value in 'variation' param
                        $frontend_variation = $request->get_param('variation');
                        if (is_array($frontend_variation) && isset($frontend_variation[$meta_key]) && !empty($frontend_variation[$meta_key])) {
                            $variation_attributes[$meta_key] = sanitize_text_field($frontend_variation[$meta_key]);
                        }
                    }
                }
            }
        }

        // Clear any existing notices before adding to cart
        wc_clear_notices();

        // Add to cart with variation attributes
        $cart_item_key = WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variation_attributes);

        if (!$cart_item_key) {
            $notices = wc_get_notices('error');
            $error_messages = [];
            foreach ($notices as $notice) {
                $error_messages[] = is_array($notice) ? $notice['notice'] : $notice;
            }
            $error_message = !empty($error_messages) ? implode(', ', $error_messages) : 'Failed to add product to cart';
            wc_clear_notices();

            return new WP_Error('add_to_cart_failed', $error_message, ['status' => 400]);
        }

        return new WP_REST_Response([
            'message' => 'Product added to cart',
            'cart_item_key' => $cart_item_key,
            'cart' => self::format_cart(),
        ], 200);
    }

    /**
     * Update cart item quantity
     */
    public static function update_cart(WP_REST_Request $request)
    {
        $cart_item_key = $request->get_param('cart_item_key');
        $quantity = $request->get_param('quantity');

        // Initialize WooCommerce session and cart for REST API requests
        if (!WC()->session) {
            WC()->initialize_session();
        }
        if (!WC()->cart) {
            WC()->initialize_cart();
        }
        if (!WC()->session->has_session()) {
            WC()->session->set_customer_session_cookie(true);
        }

        // Update quantity
        $updated = WC()->cart->set_quantity($cart_item_key, $quantity);

        if (!$updated) {
            return new WP_Error('update_failed', 'Failed to update cart item', ['status' => 400]);
        }

        return new WP_REST_Response([
            'message' => 'Cart updated',
            'cart' => self::format_cart(),
        ], 200);
    }

    /**
     * Remove item from cart
     */
    public static function remove_from_cart(WP_REST_Request $request)
    {
        $cart_item_key = $request->get_param('cart_item_key');

        // Initialize WooCommerce session and cart for REST API requests
        if (!WC()->session) {
            WC()->initialize_session();
        }
        if (!WC()->cart) {
            WC()->initialize_cart();
        }
        if (!WC()->session->has_session()) {
            WC()->session->set_customer_session_cookie(true);
        }

        // Check if item exists in cart
        $cart_contents = WC()->cart->get_cart();
        if (!isset($cart_contents[$cart_item_key])) {
            return new WP_Error('item_not_found', "Cart item not found", ['status' => 404]);
        }

        // Remove item
        $removed = WC()->cart->remove_cart_item($cart_item_key);

        if (!$removed) {
            return new WP_Error('remove_failed', 'Failed to remove cart item', ['status' => 400]);
        }

        return new WP_REST_Response([
            'message' => 'Item removed from cart',
            'cart' => self::format_cart(),
        ], 200);
    }

    /**
     * Clear entire cart
     */
    public static function clear_cart(WP_REST_Request $request)
    {
        // Initialize WooCommerce session and cart for REST API requests
        if (!WC()->session) {
            WC()->initialize_session();
        }
        if (!WC()->cart) {
            WC()->initialize_cart();
        }
        if (!WC()->session->has_session()) {
            WC()->session->set_customer_session_cookie(true);
        }

        // Empty the cart
        WC()->cart->empty_cart();

        return new WP_REST_Response([
            'message' => 'Cart cleared',
            'cart' => self::format_cart(),
        ], 200);
    }

    /**
     * Apply coupon to cart
     */
    public static function apply_coupon(WP_REST_Request $request)
    {
        $coupon_code = $request->get_param('coupon_code');

        if (!WC()->cart) {
            return new WP_Error('cart_error', 'Cart not initialized', ['status' => 500]);
        }

        // Apply coupon
        $applied = WC()->cart->apply_coupon($coupon_code);

        if (!$applied) {
            return new WP_Error('coupon_failed', 'Failed to apply coupon', ['status' => 400]);
        }

        return new WP_REST_Response([
            'message' => 'Coupon applied',
            'cart' => self::format_cart(),
        ], 200);
    }

    /**
     * Remove coupon from cart
     */
    public static function remove_coupon(WP_REST_Request $request)
    {
        $coupon_code = $request->get_param('coupon_code');

        if (!WC()->cart) {
            return new WP_Error('cart_error', 'Cart not initialized', ['status' => 500]);
        }

        // Remove coupon
        $removed = WC()->cart->remove_coupon($coupon_code);

        if (!$removed) {
            return new WP_Error('remove_coupon_failed', 'Failed to remove coupon', ['status' => 400]);
        }

        return new WP_REST_Response([
            'message' => 'Coupon removed',
            'cart' => self::format_cart(),
        ], 200);
    }

    /**
     * Format cart data for API response
     */
    private static function format_cart()
    {
        $cart = WC()->cart;

        if (!$cart) {
            return null;
        }

        $items = [];
        foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
            $product = $cart_item['data'];

            // Format variation attributes with clean names (Size instead of attribute_size)
            $formatted_attributes = [];
            if (!empty($cart_item['variation'])) {
                foreach ($cart_item['variation'] as $attr_key => $attr_value) {
                    // Remove 'attribute_' prefix and capitalize
                    $clean_key = str_replace('attribute_', '', $attr_key);
                    $clean_key = ucfirst($clean_key);
                    // Capitalize value
                    $formatted_attributes[$clean_key] = ucfirst($attr_value);
                }
            }

            $items[] = [
                'key' => $cart_item_key,
                'product_id' => $cart_item['product_id'],
                'variation_id' => $cart_item['variation_id'] ?? 0,
                'quantity' => $cart_item['quantity'],
                'name' => $product->get_name(),
                'price' => $product->get_price(),
                'subtotal' => $cart_item['line_subtotal'],
                'total' => $cart_item['line_total'],
                'image' => wp_get_attachment_url($product->get_image_id()),
                'permalink' => get_permalink($cart_item['product_id']),
                'attributes' => $formatted_attributes,
            ];
        }

        // Get applied coupons
        $coupons = [];
        foreach ($cart->get_applied_coupons() as $coupon_code) {
            $coupon = new \WC_Coupon($coupon_code);
            $coupons[] = [
                'code' => $coupon_code,
                'discount' => $cart->get_coupon_discount_amount($coupon_code),
                'type' => $coupon->get_discount_type(),
            ];
        }

        return [
            'items' => $items,
            'subtotal' => $cart->get_subtotal(),
            'subtotal_tax' => $cart->get_subtotal_tax(),
            'discount_total' => $cart->get_discount_total(),
            'discount_tax' => $cart->get_discount_tax(),
            'shipping_total' => $cart->get_shipping_total(),
            'shipping_tax' => $cart->get_shipping_tax(),
            'cart_contents_tax' => $cart->get_cart_contents_tax(),
            'fee_total' => $cart->get_fee_total(),
            'fee_tax' => $cart->get_fee_tax(),
            'total' => $cart->get_total('edit'),
            'total_tax' => $cart->get_total_tax(),
            'coupons' => $coupons,
            'needs_shipping' => $cart->needs_shipping(),
            'needs_payment' => $cart->needs_payment(),
        ];
    }
}
