<?php
require_once 'auth_rbac.php';
require_once '../db_config.php';
require_once 'RegistrationLogger.php';

// Require admin login with edit permission for registrations
requirePermission('registrations', 'edit');

$error = '';
$success = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    try {
        $pdo = getDBConnection();
        $logger = new RegistrationLogger($pdo, $_SESSION['admin_user'] ?? null);
        
        // Validate input
        $registrationId = $_POST['registration_id'] ?? null;
        $registrationProductId = $_POST['registration_product_id'] ?? null;
        $oldProductId = $_POST['old_product_id'] ?? null;
        $newProductId = $_POST['new_product_id'] ?? null;
        $quantity = intval($_POST['quantity'] ?? 0);
        $reason = trim($_POST['reason'] ?? '');
        
        if (!$registrationId || !$registrationProductId || !$oldProductId || !$newProductId || $quantity <= 0 || empty($reason)) {
            throw new Exception('All fields are required and quantity must be greater than 0');
        }
        
        if ($oldProductId === $newProductId) {
            throw new Exception('New product must be different from the current product');
        }
        
        // Start transaction
        $pdo->beginTransaction();
        
        // Get registration details to verify it's a bank transfer
        $stmt = $pdo->prepare("
            SELECT id, registration_number, payment_method, payment_status, total_amount 
            FROM registrations 
            WHERE id = ?
        ");
        $stmt->execute([$registrationId]);
        $registration = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$registration) {
            throw new Exception('Registration not found');
        }
        
        if ($registration['payment_method'] !== 'tt') {
            throw new Exception('Product changes are only allowed for bank transfer registrations');
        }
        
        // Get current registration product details
        $stmt = $pdo->prepare("
            SELECT rp.*, p.name as old_product_name, p.category_id as old_category_id, pc.name as old_category_name
            FROM registration_products rp
            JOIN products p ON rp.product_id = p.id
            LEFT JOIN product_categories pc ON p.category_id = pc.id
            WHERE rp.id = ? AND rp.registration_id = ?
        ");
        $stmt->execute([$registrationProductId, $registrationId]);
        $currentProduct = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$currentProduct) {
            throw new Exception('Current product registration not found');
        }
        
        // Get new product details and verify it's in the same category
        $stmt = $pdo->prepare("
            SELECT p.*, pc.name as category_name
            FROM products p
            LEFT JOIN product_categories pc ON p.category_id = pc.id
            WHERE p.id = ? AND p.is_active = 1
        ");
        $stmt->execute([$newProductId]);
        $newProduct = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$newProduct) {
            throw new Exception('New product not found or not active');
        }
        
        if ($newProduct['category_id'] !== $currentProduct['old_category_id']) {
            throw new Exception('New product must be in the same category as the current product');
        }
        
        // Check if new product is available for the requested quantity
        if ($newProduct['available_stock'] !== null && $newProduct['available_stock'] < $quantity) {
            throw new Exception("New product '{$newProduct['name']}' only has {$newProduct['available_stock']} units available, but {$quantity} requested");
        }
        
        // Check sale dates
        $now = date('Y-m-d H:i:s');
        if ($newProduct['sale_start_date'] && $newProduct['sale_start_date'] > $now) {
            throw new Exception("New product '{$newProduct['name']}' is not yet available for sale");
        }
        if ($newProduct['sale_end_date'] && $newProduct['sale_end_date'] < $now) {
            throw new Exception("New product '{$newProduct['name']}' is no longer available for sale");
        }
        
        // Calculate new pricing
        $newUnitPrice = $newProduct['base_price'];
        $newTotalPrice = $newUnitPrice * $quantity;
        $oldTotalPrice = $currentProduct['total_price'];
        $priceDifference = $newTotalPrice - $oldTotalPrice;
        
        // Update the registration_products record
        $stmt = $pdo->prepare("
            UPDATE registration_products 
            SET product_id = ?, 
                quantity = ?, 
                unit_price = ?, 
                total_price = ?,
                updated_at = NOW()
            WHERE id = ?
        ");
        $stmt->execute([
            $newProductId,
            $quantity,
            $newUnitPrice,
            $newTotalPrice,
            $registrationProductId
        ]);
        
        // Update registration total amount if price changed
        if ($priceDifference != 0) {
            $newRegistrationTotal = $registration['total_amount'] + $priceDifference;
            $stmt = $pdo->prepare("
                UPDATE registrations 
                SET total_amount = ?, updated_at = NOW()
                WHERE id = ?
            ");
            $stmt->execute([$newRegistrationTotal, $registrationId]);
        }
        
        // Update delegate count if this is a delegate product
        if ($newProduct['category_name'] === 'Delegate Pass') {
            // Calculate total delegate count from all delegate products
            $stmt = $pdo->prepare("
                SELECT COALESCE(SUM(rp.quantity), 0) as total_delegate_count
                FROM registration_products rp
                JOIN products p ON rp.product_id = p.id
                JOIN product_categories pc ON p.category_id = pc.id
                WHERE rp.registration_id = ? AND pc.name = 'Delegate Pass'
            ");
            $stmt->execute([$registrationId]);
            $totalDelegateCount = $stmt->fetchColumn();
            
            // Update the delegate_count in registrations table
            $stmt = $pdo->prepare("
                UPDATE registrations 
                SET delegate_count = ?, updated_at = NOW()
                WHERE id = ?
            ");
            $stmt->execute([$totalDelegateCount, $registrationId]);
            
            // Check if we need to adjust delegate records
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM delegates WHERE registration_id = ?");
            $stmt->execute([$registrationId]);
            $currentDelegateRecords = $stmt->fetchColumn();
            
            // If we have more delegate products than delegate records, we might need to add placeholders
            // If we have fewer delegate products than delegate records, we might need to remove some
            if ($totalDelegateCount != $currentDelegateRecords) {
                // Log this discrepancy for admin attention
                $logger->log([
                    'activity_type' => 'delegate_count_discrepancy',
                    'registration_id' => $registrationId,
                    'action_description' => "Delegate count mismatch after product change: {$totalDelegateCount} delegate products vs {$currentDelegateRecords} delegate records. Manual review may be needed.",
                    'metadata' => json_encode([
                        'product_delegate_count' => $totalDelegateCount,
                        'actual_delegate_records' => $currentDelegateRecords,
                        'changed_product' => $newProduct['name'],
                        'quantity_changed_from' => $currentProduct['quantity'],
                        'quantity_changed_to' => $quantity
                    ]),
                    'severity' => 'medium',
                    'tags' => ['delegate_count', 'product_change', 'data_consistency']
                ]);
            }
        }
        
        // Update product stock counts
        // First, update the old product (release stock)
        $stmt = $pdo->prepare("
            UPDATE products SET 
                sold_stock = (
                    SELECT COALESCE(SUM(quantity), 0) 
                    FROM registration_products 
                    WHERE product_id = ? AND stock_status = 'confirmed'
                ),
                reserved_stock = (
                    SELECT COALESCE(SUM(quantity), 0) 
                    FROM registration_products 
                    WHERE product_id = ? AND stock_status = 'reserved'
                )
            WHERE id = ?
        ");
        $stmt->execute([$oldProductId, $oldProductId, $oldProductId]);
        
        // Then, update the new product (reserve/confirm stock based on current status)
        $stmt->execute([$newProductId, $newProductId, $newProductId]);
        
        // Log the product change
        $changeDetails = [
            'old_product' => [
                'id' => $oldProductId,
                'name' => $currentProduct['old_product_name'],
                'category' => $currentProduct['old_category_name'],
                'quantity' => $currentProduct['quantity'],
                'unit_price' => $currentProduct['unit_price'],
                'total_price' => $currentProduct['total_price']
            ],
            'new_product' => [
                'id' => $newProductId,
                'name' => $newProduct['name'],
                'category' => $newProduct['category_name'],
                'quantity' => $quantity,
                'unit_price' => $newUnitPrice,
                'total_price' => $newTotalPrice
            ],
            'price_difference' => $priceDifference,
            'reason' => $reason,
            'admin_user' => $_SESSION['admin_user']['username'] ?? 'unknown'
        ];
        
        $logger->logProductChange(
            $registrationId,
            $registration['registration_number'],
            $registrationProductId,
            $changeDetails
        );
        
        // Send webhook notification for product change
        try {
            require_once '../webhook_service.php';
            $webhookService = new WebhookService($pdo);
            
            // Get full registration data
            $fullRegistrationData = $webhookService->getFullRegistrationData($registrationId);
            
            $webhookData = [
                'event_type' => 'product_changed',
                'trigger' => 'admin_update',
                'old_product' => $changeDetails['old_product'],
                'new_product' => $changeDetails['new_product'],
                'price_difference' => $priceDifference,
                'new_registration_total' => $newRegistrationTotal ?? $registration['total_amount'],
                'reason' => $reason,
                'admin_info' => [
                    'updated_by' => $_SESSION['admin_user']['username'] ?? 'admin',
                    'admin_id' => $_SESSION['admin_user']['id'] ?? null,
                    'admin_full_name' => $_SESSION['admin_user']['full_name'] ?? 'Unknown Admin'
                ],
                'updated_at' => date('c')
            ];
            
            // Merge with full registration data
            if ($fullRegistrationData) {
                $webhookData = array_merge($webhookData, $fullRegistrationData);
            }
            
            $webhookService->sendWebhook('product_changed', $webhookData, $registrationId);
            error_log("Product change webhook: Sent webhook for registration {$registration['registration_number']}: {$currentProduct['old_product_name']} -> {$newProduct['name']}");
        } catch (Exception $e) {
            error_log('Webhook notification failed for product change: ' . $e->getMessage());
            // Don't fail the product change if webhook fails
        }
        
        // Commit transaction
        $pdo->commit();
        
        // Redirect back to registration details with success message
        $successParams = [
            'success' => 'product_changed',
            'old_product' => urlencode($currentProduct['old_product_name']),
            'new_product' => urlencode($newProduct['name']),
            'price_diff' => $priceDifference,
            'delegate_update' => ($newProduct['category_name'] === 'Delegate Pass') ? 'true' : 'false'
        ];
        
        $queryString = http_build_query($successParams);
        header("Location: registration-details.php?id={$registrationId}&{$queryString}");
        exit();
        
    } catch (Exception $e) {
        // Rollback transaction on error
        if ($pdo->inTransaction()) {
            $pdo->rollback();
        }
        
        $error = $e->getMessage();
        
        // Redirect back with error
        $registrationId = $_POST['registration_id'] ?? '';
        header("Location: registration-details.php?id={$registrationId}&error=" . urlencode($error));
        exit();
    }
} else {
    // If not POST request, redirect to registrations
    header('Location: registrations.php');
    exit();
}
?>
