<?php
/**
 * UPDATE ORDER API
 * File: api/update-order.php
 * Update order status, add notes, or modify order details
 */

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, PUT, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

require_once '../app/Core/init.php';

// Require authentication for order updates
Auth::requireLogin();

$user_id = Auth::id();
$user_role = Auth::getUserRole();

// Only allow POST/PUT/PATCH requests
if (!in_array($_SERVER['REQUEST_METHOD'], ['POST', 'PUT', 'PATCH'])) {
    http_response_code(405);
    echo json_encode(['error' => 'Method not allowed']);
    exit;
}

try {
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (!$input) {
        $input = $_POST;
    }
    
    // Validate required fields
    $required_fields = ['order_id', 'action'];
    foreach ($required_fields as $field) {
        if (empty($input[$field])) {
            http_response_code(400);
            echo json_encode(['error' => "Field '$field' is required"]);
            exit;
        }
    }
    
    $order_id = (int)$input['order_id'];
    $action = $input['action'];
    $notes = $input['notes'] ?? null;
    $additional_data = $input['data'] ?? [];
    
    $order = new Order();
    $order_data = $order->find($order_id);
    
    if (!$order_data) {
        http_response_code(404);
        echo json_encode(['error' => 'Order not found']);
        exit;
    }
    
    // Check authorization - users can only update their own orders
    if ($user_role === 'customer' && $order_data['customer_id'] != $user_id) {
        http_response_code(403);
        echo json_encode(['error' => 'You can only update your own orders']);
        exit;
    }
    
    if ($user_role === 'vendor' && $order_data['vendor_id'] != $user_id) {
        http_response_code(403);
        echo json_encode(['error' => 'You can only update orders for your items']);
        exit;
    }
    
    // Admin can update any order
    if ($user_role !== 'admin' && $user_role !== 'customer' && $user_role !== 'vendor') {
        http_response_code(403);
        echo json_encode(['error' => 'Insufficient permissions']);
        exit;
    }
    
    $db = Database::getInstance();
    $old_status = $order_data['status'];
    $new_status = null;
    $response = ['success' => true, 'message' => ''];
    
    switch ($action) {
        case 'confirm':
            // Customer confirms order
            if ($user_role !== 'customer') {
                throw new Exception('Only customers can confirm orders');
            }
            
            if ($order_data['status'] !== 'pending') {
                throw new Exception('Order can only be confirmed when in pending status');
            }
            
            $new_status = 'confirmed';
            $response['message'] = 'Order confirmed successfully';
            
            // Update payment status if not already paid
            if ($order_data['payment_status'] !== 'paid') {
                $db->execute("UPDATE orders SET payment_status = 'pending' WHERE id = ?", [$order_id]);
            }
            
            break;
            
        case 'accept':
            // Vendor accepts order
            if ($user_role !== 'vendor') {
                throw new Exception('Only vendors can accept orders');
            }
            
            if ($order_data['status'] !== 'pending') {
                throw new Exception('Order can only be accepted when in pending status');
            }
            
            $new_status = 'confirmed';
            $response['message'] = 'Order accepted successfully';
            
            // Check if item is still available
            $item = new Item();
            $item_data = $item->find($order_data['item_id']);
            
            if ($item_data['available_quantity'] < $order_data['quantity']) {
                throw new Exception('Insufficient item quantity available');
            }
            
            break;
            
        case 'reject':
            // Vendor rejects order
            if ($user_role !== 'vendor') {
                throw new Exception('Only vendors can reject orders');
            }
            
            if (!in_array($order_data['status'], ['pending', 'confirmed'])) {
                throw new Exception('Order can only be rejected when in pending or confirmed status');
            }
            
            $new_status = 'rejected';
            $response['message'] = 'Order rejected successfully';
            
            // Process refund if payment was made
            if ($order_data['payment_status'] === 'paid') {
                // Initiate refund process
                // This would integrate with payment gateway
                $refund_amount = $order_data['total_amount'];
                
                $db->execute("UPDATE orders SET payment_status = 'refund_pending' WHERE id = ?", [$order_id]);
                $response['refund_amount'] = $refund_amount;
                $response['refund_status'] = 'processing';
            }
            
            break;
            
        case 'start':
            // Vendor marks order as started
            if ($user_role !== 'vendor') {
                throw new Exception('Only vendors can start orders');
            }
            
            if ($order_data['status'] !== 'confirmed') {
                throw new Exception('Order can only be started when in confirmed status');
            }
            
            $new_status = 'in_progress';
            $response['message'] = 'Order started successfully';
            
            break;
            
        case 'complete':
            // Vendor or customer can complete order
            if (!in_array($user_role, ['vendor', 'customer'])) {
                throw new Exception('Insufficient permissions to complete order');
            }
            
            if (!in_array($order_data['status'], ['confirmed', 'in_progress'])) {
                throw new Exception('Order can only be completed when in confirmed or in_progress status');
            }
            
            $new_status = 'completed';
            $response['message'] = 'Order completed successfully';
            
            // Update completion timestamp
            $db->execute("UPDATE orders SET completed_at = NOW() WHERE id = ?", [$order_id]);
            
            // Update item availability
            $db->execute("UPDATE items SET available_quantity = available_quantity + ? WHERE id = ?", 
                        [$order_data['quantity'], $order_data['item_id']]);
            
            break;
            
        case 'cancel':
            // Customer cancels order
            if ($user_role !== 'customer') {
                throw new Exception('Only customers can cancel orders');
            }
            
            if (in_array($order_data['status'], ['completed', 'cancelled', 'rejected'])) {
                throw new Exception('Order cannot be cancelled in current status');
            }
            
            $new_status = 'cancelled';
            $response['message'] = 'Order cancelled successfully';
            
            // Check cancellation policy
            $start_date = new DateTime($order_data['start_date']);
            $now = new DateTime();
            $hours_until_start = $now->diff($start_date)->h + ($now->diff($start_date)->days * 24);
            
            $refund_percentage = 0;
            if ($hours_until_start >= 48) {
                $refund_percentage = 100; // Full refund
            } elseif ($hours_until_start >= 24) {
                $refund_percentage = 50; // 50% refund
            } // Otherwise no refund
            
            if ($refund_percentage > 0 && $order_data['payment_status'] === 'paid') {
                $refund_amount = ($order_data['total_amount'] * $refund_percentage) / 100;
                $response['refund_amount'] = $refund_amount;
                $response['refund_percentage'] = $refund_percentage;
                
                // Process refund
                $db->execute("UPDATE orders SET payment_status = 'refund_pending' WHERE id = ?", [$order_id]);
            }
            
            break;
            
        case 'add_note':
            // Add notes to order
            if (empty($notes)) {
                throw new Exception('Notes are required for this action');
            }
            
            // Add order note
            $note_type = $additional_data['type'] ?? 'general';
            $note_sql = "INSERT INTO order_notes (order_id, user_id, note, type, created_at) 
                        VALUES (?, ?, ?, ?, NOW())";
            $db->execute($note_sql, [$order_id, $user_id, $notes, $note_type]);
            
            $response['message'] = 'Note added successfully';
            $response['note_id'] = $db->lastInsertId();
            
            break;
            
        case 'update_dates':
            // Update order dates (customer only, before start)
            if ($user_role !== 'customer') {
                throw new Exception('Only customers can modify order dates');
            }
            
            if ($order_data['status'] !== 'pending') {
                throw new Exception('Dates can only be modified for pending orders');
            }
            
            $new_start_date = $additional_data['start_date'] ?? null;
            $new_end_date = $additional_data['end_date'] ?? null;
            
            if (!$new_start_date || !$new_end_date) {
                throw new Exception('Both start and end dates are required');
            }
            
            $start = new DateTime($new_start_date);
            $end = new DateTime($new_end_date);
            
            if ($start >= $end) {
                throw new Exception('End date must be after start date');
            }
            
            if ($start <= new DateTime()) {
                throw new Exception('Start date cannot be in the past');
            }
            
            // Check availability for new dates
            $availability_sql = "SELECT COUNT(*) as overlap_count 
                                FROM orders 
                                WHERE item_id = ? 
                                AND id != ? 
                                AND status NOT IN ('cancelled', 'rejected')
                                AND (
                                    (start_date <= ? AND end_date >= ?) OR
                                    (start_date <= ? AND end_date >= ?) OR
                                    (start_date >= ? AND end_date <= ?)
                                )";
            
            $params = [
                $order_data['item_id'],
                $order_id,
                $new_start_date, $new_start_date,
                $new_end_date, $new_end_date,
                $new_start_date, $new_end_date
            ];
            
            $overlap = $db->fetch($availability_sql, $params);
            
            if ($overlap['overlap_count'] > 0) {
                throw new Exception('Item is not available for the selected dates');
            }
            
            // Recalculate price for new dates
            $calendar_service = new CalendarService();
            $new_total = $calendar_service->calculatePrice(
                $order_data['item_id'], 
                $new_start_date, 
                $new_end_date, 
                $order_data['quantity']
            );
            
            $update_sql = "UPDATE orders SET start_date = ?, end_date = ?, total_amount = ? WHERE id = ?";
            $db->execute($update_sql, [$new_start_date, $new_end_date, $new_total, $order_id]);
            
            $response['message'] = 'Order dates updated successfully';
            $response['new_total'] = $new_total;
            
            break;
            
        case 'update_quantity':
            // Update order quantity
            $new_quantity = isset($additional_data['quantity']) ? max(1, (int)$additional_data['quantity']) : null;
            
            if (!$new_quantity) {
                throw new Exception('Quantity is required');
            }
            
            if ($order_data['status'] !== 'pending') {
                throw new Exception('Quantity can only be modified for pending orders');
            }
            
            // Check item availability
            $item = new Item();
            $item_data = $item->find($order_data['item_id']);
            
            if ($item_data['available_quantity'] < $new_quantity) {
                throw new Exception('Insufficient item quantity available');
            }
            
            // Recalculate price for new quantity
            $new_total = ($item_data['price_per_day'] * $new_quantity) * 
                        (new DateTime($order_data['end_date'])->diff(new DateTime($order_data['start_date']))->days);
            
            $update_sql = "UPDATE orders SET quantity = ?, total_amount = ? WHERE id = ?";
            $db->execute($update_sql, [$new_quantity, $new_total, $order_id]);
            
            $response['message'] = 'Order quantity updated successfully';
            $response['new_quantity'] = $new_quantity;
            $response['new_total'] = $new_total;
            
            break;
            
        default:
            throw new Exception('Invalid action specified');
    }
    
    // Update order status if changed
    if ($new_status) {
        $update_sql = "UPDATE orders SET status = ?, updated_at = NOW() WHERE id = ?";
        $db->execute($update_sql, [$new_status, $order_id]);
        
        // Log status change
        $log_sql = "INSERT INTO order_status_history (order_id, old_status, new_status, changed_by, changed_at) 
                   VALUES (?, ?, ?, ?, NOW())";
        $db->execute($log_sql, [$order_id, $old_status, $new_status, $user_id]);
        
        $response['old_status'] = $old_status;
        $response['new_status'] = $new_status;
    }
    
    // Send notifications
    $notification_service = new NotificationService();
    $notification_service->notifyOrderUpdate($order_id, $action, $new_status ?? $old_status);
    
    // Log the update
    log_info('Order updated', [
        'order_id' => $order_id,
        'user_id' => $user_id,
        'action' => $action,
        'old_status' => $old_status,
        'new_status' => $new_status,
        'notes' => $notes,
        'ip' => get_client_ip()
    ]);
    
    echo json_encode($response);
    
} catch (Exception $e) {
    log_error('Order update error', $e->getMessage(), [
        'order_id' => $input['order_id'] ?? null,
        'action' => $input['action'] ?? null,
        'user_id' => $user_id ?? null,
        'input' => $input
    ]);
    
    http_response_code(400);
    echo json_encode([
        'error' => $e->getMessage(),
        'code' => 'UPDATE_ERROR'
    ]);
}