<?php
/**
 * 芋头CMS
 * ============================================================================
 * 版权所有 2016-2028 沅陵县乌托邦网络服务有限公司，并保留所有权利。
 * 网站地址: http://www.yutoucms.cn
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 芋头 <mxgsf@qq.com>
 * Date: 2026-5-20
 */

namespace Core\Lib;

class OrderTimeout
{
    const DEFAULT_TIMEOUT_SECONDS = 1800;
    const CANCEL_STATUS = -1;

    public static function cancelExpiredPendingOrders($db, $timeoutSeconds = self::DEFAULT_TIMEOUT_SECONDS, $limit = 100)
    {
        $timeoutSeconds = max(60, intval($timeoutSeconds));
        $limit = max(1, min(500, intval($limit)));
        $cutoffTime = time() - $timeoutSeconds;

        $orders = $db->fetchAll(
            "SELECT id FROM {$db->table('order')} WHERE status = 0 AND create_time > 0 AND create_time <= ? ORDER BY id ASC LIMIT {$limit}",
            [$cutoffTime]
        );

        $closed = 0;
        foreach ($orders as $order) {
            if (self::cancelPendingOrder($db, intval($order['id'] ?? 0))) {
                $closed++;
            }
        }

        return $closed;
    }

    public static function cancelPendingOrder($db, $orderId)
    {
        $orderId = intval($orderId);
        if ($orderId <= 0) {
            return false;
        }

        $db->beginTransaction();
        try {
            $order = $db->fetch("SELECT id, status FROM {$db->table('order')} WHERE id = ? FOR UPDATE", [$orderId]);
            if (!$order || intval($order['status']) !== 0) {
                $db->commit();
                return false;
            }

            $affected = $db->update('order', [
                'status' => self::CANCEL_STATUS,
                'update_time' => time(),
            ], 'id = ? AND status = 0', [$orderId]);

            if ($affected <= 0) {
                $db->commit();
                return false;
            }

            $items = $db->fetchAll("SELECT product_id, quantity FROM {$db->table('order_product')} WHERE order_id = ?", [$orderId]);
            foreach ($items as $item) {
                $productId = intval($item['product_id'] ?? 0);
                $quantity = intval($item['quantity'] ?? 0);
                if ($productId > 0 && $quantity > 0) {
                    $db->query("UPDATE {$db->table('product')} SET stock = stock + ? WHERE id = ?", [$quantity, $productId]);
                }
            }

            $db->commit();
            return true;
        } catch (\Exception $e) {
            $db->rollBack();
            throw $e;
        }
    }
}
