<?php
declare(strict_types=1);

// Fixed public-read batch: never prints response bodies or connection values.
$lane = (string)($argv[1] ?? '');
if (!in_array($lane, ['B', 'C'], true)) {
    fwrite(STDERR, "DENIED business_http=0 business_dml=0\n");
    exit(78);
}
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 schema drift');
    }
    $port = 18102;
}
$http = static function (string $path, string $method = 'GET') use ($port): array {
    if (!in_array($method, ['GET', 'POST'], true)) throw new RuntimeException('unsupported method');
    $ctx = stream_context_create(['http' => [
        'method' => $method, 'header' => "platform: H5\r\n", 'ignore_errors' => true,
        'timeout' => 15, 'follow_location' => 0,
    ]]);
    $handle = @fopen('http://127.0.0.1:' . $port . $path, 'rb', false, $ctx);
    if (!is_resource($handle)) throw new RuntimeException('isolated AI worker unavailable');
    $raw = stream_get_contents($handle, 2097153);
    fclose($handle);
    if (!is_string($raw) || strlen($raw) > 2097152) throw new RuntimeException('response over cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['status'] ?? 0) !== 200
        || (string)($body['message'] ?? '') !== 'success') {
        throw new RuntimeException('HTTP business status failed: ' . $path);
    }
    return $body;
};
$sourcePage = static function (int $pageType) use ($db): ?array {
    if (!in_array($pageType, [10, 20], true)) throw new RuntimeException('unsupported page type');
    $row = $db->query('SELECT page_id,page_data FROM yoshop_page WHERE store_id=10001'
        . ' AND page_type=' . $pageType . ' ORDER BY page_id DESC')->fetch(PDO::FETCH_ASSOC);
    if (!is_array($row)) return null;
    return array_change_key_case($row, CASE_LOWER);
};
$before = $sourcePage(10);
if ($before === null) throw new RuntimeException('no original home page row');
$rawPage = json_decode(htmlspecialchars_decode((string)$before['page_data'], ENT_QUOTES), true);
if (!is_array($rawPage) || !is_array($rawPage['items'] ?? null)) {
    throw new RuntimeException('original page JSON invalid');
}
$page = $http('/api/Page/detail')['data']['pageData'] ?? null;
$pagePost = $http('/api/Page/detail', 'POST')['data']['pageData'] ?? null;
if (!is_array($page) || !is_array($page['items'] ?? null)) {
    throw new RuntimeException('HTTP home page shape invalid');
}
$rawTypes = array_map(static function ($item): string { return (string)($item['type'] ?? ''); }, $rawPage['items']);
$httpTypes = array_map(static function ($item): string { return (string)($item['type'] ?? ''); }, $page['items']);
if (!$httpTypes || $rawTypes !== $httpTypes || !is_array($page['page'] ?? null)
    || $pagePost !== $page) {
    throw new RuntimeException('home page component order differs from original page row');
}
$after = $sourcePage(10);
if ($before !== $after) throw new RuntimeException('original page row changed during read');
$custom = $sourcePage(20);
$customCount = 0;
if ($custom !== null) {
    $customRaw = json_decode(htmlspecialchars_decode((string)$custom['page_data'], ENT_QUOTES), true);
    if (!is_array($customRaw) || !is_array($customRaw['items'] ?? null)) {
        throw new RuntimeException('original custom page JSON invalid');
    }
    $path = '/api/Page/detail?pageId=' . (int)$custom['page_id'];
    $customGet = $http($path)['data']['pageData'] ?? null;
    $customPost = $http($path, 'POST')['data']['pageData'] ?? null;
    $customTypes = array_map(static function ($item): string {
        return (string)($item['type'] ?? '');
    }, $customRaw['items']);
    $customResultTypes = is_array($customGet['items'] ?? null)
        ? array_map(static function ($item): string {
            return (string)($item['type'] ?? '');
        }, $customGet['items']) : null;
    if ($customGet !== $customPost || $customTypes !== $customResultTypes
        || $custom !== $sourcePage(20)) {
        throw new RuntimeException('custom page HTTP differs from own source or method');
    }
    $customCount = count($customResultTypes);
}
$category = $http('/api/article.Category/list')['data']['list'] ?? null;
$categoryRows = $db->query('SELECT category_id,name,status,sort FROM yoshop_article_category'
    . ' WHERE store_id=10001 AND status=1 ORDER BY sort ASC,category_id ASC')->fetchAll(PDO::FETCH_ASSOC);
if (!is_array($category) || count($category) !== count($categoryRows)) {
    throw new RuntimeException('article categories differ from original table');
}
foreach ($category as $index => $row) {
    $source = array_change_key_case($categoryRows[$index], CASE_LOWER);
    if ((int)$row['category_id'] !== (int)$source['category_id']
        || (string)$row['name'] !== (string)$source['name']
        || (int)$row['status'] !== (int)$source['status']
        || (int)$row['sort'] !== (int)$source['sort']) {
        throw new RuntimeException('article category item differs from original row');
    }
}
$articles = $http('/api/Article/list')['data']['list'] ?? null;
$articleRows = $db->query('SELECT article_id,title FROM yoshop_article'
    . ' WHERE store_id=10001 AND status=1 AND is_delete=0'
    . ' ORDER BY sort ASC,create_time DESC')->fetchAll(PDO::FETCH_ASSOC);
if (!is_array($articles) || (int)($articles['total'] ?? -1) !== count($articleRows)
    || !is_array($articles['data'] ?? null)) {
    throw new RuntimeException('article pagination differs from original table');
}
foreach ($articles['data'] as $index => $row) {
    $source = array_change_key_case($articleRows[$index], CASE_LOWER);
    if ((int)$row['article_id'] !== (int)$source['article_id']
        || (string)$row['title'] !== (string)$source['title']) {
        throw new RuntimeException('article list item differs from original row');
    }
}
$expressGet = $http('/api/Express/list')['data']['list'] ?? null;
$expressPost = $http('/api/Express/list', 'POST')['data']['list'] ?? null;
$expressSource = $db->query('SELECT express_id,express_name FROM yoshop_express'
    . ' WHERE store_id=10001 ORDER BY sort ASC,express_id ASC')->fetchAll(PDO::FETCH_ASSOC);
if (!is_array($expressGet) || !$expressGet || $expressGet !== $expressPost
    || count($expressGet) !== count($expressSource)) {
    throw new RuntimeException('express GET/POST or original table count differs');
}
foreach ($expressGet as $index => $row) {
    $sourceRow = array_change_key_case($expressSource[$index], CASE_LOWER);
    if ((int)($row['express_id'] ?? 0) !== (int)$sourceRow['express_id']
        || (string)($row['express_name'] ?? '') !== (string)$sourceRow['express_name']) {
        throw new RuntimeException('express row differs from original table');
    }
}
$itemKeyTypes = [];
foreach ($page['items'] as $item) {
    $keys = [];
    foreach ($item as $key => $value) $keys[$key] = gettype($value);
    ksort($keys);
    $itemKeyTypes[(string)$item['type']] = $keys;
}
echo json_encode([
    'lane' => $lane, 'http' => 200, 'business_status' => 200,
    'home_page_source_row' => (int)$before['page_id'],
    'home_page_components' => count($httpTypes),
    'home_page_post_get_data_equal' => true,
    'custom_page_components' => $customCount,
    'home_page_types_sha256' => hash('sha256', json_encode($httpTypes)),
    'home_page_key_types_sha256' => hash('sha256', json_encode($itemKeyTypes)),
    'category_http_source_count' => count($category),
    'article_http_source_count' => count($articleRows),
    'article_page_rows' => count($articles['data']),
    'express_own_source_count' => count($expressGet),
    'express_get_post_data_equal' => true,
    'express_data_sha256' => hash('sha256', json_encode($expressGet,
        JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
    'business_dml' => 0,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
