<?php

declare(strict_types=1);

$root = getenv('POC_TARGET_ROOT');
$url = getenv('POC_BASE_URL');
$dialect = getenv('POC_DIALECT');
if (!$root || !$url || !in_array($dialect, ['mysql', 'dm'], true)) exit(2);
$config = require $root . '/application/database.php';
foreach (['hostname', 'hostport', 'database', 'username', 'password'] as $key) {
    if (empty($config[$key])) throw new RuntimeException('Isolated business connection incomplete');
}
$dsn = $dialect === 'dm'
    ? 'dm:host=' . $config['hostname'] . ';port=' . $config['hostport'] . ';schema=' . $config['database']
    : 'mysql:host=' . $config['hostname'] . ';port=' . $config['hostport'] . ';dbname=' . $config['database'] . ';charset=utf8mb4';
$pdo = new PDO($dsn, $config['username'], $config['password'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$restaurants = $dialect === 'dm' ? 'YDY_RESTAURANTS' : 'ydy_restaurants';
$dishes = $dialect === 'dm' ? 'YDY_DISHES' : 'ydy_dishes';
$questionnaire = $dialect === 'dm' ? 'YDY_DISH_QUESTIONNAIRE' : 'ydy_dish_questionnaire';
$tags = $dialect === 'dm' ? 'YDY_DISH_QUESTIONNAIRE_TAG' : 'ydy_dish_questionnaire_tag';
$restaurantId = $pdo->query("SELECT ID FROM $restaurants WHERE STATUS=1 AND IS_DELETE=2 ORDER BY ID LIMIT 1")->fetchColumn();
$dishUuid = $pdo->query("SELECT UUID FROM $dishes WHERE STORE_ID=10001 AND STATUS=1 AND IS_DEL=1 AND IS_DELETE=0 ORDER BY ID LIMIT 1")->fetchColumn();
if (!$restaurantId || !$dishUuid) throw new RuntimeException('Approved demo fixture missing');
$dishUuids = $pdo->query("SELECT UUID FROM $dishes WHERE STORE_ID=10001 AND STATUS=1 AND IS_DEL=1 AND IS_DELETE=0 ORDER BY ID LIMIT 2")->fetchAll(PDO::FETCH_COLUMN);
if (count($dishUuids) < 2) throw new RuntimeException('Two active dishes required for batch HTTP fixture');

function postForm(string $url, array $payload): array
{
    $body = http_build_query($payload, '', '&', PHP_QUERY_RFC3986);
    $context = stream_context_create(['http' => [
        'method' => 'POST',
        'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => $body,
        'timeout' => 12,
        'ignore_errors' => true,
    ]]);
    $response = file_get_contents($url, false, $context);
    $decoded = is_string($response) ? json_decode($response, true) : null;
    if (!is_array($decoded)) throw new RuntimeException('HTTP endpoint returned non-JSON');
    return $decoded;
}

$marker = 'CODEXHTTP_' . date('YmdHis') . '_' . strtoupper(bin2hex(random_bytes(3)));
$endpoint = rtrim($url, '/') . '/api/dishQuestionnaire/submit';
$payload = [
    'type' => (string)$restaurantId,
    'restaurant_id' => (string)$restaurantId,
    'dishes_uuid' => (string)$dishUuid,
    'submit_id' => $marker,
    'score' => '4',
    'tag_codes' => '3,5',
    'comment' => 'CODEX HTTP database compatibility test',
];
$first = postForm($endpoint, $payload);
$repeat = postForm($endpoint, $payload);
if (($first['code'] ?? null) !== 0 || ($repeat['code'] ?? null) !== 0
    || !empty($first['data']['duplicated']) || empty($repeat['data']['duplicated'])
    || (int)($first['data']['id'] ?? 0) <= 0
    || (int)($first['data']['id'] ?? 0) !== (int)($repeat['data']['id'] ?? 0)) {
    throw new RuntimeException('HTTP submission or idempotency failed');
}
$stmt = $pdo->prepare("SELECT ID,SCORE FROM $questionnaire WHERE SUBMIT_ID=?");
$stmt->execute([$marker]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($rows) !== 1 || (int)$rows[0]['SCORE'] !== 4) throw new RuntimeException('HTTP submission did not persist exactly once');
$id = (int)$rows[0]['ID'];
$stmt = $pdo->prepare("SELECT COUNT(*) FROM $tags WHERE QUESTIONNAIRE_ID=?");
$stmt->execute([$id]);
if ((int)$stmt->fetchColumn() !== 2) throw new RuntimeException('HTTP submission tags did not persist');

$invalidMarker = 'CODEXHTTP_INVALID_' . strtoupper(bin2hex(random_bytes(4)));
$invalid = postForm($endpoint, array_merge($payload, ['submit_id' => $invalidMarker, 'score' => '0']));
$stmt = $pdo->prepare("SELECT COUNT(*) FROM $questionnaire WHERE SUBMIT_ID=?");
$stmt->execute([$invalidMarker]);
if (($invalid['code'] ?? null) !== 1 || (int)$stmt->fetchColumn() !== 0) {
    throw new RuntimeException('Invalid HTTP submission changed business data');
}

$batchMarkers = [
    'CODEXHTTP_BATCH_' . strtoupper(bin2hex(random_bytes(4))),
    'CODEXHTTP_BATCH_' . strtoupper(bin2hex(random_bytes(4))),
];
$items = [];
foreach ($dishUuids as $index => $uuid) {
    $items[] = [
        'submit_id' => $batchMarkers[$index],
        'restaurant_id' => (int)$restaurantId,
        'dishes_uuid' => (string)$uuid,
        'score' => $index === 0 ? 4 : 5,
        'tag_codes' => [$index === 0 ? 3 : 5],
        'comment' => 'CODEX HTTP batch test',
    ];
}
$batchEndpoint = rtrim($url, '/') . '/api/dishQuestionnaire/batchSubmit';
$batchPayload = ['type' => (string)$restaurantId, 'items' => json_encode($items, JSON_UNESCAPED_UNICODE)];
$batch = postForm($batchEndpoint, $batchPayload);
$batchRepeat = postForm($batchEndpoint, $batchPayload);
if (($batch['code'] ?? null) !== 0 || ($batchRepeat['code'] ?? null) !== 0
    || (int)($batch['data']['submitted_count'] ?? 0) !== 2
    || (int)($batchRepeat['data']['submitted_count'] ?? 0) !== 2) {
    throw new RuntimeException('Batch HTTP submission failed');
}
$batchIds = [];
foreach ($batchMarkers as $index => $batchMarker) {
    $firstId = (int)($batch['data']['results'][$index]['id'] ?? 0);
    $repeatId = (int)($batchRepeat['data']['results'][$index]['id'] ?? 0);
    if ($firstId <= 0 || $firstId !== $repeatId || !empty($batch['data']['results'][$index]['duplicated'])
        || empty($batchRepeat['data']['results'][$index]['duplicated'])) {
        throw new RuntimeException('Batch HTTP idempotency failed');
    }
    $stmt = $pdo->prepare("SELECT ID FROM $questionnaire WHERE SUBMIT_ID=?");
    $stmt->execute([$batchMarker]);
    $batchRows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    if (count($batchRows) !== 1 || (int)$batchRows[0]['ID'] !== $firstId) {
        throw new RuntimeException('Batch HTTP write did not persist exactly once');
    }
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM $tags WHERE QUESTIONNAIRE_ID=?");
    $stmt->execute([$firstId]);
    if ((int)$stmt->fetchColumn() !== 1) throw new RuntimeException('Batch HTTP tag write missing');
    $batchIds[] = $firstId;
}
$invalidBatch = $items;
$invalidBatch[0]['submit_id'] = 'CODEXHTTP_INVALID_' . strtoupper(bin2hex(random_bytes(4)));
$invalidBatch[1]['submit_id'] = 'CODEXHTTP_INVALID_' . strtoupper(bin2hex(random_bytes(4)));
$invalidBatch[1]['dishes_uuid'] = $invalidBatch[0]['dishes_uuid'];
$invalidResponse = postForm($batchEndpoint, ['type' => (string)$restaurantId,
    'items' => json_encode($invalidBatch, JSON_UNESCAPED_UNICODE)]);
if (($invalidResponse['code'] ?? null) !== 1) throw new RuntimeException('Duplicate-dish batch was accepted');
foreach ($invalidBatch as $invalidItem) {
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM $questionnaire WHERE SUBMIT_ID=?");
    $stmt->execute([$invalidItem['submit_id']]);
    if ((int)$stmt->fetchColumn() !== 0) throw new RuntimeException('Rejected batch left a row');
}
echo json_encode(['dialect' => $dialect, 'status' => 'passed', 'marker' => $marker,
    'row_id' => $id, 'http_success' => true, 'idempotent' => true,
    'database_row_count' => 1, 'tag_count' => 2, 'invalid_no_write' => true,
    'batch_markers' => $batchMarkers, 'batch_row_ids' => $batchIds,
    'batch_idempotent' => true, 'invalid_batch_no_write' => true]) . PHP_EOL;
