<?php

declare(strict_types=1);

$dsn = getenv('POC_DSN');
$user = getenv('POC_USER');
$password = getenv('POC_PASSWORD');
$dispatcherFile = __DIR__ . '/Dispatcher.php';
if (!$dsn || !$user || !$password || !is_file($dispatcherFile)) exit(2);
require_once $dispatcherFile;

$pdo = new PDO($dsn, $user, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$table = 'CODEX_DISPATCHER_POC_' . strtoupper(bin2hex(random_bytes(4)));
$check = $pdo->prepare('SELECT COUNT(*) FROM USER_TABLES WHERE TABLE_NAME=?');
$check->execute([$table]);
if ((int)$check->fetchColumn() !== 0) throw new RuntimeException('Probe table already exists');
$created = false;
try {
    $pdo->exec('CREATE TABLE "' . $table . '" ('
        . 'ID INT AUTO_INCREMENT PRIMARY KEY, BIZ_TYPE VARCHAR(32) NOT NULL, BIZ_KEY VARCHAR(64) NOT NULL, '
        . 'SOURCE_ID VARCHAR(64), DETAIL_SNAPSHOT_JSON CLOB, EVENT_VERSION INT DEFAULT 1, '
        . 'STATUS INT DEFAULT 0, RETRY_COUNT INT DEFAULT 0, NEXT_RETRY_TIME TIMESTAMP, '
        . 'CREATE_BY VARCHAR(36), CREATE_TIME TIMESTAMP, UPDATE_TIME TIMESTAMP, LAST_ERROR VARCHAR(500) DEFAULT \'\', '
        . 'UNIQUE(BIZ_TYPE,BIZ_KEY))');
    $created = true;

    $class = new ReflectionClass(\app\common\service\wanyisheng\Dispatcher::class);
    $upsertMethod = $class->getMethod('enqueueSql');
    $upsertMethod->setAccessible(true);
    $insertMethod = $class->getMethod('insertIfMissingSql');
    $insertMethod->setAccessible(true);
    $upsert = $pdo->prepare($upsertMethod->invoke(null, $table, true));
    $insertOnly = $pdo->prepare($insertMethod->invoke(null, $table, true));
    $now = date('Y-m-d H:i:s');

    $upsert->execute(['order', 'o1', 'source-1', '{"a":1}', $now, $now, $now]);
    $upsert->execute(['order', 'o1', 'source-2', null, $now, $now, $now]);
    $row = $pdo->query("SELECT SOURCE_ID,DETAIL_SNAPSHOT_JSON,EVENT_VERSION,STATUS FROM $table WHERE BIZ_KEY='o1'")->fetch(PDO::FETCH_ASSOC);
    if ($row['SOURCE_ID'] !== 'source-2' || $row['DETAIL_SNAPSHOT_JSON'] !== '{"a":1}' || (int)$row['EVENT_VERSION'] !== 2 || (int)$row['STATUS'] !== 0) {
        throw new RuntimeException('Upsert did not preserve regular update behavior');
    }

    $pdo->exec("UPDATE $table SET STATUS=1,RETRY_COUNT=4,LAST_ERROR='retry',NEXT_RETRY_TIME=TIMESTAMP '2026-01-01 00:00:00' WHERE BIZ_KEY='o1'");
    $upsert->execute(['order', 'o1', 'source-3', '{"a":3}', $now, $now, $now]);
    $row = $pdo->query("SELECT SOURCE_ID,DETAIL_SNAPSHOT_JSON,EVENT_VERSION,STATUS,RETRY_COUNT,LAST_ERROR,NEXT_RETRY_TIME FROM $table WHERE BIZ_KEY='o1'")->fetch(PDO::FETCH_ASSOC);
    if ($row['SOURCE_ID'] !== 'source-3' || $row['DETAIL_SNAPSHOT_JSON'] !== '{"a":3}' || (int)$row['EVENT_VERSION'] !== 3
        || (int)$row['STATUS'] !== 1 || (int)$row['RETRY_COUNT'] !== 4 || $row['LAST_ERROR'] !== 'retry'
        || strpos((string)$row['NEXT_RETRY_TIME'], '2026-01-01') !== 0) {
        throw new RuntimeException('Upsert did not preserve processing-state behavior');
    }

    $insertOnly->execute(['order', 'o1', 'ignored', $now, $now, $now]);
    $matchedAffected = $insertOnly->rowCount();
    $insertOnly->execute(['order', 'o2', 'new', $now, $now, $now]);
    $insertedAffected = $insertOnly->rowCount();
    $count = (int)$pdo->query("SELECT COUNT(*) FROM $table")->fetchColumn();
    if ($matchedAffected !== 0 || $insertedAffected !== 1 || $count !== 2) {
        throw new RuntimeException('Insert-only MERGE did not preserve ignore-duplicate behavior');
    }
    echo json_encode(['upsert' => 'passed', 'processing_state' => 'passed', 'insert_if_missing' => 'passed', 'row_count' => $count]) . PHP_EOL;
} finally {
    if ($created) $pdo->exec('DROP TABLE "' . $table . '"');
}
