<?php
declare(strict_types=1);

$phase = (string)($argv[1] ?? '');
$lane = (string)($argv[2] ?? '');
$marker = (string)($argv[3] ?? '');
if (!in_array($phase, ['--audit', '--run'], true) || !in_array($lane, ['B', 'C'], true)
    || !preg_match('/^CDXCAT[A-F0-9]{12}$/D', $marker)
    || ($phase === '--run' && getenv('CDX_CATEGORY_RUN') !== 'ONE_ROOT_NO_IMAGE_V1')) {
    fwrite(STDERR, "DENIED business_http=0 business_dml=0\n"); exit(78);
}
if ($lane === 'B') {
    $c = parse_ini_file('/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local', true, INI_SCANNER_RAW)['DATABASE'] ?? null;
    if (!is_array($c) || strtolower((string)($c['TYPE'] ?? '')) !== 'mysql'
        || hash('sha256', (string)($c['HOSTNAME'] ?? ''))
            !== '47e8be48b0cfd56dcdb9d9d426e6637b245f340b4efad4cd2f084ec5851ecc8e'
        || hash('sha256', (string)($c['DATABASE'] ?? ''))
            !== 'cf7756b3bb52cf72f625689134015b877fdab3ad8eb3bb2ddd962bb35f6efd66') {
        throw new RuntimeException('B code-local AI MySQL identity drift');
    }
    $db = new PDO('mysql:host=' . $c['HOSTNAME'] . ';port=3306;dbname=' . $c['DATABASE']
        . ';charset=' . $c['CHARSET'], $c['USERNAME'], $c['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 schema drift');
    }
    $port = 18102;
}
$select = static function (string $sql, array $args = []) use ($db): array {
    $stmt = $db->prepare($sql); $stmt->execute($args);
    return array_map(static function (array $r): array {
        return array_change_key_case($r, CASE_LOWER);
    }, $stmt->fetchAll(PDO::FETCH_ASSOC));
};
$own = static function () use ($select, $marker): array {
    return $select('SELECT category_id,name,parent_id,image_id,status,sort,store_id'
        . ' FROM yoshop_category WHERE name=? AND store_id=10001', [$marker]);
};
if ($phase === '--audit') {
    echo json_encode(['lane' => $lane, 'phase' => 'audit',
        'owned_category_count' => count($own()), 'business_http' => 0, 'business_dml' => 0]), PHP_EOL;
    exit($own() ? 2 : 0);
}
if ($own()) throw new RuntimeException('category marker already exists');
$sourceCount = (int)$db->query('SELECT COUNT(*) FROM yoshop_category'
    . ' WHERE store_id=10001 AND status=1')->fetchColumn();
$result = []; $error = null;
try {
    $insert = $db->prepare('INSERT INTO yoshop_category'
        . ' (name,parent_id,image_id,status,sort,store_id,create_time,update_time)'
        . ' VALUES (?,?,?,?,?,?,?,?)');
    $now = time();
    $insert->execute([$marker, 0, 0, 1, 0, 10001, $now, $now]);
    $rows = $own();
    if (count($rows) !== 1 || (int)$rows[0]['parent_id'] !== 0
        || (int)$rows[0]['image_id'] !== 0 || (int)$rows[0]['status'] !== 1) {
        throw new RuntimeException('owned category original row absent');
    }
    $ctx = stream_context_create(['http' => ['method' => 'GET',
        'header' => "platform: H5\r\n", 'ignore_errors' => true,
        'follow_location' => 0, 'timeout' => 15]]);
    $handle = @fopen('http://127.0.0.1:' . $port . '/api/Category/list?storeId=10001',
        'rb', false, $ctx);
    if (!is_resource($handle)) throw new RuntimeException('isolated AI category HTTP unavailable');
    $raw = stream_get_contents($handle, 1048577); fclose($handle);
    if (!is_string($raw) || strlen($raw) > 1048576) throw new RuntimeException('category response cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['status'] ?? 0) !== 200
        || !is_array($body['data']['list'] ?? null)) {
        throw new RuntimeException('category HTTP business failure');
    }
    $list = $body['data']['list'];
    $matches = array_values(array_filter($list, static function ($v) use ($rows): bool {
        return is_array($v) && (int)($v['category_id'] ?? 0) === (int)$rows[0]['category_id'];
    }));
    if (count($matches) !== 1 || (string)($matches[0]['name'] ?? '') !== $marker
        || (int)($matches[0]['parent_id'] ?? -1) !== 0
        || (int)($matches[0]['image_id'] ?? -1) !== 0) {
        throw new RuntimeException('category own row missing/different in HTTP');
    }
    $types = [];
    foreach ($matches[0] as $key => $value) $types[(string)$key] = gettype($value);
    ksort($types);
    $result = ['lane' => $lane, 'business_http_ok' => 1,
        'source_before_count' => $sourceCount,
        'source_with_own_count' => $sourceCount + 1,
        'http_root_count' => count($list),
        'own_row_types' => $types,
        'own_row_type_sha' => hash('sha256', json_encode($types))];
} catch (Throwable $caught) { $error = $caught; }
finally {
    foreach ($own() as $row) {
        $stmt = $db->prepare('DELETE FROM yoshop_category'
            . ' WHERE category_id=? AND name=? AND store_id=10001');
        $stmt->execute([(int)$row['category_id'], $marker]);
    }
}
if ($own() || (int)$db->query('SELECT COUNT(*) FROM yoshop_category'
    . ' WHERE store_id=10001 AND status=1')->fetchColumn() !== $sourceCount) {
    throw new RuntimeException('owned category cleanup or natural count failed');
}
if ($error !== null) throw $error;
$result['owned_category_cleanup_zero'] = true;
echo json_encode($result, JSON_UNESCAPED_SLASHES), PHP_EOL;
