<?php
declare(strict_types=1);

$phase = (string)($argv[1] ?? '');
$lane = (string)($argv[2] ?? '');
$marker = (string)($argv[3] ?? '');
if ($phase === '--archive') {
    fwrite(STDERR, "DENIED archive may create a default weight goal; use a separate owned-goal fixture\n");
    exit(78);
}
if (!in_array($phase, ['--run', '--audit'], true) || !in_array($lane, ['B', 'C'], true)
    || !preg_match('/^CDXCO[A-F0-9]{12}$/D', $marker)
    || ($phase === '--run' && getenv('CDX_CASHOUT_LIST_RUN') !== 'ONE_OWNED_ORDER_V1')) {
    fwrite(STDERR, "DENIED business_http=0 business_dml=0\n"); exit(78);
}
$root = $lane === 'B' ? '/private/tmp/zhct-http-ai-macos.x2CCZX'
    : '/tmp/zhct-ai-http-20260929.3XDj3w';
$port = $lane === 'B' ? 18101 : 18102;
if (!is_file($root . '/public/index.php') || !is_file($root . '/vendor/autoload.php')) {
    throw new RuntimeException('isolated AI worker root absent');
}
if ($lane === 'B') {
    $ini = parse_ini_file('/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local', true, INI_SCANNER_RAW);
    $aiCfg = is_array($ini) ? ($ini['DATABASE'] ?? null) : null;
    $storeCfg = is_array($ini) ? ($ini['DATABASE_ZHCT'] ?? null) : null;
    if (!is_array($aiCfg) || !is_array($storeCfg)
        || strtolower((string)($aiCfg['TYPE'] ?? '')) !== 'mysql'
        || (string)($aiCfg['HOSTPORT'] ?? '') !== '3306'
        || hash('sha256', (string)($aiCfg['HOSTNAME'] ?? '')) !== '47e8be48b0cfd56dcdb9d9d426e6637b245f340b4efad4cd2f084ec5851ecc8e'
        || hash('sha256', (string)($aiCfg['DATABASE'] ?? '')) !== 'cf7756b3bb52cf72f625689134015b877fdab3ad8eb3bb2ddd962bb35f6efd66') {
        throw new RuntimeException('B code-local AI identity drift');
    }
    foreach (['POC_DIALECT' => 'mysql',
        'POC_AI_HOST' => $aiCfg['HOSTNAME'], 'POC_AI_PORT' => $aiCfg['HOSTPORT'],
        'POC_AI_SCHEMA' => $aiCfg['DATABASE'], 'POC_AI_USER' => $aiCfg['USERNAME'],
        'POC_AI_PASSWORD' => $aiCfg['PASSWORD'],
        'POC_HOST' => $storeCfg['HOSTNAME'], 'POC_PORT' => $storeCfg['HOSTPORT'],
        'POC_SCHEMA' => $storeCfg['DATABASE'], 'POC_USER' => $storeCfg['USERNAME'],
        'POC_PASSWORD' => $storeCfg['PASSWORD']] as $name => $value) {
        putenv($name . '=' . $value);
    }
    $db = new PDO('mysql:host=' . $aiCfg['HOSTNAME'] . ';port=3306;dbname='
        . $aiCfg['DATABASE'] . ';charset=' . $aiCfg['CHARSET'],
        $aiCfg['USERNAME'], $aiCfg['PASSWORD'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
} else {
    if (getenv('POC_DIALECT') !== 'dm' || getenv('POC_AI_HOST') !== '127.0.0.1'
        || getenv('POC_AI_PORT') !== '5238' || getenv('POC_AI_SCHEMA') !== 'AIZHCT_APP'
        || getenv('POC_AI_USER') !== 'AIZHCT_APP'
        || getenv('POC_HOST') !== '127.0.0.1'
        || getenv('POC_PORT') !== '5237' || getenv('POC_SCHEMA') !== 'ZHCT_APP') {
        throw new RuntimeException('C two-customer-database identity drift');
    }
    $db = new PDO('dm:host=127.0.0.1;port=5238;schema=AIZHCT_APP',
        getenv('POC_AI_USER'), getenv('POC_AI_PASSWORD'),
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
    if ($db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn() !== 'AIZHCT_APP') {
        throw new RuntimeException('C AI effective schema drift');
    }
}
$one = static function (string $sql, array $args = []) use ($db) {
    $stmt = $db->prepare($sql);
    $stmt->execute($args);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    return is_array($row) ? array_change_key_case($row, CASE_LOWER) : null;
};
$ownedRows = static function () use ($db, $marker): array {
    $stmt = $db->prepare('SELECT id,order_no,money,pay_status,user_id,store_id,is_delete'
        . ' FROM yoshop_cashout_order WHERE order_no=?');
    $stmt->execute([$marker]);
    return array_map(static function (array $row): array {
        return array_change_key_case($row, CASE_LOWER);
    }, $stmt->fetchAll(PDO::FETCH_ASSOC));
};
$actorName = $lane === 'C' ? 'CDXPARMOB9411C2CB' : 'CDXPARMOB426CA4B0';
$actor = $one('SELECT user_id,nick_name FROM yoshop_user'
    . ' WHERE nick_name=? AND store_id=10001 AND is_delete=0', [$actorName]);
if ($actor === null || (int)$actor['user_id'] <= 0) {
    throw new RuntimeException('synthetic AI actor not uniquely available');
}
$userId = (int)$actor['user_id'];
$token = 'CDXCOTK' . strtoupper(hash('sha256', $marker));
define('TP_ENV', 'poc');
define('BUSINESS', 'aizhct');
define('ENTERPRISE_NO', '10001');
require_once $root . '/vendor/autoload.php';
(new \think\App($root))->setEnvName('poc')->initialize();
if (strtolower((string)\think\facade\Config::get('cache.default')) !== 'file'
    || realpath((string)\think\facade\Config::get('cache.stores.file.path'))
        !== realpath($root . '/runtime/cache')) {
    throw new RuntimeException('isolated File cache configuration drift');
}
$mapped = \think\facade\Db::connect('mysql_zhct')->name('user')
    ->where(['ai_user_id' => $userId, 'is_delete' => 0])->find();
if (empty($mapped) || !isset($mapped['password_version'])) {
    throw new RuntimeException('synthetic Store actor mapping/version absent');
}
$version = (int)$mapped['password_version'];
$ormUser = \app\api\model\User::detail($userId);
if (empty($ormUser) || (int)$ormUser['user_id'] !== $userId) {
    throw new RuntimeException('isolated ORM AI actor drift');
}
$existing = $ownedRows();
if ($phase === '--audit') {
    $hasToken = \think\facade\Cache::has($token);
    echo json_encode(['lane' => $lane, 'phase' => 'audit', 'marker' => $marker,
        'owned_cashout_count' => count($existing), 'owned_file_token_exists' => $hasToken,
        'business_http' => 0, 'business_dml' => 0]), PHP_EOL;
    exit(!$existing && !$hasToken ? 0 : 2);
}
if ($existing || \think\facade\Cache::has($token)) {
    throw new RuntimeException('owned order or short token already exists');
}
$http = static function (string $path) use ($port, $token): array {
    if (!in_array($path, ['/api/User/assets', '/api/Cashout/list'], true)) {
        throw new RuntimeException('unsupported fixed AI read path');
    }
    $ctx = stream_context_create(['http' => [
        'method' => 'GET', 'header' => 'Access-Token: ' . $token . "\r\n"
            . "platform: MP-WEIXIN\r\nversion: 2.0.51\r\nenv-version: develop\r\n",
        'ignore_errors' => true, 'timeout' => 15, 'follow_location' => 0,
    ]]);
    $handle = @fopen('http://127.0.0.1:' . $port . $path . '?storeId=10001',
        'rb', false, $ctx);
    if (!is_resource($handle)) throw new RuntimeException('isolated AI HTTP unavailable');
    $raw = stream_get_contents($handle, 524289);
    fclose($handle);
    if (!is_string($raw) || strlen($raw) > 524288) throw new RuntimeException('AI response cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['status'] ?? 0) !== 200) {
        throw new RuntimeException('AI business status failed at ' . $path
            . ' status=' . (string)($body['status'] ?? 'nonjson'));
    }
    return $body;
};
$naturalBefore = (int)$db->query('SELECT COUNT(*) FROM yoshop_cashout_order'
    . ' WHERE store_id=10001')->fetchColumn();
$insert = $db->prepare('INSERT INTO yoshop_cashout_order'
    . ' (order_no,money,pay_method,pay_status,user_id,cashout_date,store_id,create_time,update_time)'
    . ' VALUES (?,12.34,\'CDX_TEST_ONLY\',20,?,?,10001,?,?)');
$error = null;
$result = [];
try {
    if (!\think\facade\Cache::set($token, ['user' => $ormUser, 'store_id' => 10001,
        'is_login' => true, 'password_version' => $version, 'login_type' => 'sms'], 300)
        || !\think\facade\Cache::has($token)) {
        throw new RuntimeException('short isolated File token unavailable');
    }
    $assetBody = $http('/api/User/assets');
    if (!is_array($assetBody['data'] ?? null)) throw new RuntimeException('token preflight lacks asset data');
    $now = date('Y-m-d H:i:s');
    $insert->execute([$marker, $userId, substr($now, 0, 10), $now, $now]);
    $rows = $ownedRows();
    if (count($rows) !== 1 || (int)$rows[0]['user_id'] !== $userId
        || (int)$rows[0]['store_id'] !== 10001 || (int)$rows[0]['pay_status'] !== 20
        || bcadd((string)$rows[0]['money'], '0', 2) !== '12.34') {
        throw new RuntimeException('owned cashout order insertion mismatch');
    }
    $body = $http('/api/Cashout/list');
    $list = $body['data']['list'] ?? null;
    $items = is_array($list) ? ($list['data'] ?? null) : null;
    if (!is_array($items) || !$items || (int)($list['total'] ?? -1) < 1) {
        throw new RuntimeException('cashout list nonempty pagination missing');
    }
    $own = array_values(array_filter($items, static function ($item) use ($marker): bool {
        return is_array($item) && (string)($item['order_no'] ?? '') === $marker;
    }));
    if (count($own) !== 1 || (int)($own[0]['id'] ?? 0) !== (int)$rows[0]['id']
        || (int)($own[0]['pay_status'] ?? 0) !== 20
        || bcadd((string)($own[0]['money'] ?? ''), '0', 2) !== '12.34') {
        throw new RuntimeException('cashout HTTP row differs from owned original row');
    }
    $types = [];
    foreach ($own[0] as $field => $value) $types[$field] = gettype($value);
    ksort($types);
    $result = ['http_business_ok' => 1, 'own_cashout_row_source_equal' => true,
        'own_money_json_type' => gettype($own[0]['money']),
        'own_row_type_sha256' => hash('sha256', json_encode($types)),
        'pagination_total' => (int)$list['total']];
} catch (Throwable $caught) {
    $error = $caught;
} finally {
    if ($db->inTransaction()) $db->rollBack();
    foreach ($ownedRows() as $row) {
        $stmt = $db->prepare('DELETE FROM yoshop_cashout_order'
            . ' WHERE id=? AND order_no=? AND user_id=? AND store_id=10001');
        $stmt->execute([(int)$row['id'], $marker, $userId]);
    }
    \think\facade\Cache::delete($token);
}
if ($ownedRows() || \think\facade\Cache::has($token)) {
    throw new RuntimeException('owned cashout order/token cleanup failed');
}
$naturalAfter = (int)$db->query('SELECT COUNT(*) FROM yoshop_cashout_order'
    . ' WHERE store_id=10001')->fetchColumn();
if ($naturalBefore !== $naturalAfter) throw new RuntimeException('natural cashout count changed');
if ($error !== null) throw $error;
echo json_encode(['lane' => $lane, 'marker' => $marker] + $result + [
    'owned_order_token_cleanup_zero' => true,
    'business_dml' => 'one-own-cashout-order-insert-and-delete-only',
    'third_party_refund_payment' => 0,
], JSON_UNESCAPED_SLASHES), PHP_EOL;
