<?php
declare(strict_types=1);

$phase = (string)($argv[1] ?? '');
$lane = (string)($argv[2] ?? '');
$guest = (string)($argv[3] ?? '');
if (!in_array($phase, ['--run', '--audit'], true) || !in_array($lane, ['B', 'C'], true)
    || !preg_match('/^guest_cdx[a-f0-9]{16}$/D', $guest)
    || ($phase === '--run' && getenv('CDX_CHAT_GUEST_RUN') !== 'ONE_EMPTY_MESSAGE_SESSION_V1')) {
    fwrite(STDERR, "DENIED business_http=0 business_dml=0\n"); exit(78);
}
$bot = 'cdxchatbot';
$conversation = 'cdxchat_' . substr($guest, -16);
if ($lane === 'B') {
    $config = parse_ini_file('/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local', true, INI_SCANNER_RAW)['DATABASE'] ?? null;
    if (!is_array($config) || strtolower((string)($config['TYPE'] ?? '')) !== 'mysql'
        || (string)($config['HOSTPORT'] ?? '') !== '3306'
        || hash('sha256', (string)($config['HOSTNAME'] ?? '')) !== '47e8be48b0cfd56dcdb9d9d426e6637b245f340b4efad4cd2f084ec5851ecc8e'
        || hash('sha256', (string)($config['DATABASE'] ?? '')) !== 'cf7756b3bb52cf72f625689134015b877fdab3ad8eb3bb2ddd962bb35f6efd66') {
        throw new RuntimeException('B code-local AI MySQL identity drift');
    }
    $db = new PDO('mysql:host=' . $config['HOSTNAME'] . ';port=3306;dbname='
        . $config['DATABASE'] . ';charset=' . $config['CHARSET'],
        $config['USERNAME'], $config['PASSWORD'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
    $port = 18101;
} 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') {
        throw new RuntimeException('C isolated AI DM 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 effective AI schema drift');
    }
    $port = 18102;
}
$all = static function (string $sql, array $args = []) use ($db): array {
    $stmt = $db->prepare($sql);
    $stmt->execute($args);
    return array_map(static function (array $row): array {
        return array_change_key_case($row, CASE_LOWER);
    }, $stmt->fetchAll(PDO::FETCH_ASSOC));
};
$ownMessages = static function () use ($all, $guest, $bot, $conversation): array {
    return $all('SELECT id,user_id,store_id,bot_id,conversation_id,content,content_file_url'
        . ' FROM yoshop_ai_conversation WHERE user_id=? AND store_id=10001'
        . ' AND bot_id=? AND conversation_id=?', [$guest, $bot, $conversation]);
};
$ownSessions = static function () use ($all, $guest, $bot, $conversation): array {
    return $all('SELECT id,user_id,ai_user_id,store_id,bot_id,conversation_id,'
        . 'message_count,is_current,is_delete FROM yoshop_ai_conversation_session'
        . ' WHERE ai_user_id=? AND store_id=10001 AND bot_id=? AND conversation_id=?',
        [$guest, $bot, $conversation]);
};
$before = [count($ownMessages()), count($ownSessions())];
if ($phase === '--audit') {
    echo json_encode(['lane' => $lane, 'phase' => 'audit',
        'guest_sha12' => substr(hash('sha256', $guest), 0, 12),
        'owned_message_session_counts' => $before,
        'business_http' => 0, 'business_dml' => 0]), PHP_EOL;
    exit($before === [0, 0] ? 0 : 2);
}
if ($before !== [0, 0]) throw new RuntimeException('guest marker already has rows');
$http = static function (string $path, array $form) use ($port): array {
    if (!in_array($path, ['/api/user.AiConversation/identity',
        '/api/user.AiConversation/add', '/api/user.AiConversation/lists',
        '/api/user.AiConversation/sessionList',
        '/api/user.AiConversation/currentSession'], true)) {
        throw new RuntimeException('unsupported fixed guest route');
    }
    $bodyJson = json_encode($form, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    if (!is_string($bodyJson)) throw new RuntimeException('chat form JSON encode failed');
    $ctx = stream_context_create(['http' => [
        'method' => 'POST', 'header' => "platform: H5\r\nContent-Type: application/json\r\n",
        'content' => $bodyJson, '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 guest HTTP unavailable');
    $raw = stream_get_contents($handle, 524289);
    fclose($handle);
    if (!is_string($raw) || strlen($raw) > 524288) throw new RuntimeException('chat response cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['status'] ?? 0) !== 200) {
        throw new RuntimeException('chat HTTP business failure at ' . $path
            . ' status=' . (string)($body['status'] ?? 'nonjson')
            . ' message=' . substr((string)($body['message'] ?? ''), 0, 100));
    }
    return $body;
};
$typeGraph = static function ($value) use (&$typeGraph) {
    if (!is_array($value)) return gettype($value);
    if (!$value) return [];
    if (array_keys($value) === range(0, count($value) - 1)) return array_map($typeGraph, $value);
    ksort($value);
    return array_map($typeGraph, $value);
};
$error = null;
$result = [];
try {
    $identity = $http('/api/user.AiConversation/identity', ['guest_id' => $guest])['data'] ?? null;
    if (!is_array($identity) || ($identity['is_login'] ?? null) !== false
        || (int)($identity['user_id'] ?? -1) !== 0
        || (string)($identity['guest_id'] ?? '') !== $guest) {
        throw new RuntimeException('guest identity response differs from input');
    }
    if ($ownMessages() || $ownSessions()) throw new RuntimeException('identity unexpectedly wrote chat rows');
    $result['identity'] = hash('sha256', json_encode($typeGraph($identity)));

    $added = $http('/api/user.AiConversation/add', [
        'ai_user_id' => $guest, 'bot_id' => $bot,
        'conversation_id' => $conversation, 'additional_messages' => [],
    ]);
    if (($added['message'] ?? null) !== '保存成功' || ($added['data'] ?? null) !== []) {
        throw new RuntimeException('empty-message metadata save response invalid');
    }
    $messages = $ownMessages();
    $sessions = $ownSessions();
    if (count($messages) !== 1 || count($sessions) !== 1
        || (string)$messages[0]['user_id'] !== $guest
        || (string)$messages[0]['content_file_url'] !== ''
        || (int)$sessions[0]['user_id'] !== 0
        || (string)$sessions[0]['ai_user_id'] !== $guest
        || (int)$sessions[0]['is_current'] !== 1
        || (int)$sessions[0]['is_delete'] !== 0) {
        throw new RuntimeException('guest message/session original rows differ');
    }
    $result['add'] = hash('sha256', json_encode($typeGraph($added)));

    $params = ['ai_user_id' => $guest, 'bot_id' => $bot,
        'conversation_id' => $conversation];
    $listBody = $http('/api/user.AiConversation/lists', $params)['data'] ?? null;
    $list = $listBody['lists']['rows'] ?? null;
    $sessionsBody = $http('/api/user.AiConversation/sessionList', $params)['data']['sessions'] ?? null;
    $current = $http('/api/user.AiConversation/currentSession', $params)['data']['session'] ?? null;
    if (!is_array($list) || (int)($listBody['lists']['total'] ?? -1) !== 1
        || count($list) !== 1
        || !is_array($sessionsBody) || (int)($sessionsBody['total'] ?? -1) !== 1
        || !is_array($current)
        || (string)($current['conversation_id'] ?? '') !== $conversation) {
        throw new RuntimeException('guest chat readbacks lack owned message/session');
    }
    if (count($ownMessages()) !== 1 || count($ownSessions()) !== 1) {
        throw new RuntimeException('guest chat readbacks changed own row counts');
    }
    $result['lists'] = hash('sha256', json_encode($typeGraph($list)));
    $result['sessionList'] = hash('sha256', json_encode($typeGraph($sessionsBody)));
    $result['currentSession'] = hash('sha256', json_encode($typeGraph($current)));
} catch (Throwable $caught) {
    $error = $caught;
} finally {
    foreach ($ownMessages() as $row) {
        $stmt = $db->prepare('DELETE FROM yoshop_ai_conversation'
            . ' WHERE id=? AND user_id=? AND bot_id=? AND conversation_id=? AND store_id=10001');
        $stmt->execute([(int)$row['id'], $guest, $bot, $conversation]);
    }
    foreach ($ownSessions() as $row) {
        $stmt = $db->prepare('DELETE FROM yoshop_ai_conversation_session'
            . ' WHERE id=? AND ai_user_id=? AND bot_id=? AND conversation_id=? AND store_id=10001');
        $stmt->execute([(int)$row['id'], $guest, $bot, $conversation]);
    }
}
if ($ownMessages() || $ownSessions()) throw new RuntimeException('guest owned rows cleanup failed');
if ($error !== null) throw $error;
echo json_encode(['lane' => $lane, 'guest_sha12' => substr(hash('sha256', $guest), 0, 12),
    'http_business_ok' => 5, 'type_hashes' => $result,
    'owned_message_session_cleanup_zero' => true,
    'business_dml' => 'one-empty-message-and-one-session-insert-exact-delete',
    'OSS_real_file_requests' => 0], JSON_UNESCAPED_SLASHES), PHP_EOL;
