<?php

declare(strict_types=1);

$marker = (string)getenv('POC_MARKER');
$orderId = (int)getenv('POC_ORDER_ID');
$refundId = (int)getenv('POC_REFUND_ID');
$dialect = (string)getenv('POC_DIALECT');
$root = (string)getenv('POC_APP_ROOT');
$baseUrl = rtrim((string)getenv('POC_BASE_URL'), '/');
if (!preg_match('/^CDXPARMOB[A-F0-9]{8}$/D', $marker)
    || min($orderId, $refundId) <= 0 || !in_array($dialect, ['mysql', 'dm'], true)
    || $baseUrl === '' || !is_file($root . '/application/base/Security.php')) {
    throw new RuntimeException('Exact synthetic refund target required');
}
if ($dialect === 'mysql') {
    $config = require '/workspace/zhct/zhctproject/store/application/config/local/database.php';
    foreach (['' => $config, 'AI_' => $config['ai_zhct']] as $prefix => $part) {
        foreach (['hostname' => 'HOST', 'hostport' => 'PORT', 'database' => 'SCHEMA',
            'username' => 'USER', 'password' => 'PASSWORD'] as $source => $target) {
            putenv('POC_' . $prefix . $target . '='
                . (string)($part[$source] ?? ($target === 'PORT' ? 3306 : '')));
        }
    }
}
$boundary = json_decode((string)file_get_contents($baseUrl . '/__poc_boundary'), true);
if (empty($boundary['external_stubs']) || empty($boundary['redis_isolated'])) {
    throw new RuntimeException('External or Redis boundary missing');
}
$connect = static function (string $prefix) use ($dialect): PDO {
    $host = getenv('POC_' . $prefix . 'HOST');
    $port = getenv('POC_' . $prefix . 'PORT');
    $schema = getenv('POC_' . $prefix . 'SCHEMA');
    $dsn = $dialect === 'dm' ? "dm:host=$host;port=$port;schema=$schema"
        : "mysql:host=$host;port=$port;dbname=$schema;charset=utf8mb4";
    return new PDO($dsn, getenv('POC_' . $prefix . 'USER'),
        getenv('POC_' . $prefix . 'PASSWORD'),
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
};
$store = $connect('');
$ai = $connect('AI_');
$tab = static function (string $name) use ($dialect): string {
    return $dialect === 'dm' ? strtoupper($name) : $name;
};
$sOrder = $tab('ydy_meal_order');
$sRefund = $tab('ydy_meal_order_refund');
$sUser = $tab('ydy_user');
$aUser = $tab('yoshop_user');
$aSettlement = $tab('yoshop_account_settlement');
$aBalanceLog = $tab('yoshop_user_balance_log');
$read = static function (PDO $db, string $sql, array $args = []): array {
    $q = $db->prepare($sql);
    $q->execute($args);
    return array_change_key_case((array)$q->fetch(PDO::FETCH_ASSOC));
};
$count = static function (PDO $db, string $sql, array $args = []): int {
    $q = $db->prepare($sql);
    $q->execute($args);
    return (int)$q->fetchColumn();
};
$order = $read($store, "SELECT ID,USER_ID,REMARK,REFUND_STATUS FROM $sOrder WHERE ID=?",
    [$orderId]);
$refund = $read($store, "SELECT ID,ORDER_NO,MEAL_ORDER_ID,REFUND_STATUS FROM $sRefund WHERE ID=?",
    [$refundId]);
$user = $read($store, "SELECT ID,UUID,ACCOUNT,TYPE,AI_USER_ID FROM $sUser WHERE ID=?",
    [(int)($order['user_id'] ?? 0)]);
$aiId = (int)($user['ai_user_id'] ?? 0);
$walletBefore = $read($ai, "SELECT BALANCE FROM $aUser WHERE USER_ID=?", [$aiId]);
$refundSettleBefore = $count($ai,
    "SELECT COUNT(*) FROM $aSettlement WHERE REFUND_NO=? AND BIZ_TYPE='refund'",
    [(string)($refund['order_no'] ?? '')]);
$cashLogsBefore = $count($ai,
    "SELECT COUNT(*) FROM $aBalanceLog WHERE USER_ID=? AND ORDER_ID IN (?,?)",
    [$aiId, $orderId, $refundId]);
if ($order['remark'] !== $marker || $user['account'] !== $marker
    || strpos((string)$user['uuid'], 'CDXPARMOB-') !== 0
    || (int)$order['refund_status'] !== 3
    || (int)$refund['meal_order_id'] !== $orderId
    || (int)$refund['refund_status'] !== 2
    || (string)$walletBefore['balance'] === ''
    || $refundSettleBefore !== 1 || $cashLogsBefore !== 2) {
    throw new RuntimeException('Target is not an already-refunded synthetic order');
}
require_once $root . '/application/base/Security.php';
$token = \app\base\Security::encrypt(implode("\t", [
    (string)$user['id'], (string)$user['uuid'], $marker, '0', '', '', $marker,
]));
$originalType = (int)$user['type'];
if ($originalType !== 0) {
    $grant = $store->prepare("UPDATE $sUser SET TYPE=0 WHERE ID=? AND UUID=? AND ACCOUNT=?");
    $grant->execute([(int)$user['id'], $user['uuid'], $marker]);
    if ($grant->rowCount() !== 1) throw new RuntimeException('Synthetic admin grant not exact');
}
try {
    $context = stream_context_create(['http' => [
        'method' => 'POST',
        'header' => "Content-Type: application/x-www-form-urlencoded\r\ntoken: $token\r\n",
        'content' => http_build_query(['refund_id' => $refundId]),
        'timeout' => 30, 'ignore_errors' => true,
    ]]);
    $raw = file_get_contents($baseUrl . '/p/mealOrder/refundAgree', false, $context);
    $result = is_string($raw) ? json_decode($raw, true) : null;
    if (!is_array($result) || (int)($result['code'] ?? 0) === 0) {
        throw new RuntimeException('Repeated refund approval was accepted or non-JSON');
    }
    $walletAfter = $read($ai, "SELECT BALANCE FROM $aUser WHERE USER_ID=?", [$aiId]);
    $refundSettleAfter = $count($ai,
        "SELECT COUNT(*) FROM $aSettlement WHERE REFUND_NO=? AND BIZ_TYPE='refund'",
        [(string)$refund['order_no']]);
    $cashLogsAfter = $count($ai,
        "SELECT COUNT(*) FROM $aBalanceLog WHERE USER_ID=? AND ORDER_ID IN (?,?)",
        [$aiId, $orderId, $refundId]);
    if ((string)$walletAfter['balance'] !== (string)$walletBefore['balance']
        || $refundSettleAfter !== $refundSettleBefore || $cashLogsAfter !== $cashLogsBefore) {
        throw new RuntimeException('Repeated approval changed cash balance or ledger');
    }
    echo json_encode(['dialect' => $dialect, 'status' => 'passed',
        'order_id' => $orderId, 'refund_id' => $refundId,
        'repeat_code' => $result['code'], 'repeat_message' => $result['message'] ?? '',
        'wallet_unchanged' => true, 'refund_settlement_count' => $refundSettleAfter,
        'cash_log_count' => $cashLogsAfter], JSON_UNESCAPED_UNICODE) . PHP_EOL;
} finally {
    if ($originalType !== 0) {
        $restore = $store->prepare("UPDATE $sUser SET TYPE=? WHERE ID=? AND UUID=? AND ACCOUNT=?");
        $restore->execute([$originalType, (int)$user['id'], $user['uuid'], $marker]);
        $check = $read($store, "SELECT TYPE FROM $sUser WHERE ID=?", [(int)$user['id']]);
        if ((int)$check['type'] !== $originalType) {
            throw new RuntimeException('Synthetic admin permission not restored');
        }
    }
}
