<?php
declare(strict_types=1);
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/functions.php';
require_once __DIR__ . '/referrals.php';

// Schema setup - only run when needed
function ensure_payments_tables(PDO $pdo): void {
    $pdo->exec("CREATE TABLE IF NOT EXISTS payment_intents (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      user_id INTEGER NOT NULL,
      application_id INTEGER NOT NULL,
      method TEXT NOT NULL,
      amount REAL NOT NULL,
      status TEXT NOT NULL DEFAULT 'created',
      token_last4 TEXT,
      provider_ref TEXT,
      attempts INTEGER NOT NULL DEFAULT 0,
      created_at TEXT NOT NULL,
      updated_at TEXT NOT NULL,
      expires_at TEXT
    )");
    
    try { $pdo->exec("ALTER TABLE payments ADD COLUMN method TEXT"); } catch (\Throwable $e) {}
    try { $pdo->exec("ALTER TABLE payments ADD COLUMN provider_ref TEXT"); } catch (\Throwable $e) {}
    try { $pdo->exec("ALTER TABLE payments ADD COLUMN admin_note TEXT"); } catch (\Throwable $e) {}
    try { $pdo->exec("ALTER TABLE payment_intents ADD COLUMN expires_at TEXT"); } catch (\Throwable $e) {}
    try { $pdo->exec("ALTER TABLE payment_intents ADD COLUMN receipt_path TEXT"); } catch (\Throwable $e) {}
}

function velocity_limit_ok(PDO $pdo, int $userId, int $appId): bool {
  ensure_payments_tables($pdo);
  $q = $pdo->prepare("SELECT COUNT(*) c FROM payment_intents WHERE user_id=? AND application_id=? AND created_at>=?");
  $q->execute([$userId,$appId,date('c', time()-3600)]);
  $c = (int)$q->fetch()['c'];
  return $c < 10; // Increased limit for manual attempts
}

function create_payment_intent(PDO $pdo, int $userId, int $appId, float $amount): array {
  ensure_payments_tables($pdo);
  // Always use 'bank_transfer'
  if ($amount <= 0) return ['error'=>'invalid_amount'];
  
  // Check if there is already a pending intent
  $q = $pdo->prepare("SELECT * FROM payment_intents WHERE user_id=? AND application_id=? AND status='created' AND expires_at > ?");
  $q->execute([$userId, $appId, date('c')]);
  $existing = $q->fetch();
  if ($existing) {
    return [
      'id' => (int)$existing['id'],
      'expires_at' => $existing['expires_at'],
      'reused' => true
    ];
  }

  if (!velocity_limit_ok($pdo,$userId,$appId)) return ['error'=>'too_many_attempts'];
  
  $now = time();
  $createdAt = date('c', $now);
  $expiresAt = date('c', $now + 1800); // 30 minutes expiration
  
  $stmt = $pdo->prepare("INSERT INTO payment_intents (user_id,application_id,method,amount,status,created_at,updated_at,expires_at) VALUES (?,?,'bank_transfer',?, 'created', ?, ?, ?)");
  $stmt->execute([$userId,$appId,$amount,$createdAt,$createdAt,$expiresAt]);
  return [
    'id' => (int)$pdo->lastInsertId(),
    'expires_at' => $expiresAt
  ];
}

function confirm_payment_intent(PDO $pdo, int $intentId, int $userId, string $reference, ?string $receiptPath = null): array {
  ensure_payments_tables($pdo);
  $q = $pdo->prepare("SELECT * FROM payment_intents WHERE id=? AND user_id=?"); $q->execute([$intentId,$userId]); $pi = $q->fetch();
  if (!$pi) return ['error'=>'not_found'];
  if ($pi['status'] !== 'created') return ['error'=>'invalid_state'];
  
  // Check expiration
  if (strtotime($pi['expires_at']) < time()) {
    $pdo->prepare("UPDATE payment_intents SET status='failed', updated_at=? WHERE id=?")->execute([date('c'), $intentId]);
    return ['error'=>'expired'];
  }

  $attempts = (int)$pi['attempts'] + 1;
  $status = 'processing'; // User says they paid, system is processing/verifying
  
  $pdo->prepare("UPDATE payment_intents SET provider_ref=?, receipt_path=?, status=?, attempts=?, updated_at=? WHERE id=?")
      ->execute([$reference, $receiptPath, $status, $attempts, date('c'), $intentId]);
      
  // Create a pending payment record
  $pdo->prepare("INSERT INTO payments (application_id, amount, payment_reference, receipt_path, status, created_at, method, provider_ref) VALUES (?,?,?,?,?,?,?,?)")
      ->execute([(int)$pi['application_id'], (float)$pi['amount'], $reference, $receiptPath, 'pending', date('c'), 'bank_transfer', $reference]);
  
  // Update application status to submitted if it was draft
  $pdo->prepare("UPDATE applications SET status='submitted' WHERE id=? AND status='draft'")
      ->execute([(int)$pi['application_id']]);

  return ['status'=>$status];
}


function list_user_payments(PDO $pdo, int $userId, ?string $status=null, ?string $method=null): array {
  $sql = "SELECT p.*, a.user_id FROM payments p JOIN applications a ON a.id=p.application_id WHERE a.user_id=?";
  $params = [$userId];
  if ($status) { $sql .= " AND p.status=?"; $params[] = $status; }
  if ($method) { $sql .= " AND p.method=?"; $params[] = $method; }
  $sql .= " ORDER BY p.created_at DESC";
  $st = $pdo->prepare($sql); $st->execute($params); return $st->fetchAll();
}

function export_payments_csv(array $rows): string {
  $f = fopen('php://temp','w+');
  fputcsv($f, ['Date','Application','Amount','Status','Method','Provider Ref']);
  foreach ($rows as $r) {
    fputcsv($f, [$r['created_at'],$r['application_id'],$r['amount'],$r['status'],$r['method'] ?? '',$r['provider_ref'] ?? '']);
  }
  rewind($f); $csv = stream_get_contents($f); fclose($f); return $csv;
}
