<?php
/**
 * Simple webhook endpoint to receive status updates from data website
 */

require_once '../../config.php';

// Set content type to JSON
header('Content-Type: application/json');

// Log webhook file access
$timestamp = date('Y-m-d H:i:s');
$ip_address = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
$request_method = $_SERVER['REQUEST_METHOD'] ?? 'unknown';

error_log("[$timestamp] WEBHOOK FILE ACCESSED - IP: $ip_address, Method: $request_method, User-Agent: $user_agent");

// Only allow POST requests
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    error_log("[$timestamp] WEBHOOK METHOD DENIED - Method '$request_method' not allowed, only POST accepted");
    http_response_code(405);
    echo json_encode(['success' => false, 'message' => 'Method not allowed']);
    exit;
}

// Get the raw POST data
$raw_input = file_get_contents('php://input');
$webhook_data = json_decode($raw_input, true);

// Log webhook attempt
$timestamp = date('Y-m-d H:i:s');
error_log("[$timestamp] WEBHOOK ATTEMPT - Raw payload: " . $raw_input);

// Validate webhook data
if (!$webhook_data || !is_array($webhook_data)) {
    error_log("[$timestamp] WEBHOOK ERROR - Invalid JSON data received");
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Invalid JSON data']);
    exit;
}

error_log("[$timestamp] WEBHOOK PAYLOAD RECEIVED - " . json_encode($webhook_data));

// Extract required fields
$external_transaction_id = $webhook_data['transaction_id'] ?? null;
$new_status = $webhook_data['status'] ?? null;

error_log("[$timestamp] WEBHOOK EXTRACTED - Transaction ID: $external_transaction_id, Status: $new_status");

// Validate required fields
if (!$external_transaction_id || !$new_status) {
    error_log("[$timestamp] WEBHOOK ERROR - Missing required fields: transaction_id='$external_transaction_id', status='$new_status'");
    http_response_code(400);
    echo json_encode([
        'success' => false, 
        'message' => 'Missing required fields: transaction_id and status'
    ]);
    exit;
}

try {
    // Find the order by external_transaction_id - check both orders and agent_orders tables
    error_log("[$timestamp] WEBHOOK SEARCHING - Looking for order with external_transaction_id: $external_transaction_id");
    
    $order = null;
    $order_id = null;
    $old_status = null;
    $table_name = null;
    
    // First, search in orders table
    $stmt = $conn->prepare("SELECT id, status FROM orders WHERE external_transaction_id = ?");
    $stmt->bind_param("s", $external_transaction_id);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if ($result->num_rows > 0) {
        $order = $result->fetch_assoc();
        $order_id = $order['id'];
        $old_status = $order['status'];
        $table_name = 'orders';
    }
    $stmt->close();
    
    // If not found in orders table, search in agent_orders table
    if (!$order) {
        $stmt = $conn->prepare("SELECT id, status FROM agent_orders WHERE external_transaction_id = ?");
        $stmt->bind_param("s", $external_transaction_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $order = $result->fetch_assoc();
            $order_id = $order['id'];
            $old_status = $order['status'];
            $table_name = 'agent_orders';
        }
        $stmt->close();
    }
    
    if (!$order) {
        // Order not found in either table, log and return success (ignore unknown orders)
        error_log("[$timestamp] WEBHOOK NOT FOUND - Order not found for transaction_id: $external_transaction_id in orders or agent_orders tables");
        echo json_encode(['success' => true, 'message' => 'Order not found, ignored']);
        exit;
    }
    
    error_log("[$timestamp] WEBHOOK FOUND - Order ID: $order_id, Current Status: $old_status");
    
    // CRITICAL: Prevent webhooks from resetting processed orders back to pending
    // Once an order is in any processed state, it should never go back to 'pending'
    // This prevents Process/Cancel buttons from reappearing after an order has been processed
    $final_states = ['processing', 'completed', 'failed', 'delivered', 'paid', 'cancelled'];
    
    // Block if trying to reset any processed state back to pending
    if (in_array(strtolower($old_status), $final_states) && strtolower($new_status) === 'pending') {
        error_log("[$timestamp] WEBHOOK BLOCKED - Attempt to reset order from '$old_status' to 'pending' blocked. Order already processed.");
        echo json_encode([
            'success' => true, 
            'message' => 'Order already processed, status reset blocked',
            'order_id' => $order_id,
            'current_status' => $old_status,
            'blocked_status' => $new_status
        ]);
        exit;
    }
    
    // ADDITIONAL PROTECTION: Also block if old_status is NOT 'pending' and webhook tries to set to 'pending'
    // This catches any edge cases where status might not be in final_states but still shouldn't go back to pending
    if (strtolower($old_status) !== 'pending' && strtolower($new_status) === 'pending') {
        error_log("[$timestamp] WEBHOOK BLOCKED - Attempt to reset order from '$old_status' to 'pending' blocked. Order status is not pending.");
        echo json_encode([
            'success' => true, 
            'message' => 'Order status cannot be reset to pending',
            'order_id' => $order_id,
            'current_status' => $old_status,
            'blocked_status' => $new_status
        ]);
        exit;
    }
    
    // Map external status to internal status (direct mapping - no conversion)
    $status_mapping = [
        'delivered' => 'delivered',
        'pending' => 'pending',
        'failed' => 'failed'
    ];
    
    $internal_status = $status_mapping[strtolower($new_status)] ?? 'processing';
    
    error_log("[$timestamp] WEBHOOK MAPPING - External: '$new_status' -> Internal: '$internal_status'");
    
    // Check if status actually changed
    if ($old_status === $internal_status) {
        error_log("[$timestamp] WEBHOOK NO CHANGE - Status already '$old_status', no update needed");
        echo json_encode(['success' => true, 'message' => 'Status unchanged']);
        exit;
    }
    
    // Update order status in the correct table
    error_log("[$timestamp] WEBHOOK UPDATING - Order $order_id in $table_name: '$old_status' -> '$internal_status'");
    
    if ($table_name === 'agent_orders') {
        $update_stmt = $conn->prepare("UPDATE agent_orders SET status = ?, status_updated_at = NOW() WHERE id = ?");
        error_log("[$timestamp] WEBHOOK DB UPDATE - Preparing to update agent_orders table");
    } else {
        $update_stmt = $conn->prepare("UPDATE orders SET status = ?, status_updated_at = NOW() WHERE id = ?");
        error_log("[$timestamp] WEBHOOK DB UPDATE - Preparing to update orders table");
    }
    $update_stmt->bind_param("si", $internal_status, $order_id);
    
    if ($update_stmt->execute()) {
        $affected_rows = $update_stmt->affected_rows;
        error_log("[$timestamp] WEBHOOK DB SUCCESS - Updated $affected_rows row(s) in $table_name");
    } else {
        error_log("[$timestamp] WEBHOOK DB ERROR - Failed to execute update query: " . $update_stmt->error);
    }
    $update_stmt->close();
    
    // Log the status change
    error_log("[$timestamp] WEBHOOK SUCCESS - Order $order_id status updated from '$old_status' to '$internal_status' via webhook");
    
    echo json_encode([
        'success' => true, 
        'message' => 'Status updated successfully',
        'order_id' => $order_id,
        'old_status' => $old_status,
        'new_status' => $internal_status
    ]);
    
} catch (Exception $e) {
    $error_timestamp = date('Y-m-d H:i:s');
    error_log("[$error_timestamp] WEBHOOK EXCEPTION - Error: " . $e->getMessage());
    error_log("[$error_timestamp] WEBHOOK EXCEPTION - File: " . $e->getFile() . " Line: " . $e->getLine());
    error_log("[$error_timestamp] WEBHOOK EXCEPTION - Stack trace: " . $e->getTraceAsString());
    
    http_response_code(500);
    echo json_encode([
        'success' => false, 
        'message' => 'Internal server error',
        'error' => $e->getMessage()
    ]);
}
?>
