<?php
require_once __DIR__ . '/../core/config.php';
require_once __DIR__ . '/../core/database.php';
require_once __DIR__ . '/../services/billing/BillingRuntimeGate.php';

date_default_timezone_set('UTC');
$checks = array();
$failures = array();

function v617a_check(&$checks, &$failures, $label, $ok, $detail = '') {
    $checks[] = array($label, (bool)$ok, $detail);
    if (!$ok) $failures[] = $label . ($detail !== '' ? ': ' . $detail : '');
}

$pdo = db();
$dbName = (string)$pdo->query('SELECT DATABASE()')->fetchColumn();
v617a_check($checks, $failures, 'database target', $dbName === 'icylab_app', $dbName);

$readAllowed = $financeAllowed = $issueBlocked = false;
try { billing_assert_runtime_operation('read', 'production', 'v6.17 post activation'); $readAllowed = true; } catch (Throwable $e) {}
try { billing_assert_runtime_operation('finance', 'production', 'v6.17 post activation'); $financeAllowed = true; } catch (Throwable $e) {}
try { billing_assert_runtime_operation('issue', 'production', 'v6.17 post activation'); } catch (Throwable $e) { $issueBlocked = true; }
v617a_check($checks, $failures, 'production read allowed', $readAllowed);
v617a_check($checks, $failures, 'production finance allowed', $financeAllowed);
v617a_check($checks, $failures, 'production issue blocked', $issueBlocked);

$inventory = $pdo->query("SELECT
 (SELECT COUNT(*) FROM facto_documents WHERE BINARY environment=BINARY 'production') documents,
 (SELECT COUNT(*) FROM facto_inbox_documents WHERE BINARY environment=BINARY 'production') inbox_documents,
 (SELECT COUNT(*) FROM billing_collections WHERE BINARY environment=BINARY 'production' AND BINARY direction=BINARY 'receivable') receivables,
 (SELECT COUNT(*) FROM billing_collections WHERE BINARY environment=BINARY 'production' AND BINARY direction=BINARY 'payable') payables,
 (SELECT COUNT(*) FROM billing_payments WHERE BINARY environment=BINARY 'production') payments")->fetch(PDO::FETCH_ASSOC);
v617a_check($checks, $failures, 'controlled inventory after gate activation',
    (int)$inventory['documents'] === 264
    && (int)$inventory['inbox_documents'] === 520
    && (int)$inventory['receivables'] === 246
    && (int)$inventory['payables'] === 1
    && (int)$inventory['payments'] === 112,
    json_encode($inventory));

$duplicateKeys = (int)$pdo->query("SELECT COUNT(*) FROM (
 SELECT environment,direction,idempotency_key,COUNT(*) c
 FROM billing_payment_batches
 WHERE BINARY environment=BINARY 'production' AND idempotency_key IS NOT NULL AND TRIM(idempotency_key)<>''
 GROUP BY environment,direction,idempotency_key HAVING COUNT(*)>1
) x")->fetchColumn();
v617a_check($checks, $failures, 'no duplicate production idempotency keys', $duplicateKeys === 0, 'groups=' . $duplicateKeys);

$duplicateRefs = (int)$pdo->query("SELECT COUNT(*) FROM (
 SELECT environment,direction,cash_account_id,external_reference,COUNT(*) c
 FROM billing_payment_batches
 WHERE BINARY environment=BINARY 'production' AND TRIM(COALESCE(external_reference,''))<>''
 GROUP BY environment,direction,cash_account_id,external_reference HAVING COUNT(*)>1
) x")->fetchColumn();
v617a_check($checks, $failures, 'no duplicate production references', $duplicateRefs === 0, 'groups=' . $duplicateRefs);

$orphanAllocations = (int)$pdo->query("SELECT COUNT(*) FROM billing_payment_allocations a LEFT JOIN billing_payments p ON p.id=a.payment_id LEFT JOIN billing_payment_batches b ON b.id=a.payment_batch_id LEFT JOIN billing_collections c ON c.id=a.collection_id WHERE p.id IS NULL OR b.id IS NULL OR c.id IS NULL")->fetchColumn();
v617a_check($checks, $failures, 'no orphan payment allocations', $orphanAllocations === 0, 'rows=' . $orphanAllocations);

$invalidBalances = (int)$pdo->query("SELECT COUNT(*) FROM billing_collections WHERE BINARY environment=BINARY 'production' AND (paid_amount < -0.01 OR balance_amount < -0.01 OR ABS(total_amount-paid_amount-balance_amount)>0.02)")->fetchColumn();
v617a_check($checks, $failures, 'production collection balances consistent', $invalidBalances === 0, 'rows=' . $invalidBalances);

$permissions = $pdo->query("SELECT
 (SELECT COUNT(*) FROM permissions WHERE BINARY permission_key=BINARY 'billing.receivables.bulk_collect') receivable_permission,
 (SELECT COUNT(*) FROM permissions WHERE BINARY permission_key=BINARY 'billing.payables.bulk_pay') payable_permission")->fetch(PDO::FETCH_ASSOC);
v617a_check($checks, $failures, 'explicit bulk permissions exist', (int)$permissions['receivable_permission'] === 1 && (int)$permissions['payable_permission'] === 1, json_encode($permissions));

echo "ICYLAB BILLING CONTROLLED BULK PAYMENTS POST-ACTIVATION DIAGNOSTIC v6.17\n";
echo 'Generated at UTC: ' . gmdate('Y-m-d H:i:s') . "\n";
echo 'PHP: ' . PHP_VERSION . "\n";
echo 'DB name: ' . $dbName . "\n\n";
foreach ($checks as $check) {
    echo $check[0] . ': ' . ($check[1] ? 'PASS' : 'FAIL') . ($check[2] !== '' ? ' [' . $check[2] . ']' : '') . "\n";
}
echo "\nRESULT: " . (count($failures) === 0 ? 'PASS' : 'FAIL') . "\n";
if ($failures) foreach ($failures as $failure) echo '- ' . $failure . "\n";
exit($failures ? 1 : 0);
