<?php
declare(strict_types=1);

$root = (string)getenv('POC_APP_ROOT');
$base = rtrim((string)getenv('POC_BASE_URL'), '/');
$dialect = (string)getenv('POC_DIALECT');
if (!is_file($root . '/application/base/Security.php') || $base === ''
    || !in_array($dialect, ['mysql', 'dm'], true)) exit(2);
$boundary = json_decode((string)file_get_contents($base . '/__poc_boundary'), true);
if (empty($boundary['external_stubs']) || empty($boundary['redis_isolated'])) {
    throw new RuntimeException('Isolated HTTP boundary missing');
}
$connect = static function (bool $ai) use ($dialect): PDO {
    $prefix = $ai ? 'POC_AI_' : 'POC_';
    $host = getenv($prefix . 'HOST'); $port = getenv($prefix . 'PORT');
    $schema = getenv($prefix . 'SCHEMA');
    return new PDO($dialect === 'dm' ? "dm:host=$host;port=$port;schema=$schema"
        : "mysql:host=$host;port=$port;dbname=$schema;charset=utf8mb4",
        getenv($prefix . 'USER'), getenv($prefix . 'PASSWORD'), [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER,
        ]);
};
$store = $connect(false); $ai = $connect(true);
$t = static function (string $name, bool $isAi = false) use ($dialect): string {
    $name = ($isAi ? 'yoshop_' : 'ydy_') . $name;
    return $dialect === 'dm' ? strtoupper($name) : $name;
};
if (getenv('POC_AUDIT_ONLY') === '1') {
    $users = (int)$ai->query('SELECT COUNT(*) FROM ' . $t('user', true)
        . " WHERE NICK_NAME LIKE 'CDXZTRD%'")->fetchColumn();
    $sessions = (int)$store->query('SELECT COUNT(*) FROM ' . $t('measurement_session')
        . " WHERE DEVICE_MODEL LIKE 'CDXZTRD%'")->fetchColumn();
    echo json_encode(['audit_only' => true, 'synthetic_users' => $users,
        'synthetic_sessions' => $sessions]) . PHP_EOL;
    exit(($users === 0 && $sessions === 0) ? 0 : 1);
}
$marker = 'CDXZTRD' . strtoupper(bin2hex(random_bytes(6)));
$userId = 0; $sessions = []; $results = [];
$day1 = date('Y-m-d', strtotime('-1 day')); $day2 = date('Y-m-d');
if (getenv('POC_GROUP_CHECK') === '1') {
    $day1 = '2005-01-02'; $day2 = '2005-01-03';
    $q = $store->prepare('SELECT COUNT(*) FROM ' . $t('measurement_session') . ' WHERE START_TIME>=? AND START_TIME<=?');
    $q->execute([$day1 . ' 00:00:00', $day2 . ' 23:59:59']);
    if ((int)$q->fetchColumn() !== 0) throw new RuntimeException('Group fixture date range is not empty');
}
$time1 = $day1 . ' 10:00:00'; $time2 = $day2 . ' 10:00:00';
require_once $root . '/application/base/Security.php';
$token = \app\base\Security::encrypt(implode("\t", ['0', $marker, $marker, '0', '', '', $marker]));
$post = static function (string $route, array $form, bool $auth = true, string $method = 'POST') use ($base, $token): array {
    $context = stream_context_create(['http' => [
        'method' => $method, 'header' => "Content-Type: application/x-www-form-urlencoded\r\n"
            . ($auth ? 'token: ' . $token . "\r\n" : ''),
        'content' => http_build_query($form), 'timeout' => 30, 'ignore_errors' => true,
    ]]);
    $body = file_get_contents($base . $route, false, $context);
    if (!preg_match('#^HTTP/\S+\s+200(?:\s|$)#', $http_response_header[0] ?? '')) {
        throw new RuntimeException('Health report unexpected transport status');
    }
    $data = is_string($body) ? json_decode($body, true) : null;
    if (!is_array($data)) throw new RuntimeException('Health report HTTP did not return JSON');
    return $data;
};
try {
    $metric = $store->query('SELECT COUNT(*) FROM ' . $t('health_metric') . " WHERE METRIC_CODE='weight'")->fetchColumn();
    if ((int)$metric !== 1) throw new RuntimeException('Weight dictionary is not available');
    $q = $ai->prepare('INSERT INTO ' . $t('user', true)
        . ' (STORE_ID,MOBILE,NICK_NAME,BALANCE,GIFT_BALANCE,IS_DELETE,CREATE_TIME) VALUES (10001,?,?,?,?,0,?)');
    $q->execute(['', $marker, '0.00', '0.00', time()]); $userId = (int)$ai->lastInsertId();
    if ($userId <= 0) throw new RuntimeException('Synthetic health user insert failed');
    foreach ([[$time1, '70.50'], [$time2, '69.50']] as [$measuredAt, $weight]) {
        $q = $store->prepare('INSERT INTO ' . $t('measurement_session')
            . ' (AI_USER_ID,EVENT_TYPE,START_TIME,SOURCE_PLATFORM,VENDOR,DEVICE_TYPE,DEVICE_MODEL,BUSINESS_CONTEXT,IS_VALID)'
            . ' VALUES (?,?,?,?,?,?,?,?,1)');
        $q->execute([$userId, 'measurement', $measuredAt, 'direct_device', 'zhaiker',
            'body_scale', $marker, 'health']);
        $sessionId = (int)$store->lastInsertId();
        if ($sessionId <= 0) throw new RuntimeException('Synthetic health session insert failed');
        $sessions[] = $sessionId;
        $q = $store->prepare('INSERT INTO ' . $t('health_record')
            . ' (SESSION_ID,AI_USER_ID,METRIC_CODE,VALUE,UNIT,SEGMENT,SEGMENT_KEY,START_TIME) VALUES (?,?,?,?,?,NULL,?,?)');
        $q->execute([$sessionId, $userId, 'weight', $weight, 'kg', '', $measuredAt]);
    }
    $q = $store->prepare('SELECT VALUE,START_TIME FROM ' . $t('health_record')
        . ' WHERE AI_USER_ID=? ORDER BY START_TIME');
    $q->execute([$userId]); $source = $q->fetchAll(PDO::FETCH_ASSOC);
    if (count($source) !== 2 || bccomp((string)$source[0]['value'], '70.50', 2) !== 0
        || bccomp((string)$source[1]['value'], '69.50', 2) !== 0) {
        throw new RuntimeException('Health fixture independent readback failed');
    }
    $params = ['ai_user_id' => $userId, 'metric_codes' => 'weight',
        'start_date' => $day1, 'end_date' => $day2];
    $anon = $post('/p/zhaikerHealth/personalTrend', $params, false);
    $results['no_auth'] = ['pass' => (int)($anon['code'] ?? 0) === 100];
    $trend = $post('/p/zhaikerHealth/personalTrend', $params);
    $detail = $trend['data']['detail_rows'] ?? [];
    $results['trend'] = [
        'business_pass' => (int)($trend['code'] ?? -1) === 0 && count($detail) === 2
            && (float)($detail[0]['value'] ?? 0) === 70.5 && (float)($detail[1]['value'] ?? 0) === 69.5,
        'time_contract_pass' => ($detail[0]['record_time'] ?? null) === $time1
            && ($detail[1]['record_time'] ?? null) === $time2,
        'code' => $trend['code'] ?? null, 'message' => $trend['message'] ?? null,
        'record_times' => array_column($detail, 'record_time'),
    ];
    $dates = $post('/p/zhaikerHealth/personalChangeRateDates', $params);
    $values = array_column($dates['data']['metric_date_options']['weight'] ?? [], 'value');
    $results['dates'] = ['pass' => (int)($dates['code'] ?? -1) === 0
        && $values === [$day2, $day1], 'code' => $dates['code'] ?? null];
    $rate = $post('/p/zhaikerHealth/personalChangeRate', [
        'ai_user_id' => $userId,
        'metric_items' => json_encode([['metric_code' => 'weight', 'target_date' => $day2]]),
    ]);
    $rateRow = $rate['data']['rows'][0] ?? [];
    $results['change_rate'] = [
        'business_pass' => (int)($rate['code'] ?? -1) === 0
            && ($rateRow['current_value'] ?? null) === '69.5 kg'
            && ($rateRow['day_value'] ?? null) === '70.5 kg',
        'time_contract_pass' => ($rateRow['base_dates']['current'] ?? null) === $time2
            && ($rateRow['base_dates']['day'] ?? null) === $time1,
        'code' => $rate['code'] ?? null, 'message' => $rate['message'] ?? null,
        'base_dates' => $rateRow['base_dates'] ?? [],
    ];
    $invalid = $post('/p/zhaikerHealth/personalTrend', array_replace($params, ['ai_user_id' => 0]));
    $reverse = $post('/p/zhaikerHealth/personalTrend', array_replace($params,
        ['start_date' => $day2, 'end_date' => $day1]));
    $results['invalid'] = ['pass' => (int)($invalid['code'] ?? 0) !== 0
        && (int)($reverse['code'] ?? 0) !== 0];
    if (getenv('POC_GROUP_CHECK') === '1') {
        $group = $post('/p/zhaikerHealth/groupAnalysis', $params);
        $summary = $group['data']['summary_rows'][0] ?? [];
        $results['group'] = ['pass' => ($group['code'] ?? null) === 0
            && ($group['data']['group_size'] ?? null) === 1
            && ($group['data']['record_count'] ?? null) === 2
            && ($summary['sample_count'] ?? null) === 2
            && (float)($summary['avg'] ?? 0) === 70.0
            && (float)($summary['stddev'] ?? 0) === 0.71
            && (float)($summary['min'] ?? 0) === 69.5
            && (float)($summary['max'] ?? 0) === 70.5,
            'code' => $group['code'] ?? null, 'message' => $group['message'] ?? null];
        foreach (['GET', 'POST'] as $method) {
            $options = $post('/p/zhaikerHealth/baseOptions', [], true, $method);
            $users = array_filter($options['data']['users'] ?? [], static function (array $user) use ($userId): bool {
                return (int)($user['ai_user_id'] ?? 0) === $userId;
            });
            $results['base_options_' . $method] = ['pass' => ($options['code'] ?? null) === 0
                && count($users) === 1
                && in_array('weight', array_column($options['data']['metrics'] ?? [], 'metric_code'), true)];
        }
        $groupAnon = $post('/p/zhaikerHealth/groupAnalysis', $params, false);
        $groupInvalid = $post('/p/zhaikerHealth/groupAnalysis', array_replace($params, ['metric_codes' => 'unknown']));
        $results['group_negative'] = ['pass' => ($groupAnon['code'] ?? null) === 100 && ($groupInvalid['code'] ?? 0) !== 0];
    }
} finally {
    foreach ($sessions as $sessionId) {
        $store->prepare('DELETE FROM ' . $t('health_record') . ' WHERE SESSION_ID=? AND AI_USER_ID=?')
            ->execute([$sessionId, $userId]);
        $store->prepare('DELETE FROM ' . $t('measurement_session') . ' WHERE SESSION_ID=? AND DEVICE_MODEL=?')
            ->execute([$sessionId, $marker]);
    }
    if ($userId > 0) {
        $ai->prepare('DELETE FROM ' . $t('user', true) . ' WHERE USER_ID=? AND NICK_NAME=?')
            ->execute([$userId, $marker]);
        foreach ([[$store, $t('health_record'), 'AI_USER_ID'],
            [$store, $t('measurement_session'), 'AI_USER_ID'], [$ai, $t('user', true), 'USER_ID']] as [$db, $table, $column]) {
            $q = $db->prepare('SELECT COUNT(*) FROM ' . $table . ' WHERE ' . $column . '=?');
            $q->execute([$userId]); if ((int)$q->fetchColumn() !== 0) {
                throw new RuntimeException('Health report synthetic cleanup left rows');
            }
        }
    }
}
echo json_encode(['dialect' => $dialect, 'results' => $results, 'cleanup_zero' => true],
    JSON_UNESCAPED_UNICODE) . PHP_EOL;
foreach ($results as $result) {
    foreach ($result as $name => $value) {
        if (($name === 'pass' || substr($name, -5) === '_pass') && $value !== true) {
            exit(1);
        }
    }
}
