<?php
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST");

require('dbcon.php'); // Database connection
require __DIR__ . '/vendor/autoload.php'; // Firebase Admin SDK

use Kreait\Firebase\Factory;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;

// === LOAD FIREBASE SERVICE ACCOUNT ===
$factory = (new Factory)->withServiceAccount(__DIR__.'/amstapay-firebase.json');
$messaging = $factory->createMessaging();

// Decode incoming JSON
$rawInput = file_get_contents("php://input");
$data = json_decode($rawInput, true);
file_put_contents("log.txt", $rawInput . PHP_EOL, FILE_APPEND);

// === Validate required fields ===
$required = ['emailOrPhone', 'fromAccount', 'toAccount', 'recipientName', 'recipientBank', 'amount', 'note', 'transactionPin'];
foreach ($required as $field) {
    if (empty($data[$field])) {
        echo json_encode(["status" => "error", "message" => "Missing field: $field"]);
        exit;
    }
}

// === Extract data ===
$emailOrPhone   = trim($data['emailOrPhone']);
$fromAccount    = trim($data['fromAccount']);
$toAccount      = trim($data['toAccount']);
$recipientName  = trim($data['recipientName']);
$recipientBank  = trim($data['recipientBank']);
$amount         = floatval($data['amount']);
$note           = trim($data['note']);
$transactionPin = trim($data['transactionPin']);
$saveBeneficiary = isset($data['saveBeneficiary']) ? intval($data['saveBeneficiary']) : 0;

// === STEP 1: Verify sender ===
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? OR phone = ?");
$stmt->execute([$emailOrPhone, $emailOrPhone]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$user) {
    echo json_encode(["status" => "error", "message" => "Invalid user or account number."]);
    exit;
}

// === STEP 2: Verify PIN ===
if (md5($transactionPin) !== $user['transaction_pin']) {
    echo json_encode(["status" => "error", "message" => "Incorrect transaction PIN."]);
    exit;
}

// === STEP 3: Check balance ===
$currentBalance = floatval($user['balance']);
if ($currentBalance < $amount) {
    $stmt = $pdo->prepare("INSERT INTO notifications 
        (emailOrPhone, fromAccount, toAccount, recipientName, recipientBank, amount, note, status, created_at)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())");
    $stmt->execute([$emailOrPhone, $fromAccount, $toAccount, $recipientName, $recipientBank, $amount, $note, "insufficient_funds"]);

    echo json_encode(["status" => "error", "message" => "Insufficient funds."]);
    exit;
}

// === STEP 4: Deduct from sender ===
$newBalance = $currentBalance - $amount;
$update = $pdo->prepare("UPDATE users SET balance = ? WHERE id = ?");
$update->execute([$newBalance, $user['id']]);

// === STEP 5: Credit receiver ===
$stmtrv = $pdo->prepare("SELECT * FROM users WHERE account_no = ?");
$stmtrv->execute([$toAccount]);
$userrv = $stmtrv->fetch(PDO::FETCH_ASSOC);

if (!$userrv) {
    echo json_encode(["status" => "error", "message" => "Invalid recipient account number."]);
    exit;
}

$currentBalancerv = floatval($userrv['balance']);
$newBalancereceiver = $currentBalancerv + $amount;
$update = $pdo->prepare("UPDATE users SET balance = ? WHERE id = ?");
$update->execute([$newBalancereceiver, $userrv['id']]);

// === STEP 6: Create transaction reference ===
$transactionRef = "TXN" . strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 10));

// === STEP 7: Record transaction ===
$stmt = $pdo->prepare("INSERT INTO transactions 
    (transaction_ref, emailOrPhone, fromAccount, toAccount, recipientName, recipientBank, amount, note, type, status, balance_before, balance_after, created_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())");
$stmt->execute([
    $transactionRef,
    $emailOrPhone,
    $fromAccount,
    $toAccount,
    $recipientName,
    $recipientBank,
    $amount,
    $note,
    "debit",
    "success",
    $currentBalance,
    $newBalance
]);

// === STEP 8: Record notifications locally ===
$stmt = $pdo->prepare("INSERT INTO notifications 
    (emailOrPhone, transaction_ref, fromAccount, toAccount, recipientName, recipientBank, amount, note, status, created_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())");
$stmt->execute([
    $emailOrPhone,
    $transactionRef,
    $fromAccount,
    $toAccount,
    $recipientName,
    $recipientBank,
    $amount,
    $note,
    "success"
]);

// === STEP 9: Notify Node.js Socket server ===
$socketServerUrl = 'https://amsta-real-time.onrender.com/notify';

// Notify receiver (credit)
$creditData = [
    'receiver_id' => $userrv['id'],
    'sender' => $user['name'],
    'amount' => $amount
];
$ch1 = curl_init($socketServerUrl);
curl_setopt($ch1, CURLOPT_POST, 1);
curl_setopt($ch1, CURLOPT_POSTFIELDS, json_encode($creditData));
curl_setopt($ch1, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
$creditResponse = curl_exec($ch1);
curl_close($ch1);

// Notify sender (debit)
$debitData = [
    'receiver_id' => $user['id'],
    'sender' => $recipientName,
    'amount' => -$amount
];
$ch2 = curl_init($socketServerUrl);
curl_setopt($ch2, CURLOPT_POST, 1);
curl_setopt($ch2, CURLOPT_POSTFIELDS, json_encode($debitData));
curl_setopt($ch2, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
$debitResponse = curl_exec($ch2);
curl_close($ch2);

// === STEP 10: Send Firebase Push Notifications ===
function sendFirebaseNotification($messaging, $tokens, $title, $body) {
    foreach ($tokens as $token) {
        $notification = Notification::create($title, $body);
        $message = CloudMessage::withTarget('token', $token)
            ->withNotification($notification);

        try {
            $messaging->send($message);
        } catch (Exception $e) {
            file_put_contents("fcm_errors.txt", $e->getMessage() . PHP_EOL, FILE_APPEND);
        }
    }
}

// === Get receiver’s FCM tokens ===
$stmt = $pdo->prepare("SELECT fcm_token FROM user_devices WHERE user_id = ? AND removed = 0");
$stmt->execute([$userrv['id']]);
$receiverTokens = $stmt->fetchAll(PDO::FETCH_COLUMN);

if (!empty($receiverTokens)) {
    sendFirebaseNotification($messaging, $receiverTokens, "Credit Alert", "₦" . number_format($amount, 2) . " received from " . $user['name']);
}

// === Get sender’s FCM tokens ===
$stmt = $pdo->prepare("SELECT fcm_token FROM user_devices WHERE user_id = ? AND removed = 0");
$stmt->execute([$user['id']]);
$senderTokens = $stmt->fetchAll(PDO::FETCH_COLUMN);

if (!empty($senderTokens)) {
    sendFirebaseNotification($messaging, $senderTokens, "Debit Alert", "₦" . number_format($amount, 2) . " sent to " . $recipientName);
}

// === STEP 11: Return response to app ===
echo json_encode([
    "status" => "success",
    "message" => "Payment of ₦" . number_format($amount, 2) . " to " . $recipientName . " successful.",
    "transaction_ref" => $transactionRef,
    "new_balance" => number_format($newBalance, 2),
    "credit_response" => $creditResponse,
    "debit_response" => $debitResponse
]);
?>
