<?php
// includes/status_updater.php

require_once __DIR__ . '/../db/config.php';

/**
 * Recalculates and updates the overall order status based on its items' statuses.
 *
 * @param int $order_id The ID of the order to update.
 * @return bool True on success, false on failure or if no update was needed.
 */
function update_order_status($order_id) {
    $pdo = db();

    try {
        // Start a transaction
        $pdo->beginTransaction();

        // 1. Get the current order status. If it's a terminal state, don't override it.
        $stmt = $pdo->prepare("SELECT status FROM orders WHERE id = :order_id FOR UPDATE");
        $stmt->execute(['order_id' => $order_id]);
        $current_status = $stmt->fetchColumn();

        if ($current_status === 'completed' || $current_status === 'cancelled') {
            $pdo->commit();
            return true; // No action needed
        }

        // TODO: Later, check payment status here. If pending_payment, we might not want to move to 'in_progress' yet.

        // 2. Get counts of item statuses for the order
        $stmt = $pdo->prepare("
            SELECT
                COUNT(*) AS total_items,
                SUM(CASE WHEN item_status = 'shipped' THEN 1 ELSE 0 END) AS shipped_items,
                SUM(CASE WHEN item_status = 'pending' THEN 1 ELSE 0 END) AS pending_items,
                SUM(CASE WHEN item_status = 'in_progress' THEN 1 ELSE 0 END) AS in_progress_items
            FROM order_items
            WHERE order_id = :order_id
        ");
        $stmt->execute(['order_id' => $order_id]);
        $status_counts = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$status_counts || $status_counts['total_items'] == 0) {
            $pdo->rollBack();
            return false; // No items found
        }

        $new_status = null;

        // 3. Apply status aggregation rules
        if ($status_counts['shipped_items'] == $status_counts['total_items']) {
            $new_status = 'shipped';
        } elseif ($status_counts['pending_items'] > 0 || $status_counts['in_progress_items'] > 0) {
            // As long as payment is made, any non-shipped item means work is in progress.
            $new_status = 'in_progress';
        }

        // 4. Update the order status if it has changed
        if ($new_status && $new_status !== $current_status) {
            $update_stmt = $pdo->prepare("UPDATE orders SET status = :status WHERE id = :order_id");
            $update_stmt->execute(['status' => $new_status, 'order_id' => $order_id]);
            // TODO: send email when order.status changes to 'shipped'
        }

        // Commit the transaction
        $pdo->commit();

        return true;

    } catch (Exception $e) {
        // Roll back on error
        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }
        // Log error, e.g., error_log('Order status update failed: ' . $e->getMessage());
        return false;
    }
}
