<?php
declare(strict_types=1);

// Independent second-process audit. SELECT and isolated File-cache has() only.
if (($argv[1] ?? '') !== '--verify-b'
    || getenv('CDX_CASHIER_B_VERIFY') !== 'APPROVED_INDEPENDENT_ZERO_20261008'
    || !hash_equals((string) getenv('CDX_CASHIER_VERIFY_SHA'),
        (string) hash_file('sha256', __FILE__))) {
    echo json_encode(['status' => 'DENIED', 'business_http' => 0, 'business_dml' => 0]), PHP_EOL;
    exit(78);
}

$path = (string) ($argv[2] ?? '');
$base = '/Users/wiscourper/.codex/cashier-orderinfo-b-20261008/';
if (!preg_match('#^' . preg_quote($base, '#') . 'CDXCOI[0-9A-F]{10}\.json$#D', $path)
    || is_link($path) || !is_file($path)
    || (((int) fileperms($path) & 0077) !== 0)) {
    throw new RuntimeException('private exact journal path/permission mismatch');
}
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$entries = array_map(static function (string $line): array {
    $item = json_decode($line, true);
    if (!is_array($item)) throw new RuntimeException('invalid journal line');
    return $item;
}, $lines);
$prepared = $entries[0] ?? [];
$marker = (string) ($prepared['marker'] ?? '');
$token = (string) ($prepared['token'] ?? '');
$before = $prepared['before'] ?? null;
$orderId = 0;
$aiStaffId = 0;
$rechargeId = 0;
foreach ($entries as $item) {
    if (($item['phase'] ?? '') === 'owned_order_inserted') {
        $orderId = (int) ($item['order_id'] ?? 0);
    }
    if (($item['phase'] ?? '') === 'ai_staff_inserted') {
        $aiStaffId = (int)($item['ai_staff_id'] ?? 0);
    }
    if (($item['phase'] ?? '') === 'recharge_inserted') {
        $rechargeId = (int)($item['recharge_id'] ?? 0);
    }
}
if (!preg_match('/^CDXCOI[0-9A-F]{10}$/D', $marker)
    || $path !== $base . $marker . '.json'
    || !preg_match('/^CDXCOI[0-9A-F]{10}T[0-9A-F]{24}$/D', $token)
    || !is_array($before) || $orderId <= 0) {
    throw new RuntimeException('journal does not identify one owned order/token');
}
$config = parse_ini_file('/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local',
    true, INI_SCANNER_RAW);
if (!is_array($config) || !isset($config['DATABASE'], $config['DATABASE_ZHCT'])) {
    throw new RuntimeException('code-local config unavailable');
}
$connect = static function (string $section, string $schemaSha) use ($config): PDO {
    $d = $config[$section];
    if (strtolower((string) $d['TYPE']) !== 'mysql'
        || (string) $d['HOSTPORT'] !== '3306' || (string) $d['CHARSET'] !== 'utf8'
        || !hash_equals('47e8be48b0cfd56dcdb9d9d426e6637b245f340b4efad4cd2f084ec5851ecc8e',
            hash('sha256', (string) $d['HOSTNAME']))
        || !hash_equals($schemaSha, hash('sha256', (string) $d['DATABASE']))) {
        throw new RuntimeException('code-local DB identity drift');
    }
    $db = new PDO('mysql:host=' . $d['HOSTNAME'] . ';port=' . $d['HOSTPORT']
        . ';dbname=' . $d['DATABASE'] . ';charset=' . $d['CHARSET'],
        $d['USERNAME'], $d['PASSWORD'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_TIMEOUT => 5]);
    $db->exec('SET SESSION TRANSACTION READ ONLY');
    if ((string) $db->query('SELECT DATABASE()')->fetchColumn() !== (string) $d['DATABASE']) {
        throw new RuntimeException('connected schema drift');
    }
    return $db;
};
$ai = $connect('DATABASE',
    'cf7756b3bb52cf72f625689134015b877fdab3ad8eb3bb2ddd962bb35f6efd66');
$store = $connect('DATABASE_ZHCT',
    'e8414690ae09be92817caeebf414e12ded85a2230818986fe9b866dbe4cfaef5');
$count = static function (PDO $db, string $sql, array $args): int {
    $q = $db->prepare($sql);
    $q->execute($args);
    return (int) $q->fetchColumn();
};
$orderZero = $count($store,
    'SELECT COUNT(*) FROM ydy_meal_order WHERE ID=? OR ORDER_NO=? OR REMARK=?',
    [$orderId, $marker, $marker]) === 0;
$childrenZero = $count($store,
    'SELECT COUNT(*) FROM ydy_initial_menu WHERE MEAL_ORDER_ID=?', [$orderId]) === 0
    && $count($store, 'SELECT COUNT(*) FROM ydy_meal_order_pickup WHERE MEAL_ORDER_ID=?',
        [$orderId]) === 0;
$actorCounts = [];
foreach (['yoshop_account_settlement', 'yoshop_user_balance_log',
    'yoshop_user_subsidy_log'] as $table) {
    $actorCounts[$table] = $count($ai,
        'SELECT COUNT(*) FROM ' . $table . ' WHERE USER_ID=?', [44676]);
}
$accountZeroDelta = $actorCounts === ($before['account_counts'] ?? null);
$userRow = $ai->prepare('SELECT USER_ID,STORE_ID,IS_DELETE,BALANCE,GIFT_BALANCE,'
    . 'SUBSIDY_BALANCE FROM yoshop_user WHERE USER_ID=? AND NICK_NAME=?');
$userRow->execute([44676, 'CDXPARMOB838A9419']);
$user = array_change_key_case((array) $userRow->fetch(PDO::FETCH_ASSOC), CASE_LOWER);
$staffRow = $store->prepare('SELECT ID,AI_USER_ID,IS_SHOW FROM ydy_staff WHERE ID=? AND NAME=?');
$staffRow->execute([107491, 'CDXPARMOB838A9419']);
$staff = array_change_key_case((array) $staffRow->fetch(PDO::FETCH_ASSOC), CASE_LOWER);
$storeUserRow = $store->prepare('SELECT ID,AI_USER_ID,STAFF_UUID,IS_DELETE FROM ydy_user'
    . ' WHERE ID=? AND ACCOUNT=?');
$storeUserRow->execute([97274, 'CDXPARMOB838A9419']);
$storeUser = array_change_key_case((array) $storeUserRow->fetch(PDO::FETCH_ASSOC), CASE_LOWER);
$historicRow = $store->prepare('SELECT ID,USER_ID,SOURCE,PAY_STATUS,ORDER_STATUS,'
    . 'PAY_PRICE,ACCOUNT_SETTLEMENT_ID FROM ydy_meal_order WHERE ID=? AND REMARK=?');
$historicRow->execute([68323, 'CDXPARMOB838A9419']);
$historic = array_change_key_case((array) $historicRow->fetch(PDO::FETCH_ASSOC), CASE_LOWER);
$actorUnchanged = hash_equals((string) ($before['actor_sha'] ?? ''),
    hash('sha256', json_encode([$user, $staff, $storeUser, $historic])));
$oldAuditIntact = $count($store,
    'SELECT COUNT(*) FROM ydy_meal_order WHERE ID=68323 AND USER_ID=97274'
        . ' AND SOURCE=4 AND PAY_STATUS=20 AND REMARK=?', ['CDXPARMOB838A9419']) === 1;

foreach (['DATABASE' => 'AI_', 'DATABASE_ZHCT' => ''] as $section => $prefix) {
    $d = $config[$section];
    foreach (['HOSTNAME' => 'HOST', 'HOSTPORT' => 'PORT', 'DATABASE' => 'SCHEMA',
        'USERNAME' => 'USER', 'PASSWORD' => 'PASSWORD'] as $source => $target) {
        putenv('POC_' . $prefix . $target . '=' . $d[$source]);
    }
}
putenv('POC_DIALECT=mysql');
define('TP_ENV', 'poc');
define('BUSINESS', 'aizhct');
define('ENTERPRISE_NO', '10001');
$root = '/private/tmp/zhct-http-ai-macos.x2CCZX';
if (realpath($root) !== $root
    || !hash_equals('98fa13484feb3db94bc4ebdd3de2f0b4ebc2c80d1cccb7a283a16f45eb9095a4',
        (string) hash_file('sha256', $root . '/config/cache.php'))) {
    throw new RuntimeException('isolated File-cache boundary drift');
}
require $root . '/vendor/autoload.php';
(new \think\App($root))->setEnvName('poc')->initialize();
$tokenZero = !\think\facade\Cache::has($token);
$staffZero = $aiStaffId === 0 || ($aiStaffId > 0
    && $count($ai, 'SELECT COUNT(*) FROM yoshop_staff WHERE ID=? OR NAME=?',
        [$aiStaffId, $marker . 'STAFF']) === 0);
$rechargeZero = $rechargeId === 0 || ($rechargeId > 0
    && $count($ai, 'SELECT COUNT(*) FROM yoshop_recharge_order'
        . ' WHERE ORDER_ID=? OR ORDER_NO=? OR NOTE=?',
        [$rechargeId, 'CR' . $marker, 'CR' . $marker]) === 0
    && $count($ai, 'SELECT COUNT(*) FROM yoshop_cashout_order_detail'
        . ' WHERE RECHARGE_ORDER_ID=?', [$rechargeId]) === 0);
$allZero = $orderZero && $childrenZero && $accountZeroDelta && $actorUnchanged
    && $oldAuditIntact && $tokenZero && $staffZero && $rechargeZero;
echo json_encode(['status' => $allZero ? 'ZERO_VERIFIED' : 'ZERO_FAILED',
    'journal_marker_sha' => hash('sha256', $marker),
    'order_zero' => $orderZero, 'children_zero' => $childrenZero,
    'ledger_delta_zero' => $accountZeroDelta, 'actor_unchanged' => $actorUnchanged,
    'prior_audit_intact' => $oldAuditIntact,
    'token_zero' => $tokenZero, 'ai_staff_zero' => $staffZero,
    'owned_recharge_and_cashout_detail_zero' => $rechargeZero,
    'business_http' => 0, 'business_dml' => 0]), PHP_EOL;
exit($allZero ? 0 : 1);
