<?php
/**
 * Product API Endpoints
 * XChange 2025 Registration System
 */

// Apply secure CORS configuration
require_once 'cors_security.php';
applySecureCORS();

header('Content-Type: application/json');

require_once 'db_config.php';
require_once 'admin/product_helper.php';

$productManager = new ProductManager($conn);

$action = $_GET['action'] ?? $_POST['action'] ?? '';

try {
    switch ($action) {
        case 'get_products':
            echo json_encode(getProducts());
            break;
            
        case 'check_availability':
            echo json_encode(checkProductAvailability());
            break;
            
        case 'get_pricing':
            echo json_encode(getProductPricing());
            break;
            
        case 'reserve_products':
            echo json_encode(reserveProducts());
            break;
            
        case 'release_reservation':
            echo json_encode(releaseReservation());
            break;
            
        default:
            throw new Exception('Invalid action');
    }
    
} catch (Exception $e) {
    http_response_code(400);
    echo json_encode([
        'success' => false,
        'error' => $e->getMessage()
    ]);
}

/**
 * Get all active products with current pricing and availability
 */
function getProducts() {
    global $productManager;
    
    $filters = [
        'category_id' => $_GET['category_id'] ?? '',
        'active_only' => true,
        'frontend_visible_only' => true
    ];
    
    $products = $productManager->getAllProducts($filters);
    $categories = $productManager->getProductCategories();
    
    // Add current pricing to each product
    foreach ($products as &$product) {
        $pricing = $productManager->getCurrentPrice($product['id']);
        $product['current_price'] = $pricing['price'];
        $product['pricing_tier'] = $pricing['pricing_tier'];
        $product['is_available'] = $productManager->isProductAvailable($product['id']);
        
        // Format stock information
        if ($product['total_stock'] === null) {
            $product['stock_display'] = 'Unlimited';
            $product['stock_level'] = 'unlimited';
        } else {
            $product['stock_display'] = $product['available_stock'] . ' available';
            if ($product['available_stock'] == 0) {
                $product['stock_level'] = 'out';
            } elseif ($product['available_stock'] <= ($product['total_stock'] * 0.2)) {
                $product['stock_level'] = 'low';
            } else {
                $product['stock_level'] = 'high';
            }
        }
    }
    
    return [
        'success' => true,
        'products' => $products,
        'categories' => $categories
    ];
}

/**
 * Check availability for specific products and quantities
 */
function checkProductAvailability() {
    global $productManager;
    
    $products = $_POST['products'] ?? [];
    $results = [];
    
    foreach ($products as $productRequest) {
        $product_id = $productRequest['product_id'];
        $quantity = $productRequest['quantity'] ?? 1;
        
        $available = $productManager->isProductAvailable($product_id, $quantity);
        $pricing = $productManager->getCurrentPrice($product_id);
        
        $results[] = [
            'product_id' => $product_id,
            'quantity' => $quantity,
            'available' => $available,
            'price' => $pricing['price'] ?? 0,
            'pricing_tier' => $pricing['pricing_tier'] ?? 'standard'
        ];
    }
    
    return [
        'success' => true,
        'availability' => $results
    ];
}

/**
 * Get current pricing for products
 */
function getProductPricing() {
    global $productManager;
    
    $product_ids = $_GET['product_ids'] ?? [];
    if (is_string($product_ids)) {
        $product_ids = explode(',', $product_ids);
    }
    
    $pricing = [];
    
    foreach ($product_ids as $product_id) {
        $price_info = $productManager->getCurrentPrice($product_id);
        $pricing[$product_id] = $price_info;
    }
    
    return [
        'success' => true,
        'pricing' => $pricing
    ];
}

/**
 * Reserve products for a registration (temporary hold)
 */
function reserveProducts() {
    global $conn, $productManager;
    
    $registration_id = $_POST['registration_id'] ?? null;
    $products = $_POST['products'] ?? [];
    $expires_in_minutes = $_POST['expires_in_minutes'] ?? 30;
    
    if (!$registration_id || empty($products)) {
        throw new Exception('Registration ID and products are required');
    }
    
    $conn->beginTransaction();
    
    try {
        $reserved_products = [];
        $expires_at = date('Y-m-d H:i:s', strtotime("+{$expires_in_minutes} minutes"));
        
        foreach ($products as $product_request) {
            $product_id = $product_request['product_id'];
            $quantity = $product_request['quantity'] ?? 1;
            
            // Check availability
            if (!$productManager->isProductAvailable($product_id, $quantity)) {
                throw new Exception("Product ID {$product_id} is not available in requested quantity");
            }
            
            // Get current pricing
            $pricing = $productManager->getCurrentPrice($product_id);
            $unit_price = $pricing['price'];
            $total_price = $unit_price * $quantity;
            
            // Create reservation record
            $sql = "INSERT INTO registration_products 
                    (registration_id, product_id, quantity, unit_price, total_price, 
                     pricing_tier, stock_status, expires_at, product_metadata)
                    VALUES (?, ?, ?, ?, ?, ?, 'reserved', ?, ?)";
            
            $metadata = json_encode($product_request['metadata'] ?? []);
            
            $stmt = $conn->prepare($sql);
            $stmt->execute([
                $registration_id, $product_id, $quantity, $unit_price, $total_price,
                $pricing['pricing_tier'], $expires_at, $metadata
            ]);
            
            $reservation_id = $conn->lastInsertId();
            
            // Update product stock counts
            $productManager->updateProductStockCounts($product_id);
            
            // Log stock movement
            $productManager->logStockMovement($product_id, $registration_id, 'reserve', 
                                            $quantity, null, 'Product reserved for registration');
            
            $reserved_products[] = [
                'reservation_id' => $reservation_id,
                'product_id' => $product_id,
                'quantity' => $quantity,
                'unit_price' => $unit_price,
                'total_price' => $total_price,
                'expires_at' => $expires_at
            ];
        }
        
        $conn->commit();
        
        return [
            'success' => true,
            'reservations' => $reserved_products,
            'expires_at' => $expires_at
        ];
        
    } catch (Exception $e) {
        $conn->rollBack();
        throw $e;
    }
}

/**
 * Release product reservations (cancel hold)
 */
function releaseReservation() {
    global $conn, $productManager;
    
    $registration_id = $_POST['registration_id'] ?? null;
    $reservation_ids = $_POST['reservation_ids'] ?? [];
    
    if (!$registration_id && empty($reservation_ids)) {
        throw new Exception('Registration ID or reservation IDs are required');
    }
    
    $conn->beginTransaction();
    
    try {
        $sql = "SELECT rp.*, p.name as product_name 
                FROM registration_products rp 
                JOIN products p ON rp.product_id = p.id 
                WHERE rp.stock_status = 'reserved'";
        $params = [];
        
        if ($registration_id) {
            $sql .= " AND rp.registration_id = ?";
            $params[] = $registration_id;
        }
        
        if (!empty($reservation_ids)) {
            $placeholders = str_repeat('?,', count($reservation_ids) - 1) . '?';
            $sql .= " AND rp.id IN ({$placeholders})";
            $params = array_merge($params, $reservation_ids);
        }
        
        $stmt = $conn->prepare($sql);
        $stmt->execute($params);
        $reservations = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        $released = [];
        
        foreach ($reservations as $reservation) {
            // Update reservation status to cancelled
            $sql = "UPDATE registration_products SET 
                        stock_status = 'cancelled',
                        updated_at = NOW()
                    WHERE id = ?";
            $stmt = $conn->prepare($sql);
            $stmt->execute([$reservation['id']]);
            
            // Update product stock counts
            $productManager->updateProductStockCounts($reservation['product_id']);
            
            // Log stock movement
            $productManager->logStockMovement($reservation['product_id'], $reservation['registration_id'], 
                                            'release', $reservation['quantity'], null, 'Reservation released');
            
            $released[] = [
                'reservation_id' => $reservation['id'],
                'product_id' => $reservation['product_id'],
                'product_name' => $reservation['product_name'],
                'quantity' => $reservation['quantity']
            ];
        }
        
        $conn->commit();
        
        return [
            'success' => true,
            'released' => $released
        ];
        
    } catch (Exception $e) {
        $conn->rollBack();
        throw $e;
    }
}

/**
 * Clean up expired reservations (called by cron job)
 */
function cleanupExpiredReservations() {
    global $conn, $productManager;
    
    $conn->beginTransaction();
    
    try {
        // Find expired reservations
        $sql = "SELECT rp.*, p.name as product_name 
                FROM registration_products rp 
                JOIN products p ON rp.product_id = p.id 
                WHERE rp.stock_status = 'reserved' 
                AND rp.expires_at IS NOT NULL 
                AND rp.expires_at < NOW()";
        
        $stmt = $conn->prepare($sql);
        $stmt->execute();
        $expired = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        $cleaned = [];
        
        foreach ($expired as $reservation) {
            // Update to cancelled
            $sql = "UPDATE registration_products SET 
                        stock_status = 'cancelled',
                        updated_at = NOW()
                    WHERE id = ?";
            $stmt = $conn->prepare($sql);
            $stmt->execute([$reservation['id']]);
            
            // Update stock counts
            $productManager->updateProductStockCounts($reservation['product_id']);
            
            // Log movement
            $productManager->logStockMovement($reservation['product_id'], $reservation['registration_id'], 
                                            'release', $reservation['quantity'], null, 'Expired reservation cleanup');
            
            $cleaned[] = $reservation['id'];
        }
        
        $conn->commit();
        
        return [
            'success' => true,
            'cleaned_count' => count($cleaned),
            'cleaned_reservations' => $cleaned
        ];
        
    } catch (Exception $e) {
        $conn->rollBack();
        throw $e;
    }
}

// Auto-cleanup if requested
if ($action === 'cleanup_expired') {
    echo json_encode(cleanupExpiredReservations());
}
?>
