<?php

declare(strict_types=1);

// One exact synthetic C order; never invoke the whole-table MealOrder command.
$root = '/tmp/cdx-prepay-code-scan-20261012-C-store';
$marker = 'CDXPP121012C01';
$prepayId = 3;
$mealId = 23664;
$storeUserId = 2792;
$pid = (int)file_get_contents($root . '/private-http.pid');
if (strpos((string)file_get_contents('/proc/' . $pid . '/cmdline'), $root . '/public') === false) {
    throw new RuntimeException('Wrong private DM Store process');
}
foreach (explode("\0", (string)file_get_contents('/proc/' . $pid . '/environ')) as $pair) {
    $parts = explode('=', $pair, 2);
    if (count($parts) === 2 && strpos($parts[0], 'POC_') === 0) putenv($pair);
}
if (getenv('POC_DIALECT') !== 'dm') throw new RuntimeException('Only DM test lane allowed');
$config = require $root . '/application/database.php';
$dsn = 'dm:host=' . $config['hostname'] . ';port=' . $config['hostport']
    . ';schema=' . $config['database'];
$pdo = new PDO($dsn, $config['username'], $config['password'],
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$one = static function (string $sql, array $params = []) use ($pdo): array {
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    return array_change_key_case($stmt->fetch(PDO::FETCH_ASSOC) ?: [], CASE_LOWER);
};
$prepay = $one('SELECT ID,DEVICE_ORDER_NO,MEAL_ORDER_ID,USER_ID,PREPAY_STATUS,'
    . 'UPDATE_BY,UPDATE_TIME FROM YDY_PREPAY_ORDER WHERE ID=?', [$prepayId]);
$meal = $one('SELECT ID,USER_ID,SOURCE,PAY_STATUS,ORDER_STATUS,BIND_TIME,UPDATE_TIME,'
    . 'PAY_PRICE FROM YDY_MEAL_ORDER WHERE ID=?', [$mealId]);
$related = $one('SELECT COUNT(*) AS N FROM YDY_PREPAY_ORDER WHERE MEAL_ORDER_ID=?', [$mealId]);
$bind = $one("SELECT CONFIG_VALUE FROM YDY_CONFIG WHERE CONFIG_KEY='bind_time' AND STATUS=1");
if ((string)($prepay['device_order_no'] ?? '') !== $marker
    || (int)($prepay['id'] ?? 0) !== $prepayId
    || (int)($prepay['meal_order_id'] ?? 0) !== $mealId
    || (int)($prepay['user_id'] ?? 0) !== $storeUserId
    || (int)($prepay['prepay_status'] ?? -1) !== 2
    || (int)($related['n'] ?? 0) !== 1
    || (int)($meal['id'] ?? 0) !== $mealId
    || (int)($meal['user_id'] ?? 0) !== $storeUserId
    || (int)($meal['source'] ?? -1) !== 8
    || (int)($meal['pay_status'] ?? -1) !== 10
    || (int)($meal['order_status'] ?? -1) !== 10
    || bccomp((string)($meal['pay_price'] ?? '-1'), '0.01', 2) !== 0
    || (int)($bind['config_value'] ?? 0) !== 3
    || strtotime((string)$meal['bind_time']) > time() - 180) {
    throw new RuntimeException('Owned C order is not uniquely due and unpaid');
}
if (getenv('POC_DRY_RUN') === '1') {
    echo json_encode(['lane' => 'C', 'prepay_id' => $prepayId,
        'meal_id' => $mealId, 'unique_owned_relation' => true,
        'due_for_3_minute_rule' => true, 'no_DML' => true]) . PHP_EOL;
    exit(0);
}
$attemptPath = $root . '/expire-owned-attempt.json';
if (is_file($attemptPath)) throw new RuntimeException('Exact synthetic expiry already attempted');
$attempt = ['lane' => 'C', 'marker' => $marker, 'prepay_id' => $prepayId,
    'meal_id' => $mealId, 'before_prepay_status' => 2,
    'before_meal_status' => 10, 'source_command_sha256' => hash_file('sha256',
        $root . '/application/cron/command/MealOrder.php'),
    'source_service_sha256' => hash_file('sha256',
        $root . '/application/api/service/PrepayOrder.php'),
    'at' => date('c')];
$handle = fopen($attemptPath, 'xb');
if (!$handle) throw new RuntimeException('Could not lock exact expiry attempt');
fwrite($handle, json_encode($attempt, JSON_UNESCAPED_SLASHES));
fclose($handle);
chmod($attemptPath, 0600);
require $root . '/env.php';
define('APP_PATH', $root . '/application/');
require $root . '/thinkphp/base.php';
require $root . '/application/common.php';
\think\Config::set($config, 'database');
\think\Db::clear();
$committed = false;
\think\Db::startTrans();
try {
    $affected = (new \app\common\model\meal\Order())->where('id', $mealId)
        ->where('pay_status', 10)->where('order_status', 10)
        ->where('source', 8)->where('user_id', $storeUserId)
        ->update(['order_status' => 20]);
    if ((int)$affected !== 1) throw new RuntimeException('Owned meal conditional update did not affect one row');
    (new \app\api\service\PrepayOrder())->markExpiredByMealOrder($mealId);
    $inside = \think\Db::name('prepay_order')->where('id', $prepayId)
        ->where('device_order_no', $marker)->find();
    if (!$inside || (int)$inside['prepay_status'] !== 3
        || (string)$inside['update_by'] !== 'cron') {
        throw new RuntimeException('Exact prepay service did not expire owned row');
    }
    \think\Db::commit();
    $committed = true;
} finally {
    if (!$committed) \think\Db::rollback();
}
$prepayAfter = $one('SELECT ID,DEVICE_ORDER_NO,MEAL_ORDER_ID,USER_ID,PREPAY_STATUS,'
    . 'UPDATE_BY,UPDATE_TIME FROM YDY_PREPAY_ORDER WHERE ID=?', [$prepayId]);
$mealAfter = $one('SELECT ID,PAY_STATUS,ORDER_STATUS,UPDATE_TIME FROM YDY_MEAL_ORDER WHERE ID=?', [$mealId]);
$receipt = [
    'lane' => 'C', 'marker' => $marker,
    'prepay_id' => $prepayId, 'meal_id' => $mealId,
    'conditional_meal_affected' => (int)$affected,
    'prepay_status_before' => (int)$prepay['prepay_status'],
    'prepay_status_after' => (int)($prepayAfter['prepay_status'] ?? -1),
    'prepay_update_by' => (string)($prepayAfter['update_by'] ?? ''),
    'meal_status_before' => (int)$meal['order_status'],
    'meal_status_after' => (int)($mealAfter['order_status'] ?? -1),
    'meal_pay_status_after' => (int)($mealAfter['pay_status'] ?? -1),
    'same_owned_link' => (int)($prepayAfter['meal_order_id'] ?? 0) === $mealId
        && (string)($prepayAfter['device_order_no'] ?? '') === $marker,
];
$receipt['passed'] = $receipt['conditional_meal_affected'] === 1
    && $receipt['prepay_status_after'] === 3
    && $receipt['prepay_update_by'] === 'cron'
    && $receipt['meal_status_after'] === 20
    && $receipt['meal_pay_status_after'] === 10
    && $receipt['same_owned_link'];
file_put_contents($root . '/expire-owned-receipt.json', json_encode($receipt,
    JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), LOCK_EX);
chmod($root . '/expire-owned-receipt.json', 0600);
echo json_encode($receipt, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
exit($receipt['passed'] ? 0 : 1);
