<?php

declare(strict_types=1);

// One bounded sport-target write, shared controller route on A/B/C.
$root = (string)getenv('POC_TARGET_ROOT');
$baseUrl = rtrim((string)getenv('POC_BASE_URL'), '/');
$dialect = (string)getenv('POC_DIALECT');
$variant = (string)getenv('POC_VARIANT');
$mode = (string)($argv[1] ?? '--preflight');
if ($root === '' || $baseUrl === '' || !in_array($dialect, ['mysql', 'dm'], true)
    || !in_array($variant, ['A', 'B', 'C'], true)
    || ($variant === 'C') !== ($dialect === 'dm')
    || !in_array($mode, ['--preflight', '--execute', '--audit'], true)) {
    throw new RuntimeException('Explicit isolated sport-target target and mode required');
}
if ($dialect === 'mysql') {
    $local = parse_ini_file((string)getenv('POC_MYSQL_LOCAL_ENV'), true, INI_SCANNER_RAW);
    if (!is_array($local) || !isset($local['DATABASE'])) {
        throw new RuntimeException('Code .env.local AI database unavailable');
    }
    foreach (['HOSTNAME' => 'HOST', 'HOSTPORT' => 'PORT', 'DATABASE' => 'SCHEMA',
        'USERNAME' => 'USER', 'PASSWORD' => 'PASSWORD'] as $from => $to) {
        putenv('POC_AI_' . $to . '=' . (string)$local['DATABASE'][$from]);
    }
} else {
    $pid = (int)getenv('POC_IMPORT_SERVER_PID');
    $command = $pid > 0 ? @file_get_contents('/proc/' . $pid . '/cmdline') : false;
    if (!is_string($command) || strpos($command, '127.0.0.1:18102') === false
        || strpos($command, $root . '/public') === false) {
        throw new RuntimeException('Verified isolated C HTTP process required');
    }
    $serverEnv = @file_get_contents('/proc/' . $pid . '/environ');
    if (!is_string($serverEnv)) throw new RuntimeException('C process environment unavailable');
    foreach (explode("\0", $serverEnv) as $entry) {
        if (strpos($entry, 'POC_AI_') === 0) putenv($entry);
    }
}
foreach (['POC_AI_HOST', 'POC_AI_PORT', 'POC_AI_SCHEMA', 'POC_AI_USER',
    'POC_AI_PASSWORD'] as $part) {
    if ((string)getenv($part) === '') throw new RuntimeException('Selected AI database incomplete');
}
if ($dialect === 'dm' && ((string)getenv('POC_AI_SCHEMA') !== 'AIZHCT_APP'
    || (string)getenv('POC_AI_PORT') !== '5238')) {
    throw new RuntimeException('Unexpected C database identity');
}
$boundary = json_decode((string)@file_get_contents($baseUrl . '/__poc_boundary'), true);
if (empty($boundary['external_stubs'])) throw new RuntimeException('External stubs unavailable');

define('TP_ENV', 'poc');
define('BUSINESS', 'aizhct');
define('ENTERPRISE_NO', '10001');
require $root . '/vendor/autoload.php';
(new \think\App($root))->setEnvName('poc')->initialize();
$dsn = $dialect === 'dm'
    ? 'dm:host=' . getenv('POC_AI_HOST') . ';port=' . getenv('POC_AI_PORT')
        . ';schema=' . getenv('POC_AI_SCHEMA')
    : 'mysql:host=' . getenv('POC_AI_HOST') . ';port=' . getenv('POC_AI_PORT')
        . ';dbname=' . getenv('POC_AI_SCHEMA') . ';charset=utf8mb4';
$db = new PDO($dsn, getenv('POC_AI_USER'), getenv('POC_AI_PASSWORD'),
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$userTable = $dialect === 'dm' ? 'YOSHOP_USER' : 'yoshop_user';
$targetTable = $dialect === 'dm' ? 'YOSHOP_USER_SPORT_TARGET' : 'yoshop_user_sport_target';
$columns = [
    'user' => $db->query("SELECT * FROM $userTable WHERE 1=0")->columnCount(),
    'target' => $db->query("SELECT * FROM $targetTable WHERE 1=0")->columnCount(),
];
if ($mode === '--preflight') {
    echo json_encode(['mode' => 'preflight', 'dialect' => $dialect,
        'schema' => (string)getenv('POC_AI_SCHEMA'), 'columns' => $columns,
        'external_stubs' => true], JSON_UNESCAPED_UNICODE) . PHP_EOL;
    exit(0);
}
$read = static function (string $sql, array $args = []) use ($db): array {
    $statement = $db->prepare($sql);
    $statement->execute($args);
    $row = $statement->fetch(PDO::FETCH_ASSOC);
    return $row === false ? [] : array_change_key_case($row);
};
$count = static function (string $sql, array $args = []) use ($db): int {
    $statement = $db->prepare($sql);
    $statement->execute($args);
    return (int)$statement->fetchColumn();
};
if ($mode === '--audit') {
    $marker = (string)($argv[2] ?? '');
    $userId = (int)($argv[3] ?? 0);
    if (!preg_match('/^CDXPARSTARGET[0-9A-F]{8}$/', $marker) || $userId <= 0) {
        throw new RuntimeException('Exact synthetic target marker/user ID required');
    }
    $counts = [
        'user' => $count("SELECT COUNT(*) FROM $userTable WHERE USER_ID=? AND NICK_NAME=?",
            [$userId, $marker]),
        'target' => $count("SELECT COUNT(*) FROM $targetTable WHERE USER_ID=?",
            [$userId]),
    ];
    if (array_sum($counts) !== 0) throw new RuntimeException('Independent target cleanup audit failed');
    echo json_encode(['mode' => 'audit', 'dialect' => $dialect,
        'remaining_rows' => $counts], JSON_UNESCAPED_UNICODE) . PHP_EOL;
    exit(0);
}

$transportUnknown = false;
$request = static function (string $path, string $method, string $token,
    array $payload = []) use ($baseUrl, &$transportUnknown): array {
    $headers = "platform: POC\r\n";
    if ($method === 'POST') $headers .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $headers .= 'Access-Token: ' . $token . "\r\n";
    $url = $baseUrl . $path . '?storeId=10001';
    $context = stream_context_create(['http' => [
        'method' => $method, 'header' => $headers,
        'content' => $method === 'POST' ? http_build_query(['form' => $payload]) : '',
        'timeout' => 30, 'ignore_errors' => true, 'follow_location' => 0,
    ]]);
    $started = microtime(true);
    $raw = @file_get_contents($url, false, $context);
    $httpLine = $http_response_header[0] ?? '';
    $body = is_string($raw) ? json_decode($raw, true) : null;
    if (!is_array($body)) {
        $transportUnknown = true;
        throw new RuntimeException('Transport/body uncertain at ' . $path);
    }
    return ['http' => (int)(preg_match('/HTTP\/\S+\s+(\d+)/', $httpLine, $m) ? $m[1] : 0),
        'status' => (int)($body['status'] ?? -1),
        'message' => (string)($body['message'] ?? ''), 'data' => $body['data'] ?? null,
        'elapsed_ms' => (int)round((microtime(true) - $started) * 1000)];
};
$shape = static function (array $response): array {
    return ['http' => $response['http'], 'status' => $response['status'],
        'message' => $response['message'], 'data_type' => gettype($response['data']),
        'data_keys' => is_array($response['data']) ? array_keys($response['data']) : [],
        'data_types' => is_array($response['data'])
            ? array_map('gettype', $response['data']) : [],
        'elapsed_ms' => $response['elapsed_ms']];
};
$assert = static function (bool $ok, string $message): void {
    if (!$ok) throw new RuntimeException($message);
};
$marker = 'CDXPARSTARGET' . strtoupper(bin2hex(random_bytes(4)));
$token = $marker . 'T' . strtoupper(bin2hex(random_bytes(10)));
$userId = 0;
$today = date('Y-m-d');
try {
    $db->prepare("INSERT INTO $userTable"
        . ' (STORE_ID,MOBILE,NICK_NAME,BALANCE,GIFT_BALANCE,IS_DELETE,CREATE_TIME)'
        . ' VALUES (10001,?,?,?,?,0,?)')
        ->execute(['', $marker, '0.00', '0.00', time()]);
    $userId = (int)($read("SELECT USER_ID FROM $userTable WHERE NICK_NAME=?",
        [$marker])['user_id'] ?? 0);
    $assert($userId > 0 && $count("SELECT COUNT(*) FROM $targetTable WHERE USER_ID=?",
        [$userId]) === 0, 'Synthetic target fixture incomplete');
    \think\facade\Cache::set($token, ['user' => ['user_id' => $userId],
        'password_version' => 0, 'login_type' => 'thirdparty'], 300);

    $set = $request('/api/user.UserSportTarget/set', 'POST', $token, ['type' => 3]);
    $row = $read("SELECT ID,STORE_ID,USER_ID,TYPE,DATE,IS_DELETE"
        . " FROM $targetTable WHERE USER_ID=? ORDER BY ID DESC", [$userId]);
    $assert($set['http'] === 200 && $set['status'] === 200
        && $count("SELECT COUNT(*) FROM $targetTable WHERE USER_ID=?", [$userId]) === 1
        && (int)($row['id'] ?? 0) > 0
        && (int)($row['store_id'] ?? 0) === 10001
        && (int)($row['user_id'] ?? 0) === $userId
        && (int)($row['type'] ?? 0) === 3
        && (string)($row['date'] ?? '') === $today
        && (int)($row['is_delete'] ?? -1) === 0
        && (int)($set['data']['id'] ?? 0) === (int)$row['id']
        && (int)($set['data']['type'] ?? 0) === 3,
        'Sport-target set HTTP/original-table mismatch');
    $current = $request('/api/user.UserSportTarget/current', 'GET', $token);
    $assert($current['http'] === 200 && $current['status'] === 200
        && (int)($current['data']['id'] ?? 0) === (int)$row['id']
        && (int)($current['data']['type'] ?? 0) === 3
        && (string)($current['data']['date'] ?? '') === $today,
        'Sport-target current API readback mismatch');
    $alias = null;
    if ($variant !== 'A') {
        // Only the compatibility code has this conventional-routing alias.
        $alias = $request('/api/user.sport_target/current', 'GET', $token);
        $assert($alias['http'] === 200 && $alias['status'] === 200
            && (int)($alias['data']['id'] ?? 0) === (int)$row['id'],
            'Compatibility alias current route mismatch');
    }
    echo json_encode(['mode' => 'execute', 'variant' => $variant, 'dialect' => $dialect,
        'marker' => $marker, 'user_id' => $userId,
        'response' => ['set' => $shape($set), 'current' => $shape($current),
            'compat_alias_current' => $alias === null ? null : $shape($alias)],
        'original_table' => ['rows' => 1, 'type' => (int)$row['type'],
            'date' => (string)$row['date'], 'is_delete' => (int)$row['is_delete']]],
        JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
} finally {
    if ($transportUnknown) {
        fwrite(STDERR, 'Transport unknown; fixture retained for manual recovery: '
            . $marker . PHP_EOL);
    } else {
        \think\facade\Cache::delete($token);
        $db->prepare("DELETE FROM $targetTable WHERE USER_ID=?")->execute([$userId]);
        $db->prepare("DELETE FROM $userTable WHERE USER_ID=? AND NICK_NAME=?")
            ->execute([$userId, $marker]);
        $left = $count("SELECT COUNT(*) FROM $targetTable WHERE USER_ID=?", [$userId])
            + $count("SELECT COUNT(*) FROM $userTable WHERE USER_ID=? AND NICK_NAME=?",
                [$userId, $marker]);
        if ($left !== 0) throw new RuntimeException('Synthetic target cleanup left rows=' . $left);
        fwrite(STDERR, 'Synthetic sport-target cleanup rows=0' . PHP_EOL);
    }
}
