<?php

require_once dirname(__DIR__) . '/db_bootstrap.php';
require_once dirname(__DIR__) . '/finance_payment_lib.php';

$conn = ensure_db(true);
ua_agent_schema_migrate($conn);
finance_ensure_payments_table($conn);

$key = 'IT-' . bin2hex(random_bytes(6));
$invoiceResult = $conn->query("SELECT i.id,i.subscriber_id FROM invoices i INNER JOIN subscribers s ON s.id=i.subscriber_id ORDER BY i.id ASC LIMIT 1");
$invoice = $invoiceResult && $invoiceResult->num_rows ? $invoiceResult->fetch_assoc() : null;
if (!$invoice) {
  fwrite(STDERR, "No invoice is available for the integration test.\n");
  exit(1);
}
$invoiceId = (int)$invoice['id'];
$subscriberId = (int)($invoice['subscriber_id'] ?? 0);
$conn->begin_transaction();

try {
  $saved = ua_agent_repo_save($conn, [
    'code' => $key,
    'full_name' => 'Integration Test Agent',
    'username' => strtolower($key),
    'is_active' => 1,
    'portal_enabled' => 1,
    'pos_enabled' => 1,
  ]);
  if (!$saved['ok']) throw new RuntimeException($saved['error']);
  $agentId = (int)$saved['id'];

  $payment = finance_record_payment_row(
    $conn,
    $invoiceId,
    $subscriberId,
    125.50,
    'test',
    'agent finance integration test',
    'codex-test',
    date('Y-m-d H:i:s'),
    $key,
    $agentId,
    ['idempotency_key' => 'PAY:' . $key]
  );
  if (!$payment['ok'] || empty($payment['id'])) {
    throw new RuntimeException($payment['error'] ?: 'Payment ID is missing.');
  }

  $entry = ua_agent_ledger_post($conn, [
    'agent_id' => $agentId,
    'direction' => 'DEBIT',
    'entry_type' => 'INVOICE_PAYMENT',
    'amount' => 125.50,
    'invoice_id' => $invoiceId,
    'subscriber_id' => $subscriberId,
    'payment_id' => (int)$payment['id'],
    'idempotency_key' => 'LEDGER:' . $key,
  ], false);
  if (!$entry['ok']) throw new RuntimeException($entry['error']);

  $duplicate = ua_agent_ledger_post($conn, [
    'agent_id' => $agentId,
    'direction' => 'DEBIT',
    'entry_type' => 'INVOICE_PAYMENT',
    'amount' => 125.50,
    'payment_id' => (int)$payment['id'],
    'idempotency_key' => 'LEDGER:' . $key,
  ], false);
  if (empty($duplicate['duplicate'])) {
    throw new RuntimeException('Ledger idempotency check failed.');
  }

  $reverse = ua_agent_ledger_reverse(
    $conn,
    (int)$entry['entry']['id'],
    'Integration test reversal',
    ['type' => 'admin'],
    false
  );
  if (!$reverse['ok']) throw new RuntimeException($reverse['error']);

  $balance = ua_agent_ledger_balance($conn, $agentId);
  if (abs($balance) > 0.001) {
    throw new RuntimeException('Unexpected balance after reversal: ' . $balance);
  }

  $conn->rollback();
  $escapedKey = $conn->real_escape_string($key);
  $left = $conn->query("SELECT COUNT(*) c FROM agents WHERE code='{$escapedKey}'")->fetch_assoc();
  if ((int)($left['c'] ?? 0) !== 0) {
    throw new RuntimeException('Rollback left test data behind.');
  }

  echo json_encode([
    'ok' => true,
    'duplicate_blocked' => true,
    'balance_after_reverse' => $balance,
    'rows_after_rollback' => 0,
  ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . PHP_EOL;
} catch (Throwable $e) {
  @$conn->rollback();
  fwrite(STDERR, $e->getMessage() . PHP_EOL);
  exit(1);
}
