<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
ob_start(); // Prevent headers already sent issues

require '../config.php'; // DB config
require '../vendor-authorize/autoload.php';

use net\authorize\api\contract\v1 as AnetAPI;
use net\authorize\api\controller as AnetController;

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    die("Invalid request");
}

// Fetch POST data
$invoiceId     = $_POST['invoice_id'] ?? '';
$uuid          = $_POST['uuid'] ?? '';
$clientHash    = $_POST['hash'] ?? '';
$desc          = $_POST['desc'] ?? '';
$amount        = number_format((float)($_POST['amount'] ?? 0), 2, '.', '');
$dataDescriptor= $_POST['dataDescriptor'] ?? '';
$dataValue     = $_POST['dataValue'] ?? '';

if (!$invoiceId || !$uuid || !$clientHash || !$dataDescriptor || !$dataValue) {
    die("Missing required parameters");
}

// Database connection
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) die("DB connection failed: " . $conn->connect_error);

// Fetch invoice by ID and UUID
$stmt = $conn->prepare("SELECT * FROM invoices WHERE id=? AND uuid=?");
$stmt->bind_param("is", $invoiceId, $uuid);
$stmt->execute();
$result = $stmt->get_result();
$invoice = $result->fetch_assoc();
$stmt->close();

// Validate invoice and hash
if (!$invoice) {
    die("Invalid invoice access");
}
$invoiceHash = generateInvoiceHash($invoice['id'], $invoice['salt'] ?? '');
if (!hash_equals($invoiceHash, $clientHash)) {
    die("Invalid invoice access");
}

// Fetch Authorize.Net keys dynamically from payment_methods table
$pmId = $invoice['payment_method_id'] ?? 5; // default authorize id
$pmStmt = $conn->prepare("SELECT * FROM payment_methods WHERE id=? AND status=1");
$pmStmt->bind_param("i", $pmId);
$pmStmt->execute();
$pmResult = $pmStmt->get_result();
$gatewayData = $pmResult->fetch_assoc();
$pmStmt->close();

if (!$gatewayData) {
    die("Payment method configuration missing");
}

// Define Authorize.Net constants dynamically
define('AUTHORIZE_API_LOGIN_ID', $gatewayData['authorize_api_login'] ?? '');
define('AUTHORIZE_TRANSACTION_KEY', $gatewayData['authorize_transaction_key'] ?? '');
define('AUTHORIZE_PUBLIC_KEY', $gatewayData['authorize_public_key'] ?? '');
define('AUTHORIZE_SIGNATURE_KEY', $gatewayData['authorize_signature_key'] ?? '');

// Sandbox or live
$isSandbox = false; // change false for live

// Merchant authentication
$merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
$merchantAuthentication->setName(AUTHORIZE_API_LOGIN_ID);
$merchantAuthentication->setTransactionKey(AUTHORIZE_TRANSACTION_KEY);

$refId = 'ref' . time();

// Payment data
$opaqueData = new AnetAPI\OpaqueDataType();
$opaqueData->setDataDescriptor($dataDescriptor);
$opaqueData->setDataValue($dataValue);

$paymentType = new AnetAPI\PaymentType();
$paymentType->setOpaqueData($opaqueData);

// Transaction request
$transactionRequest = new AnetAPI\TransactionRequestType();
$transactionRequest->setTransactionType("authCaptureTransaction");
$transactionRequest->setAmount($amount);
$transactionRequest->setPayment($paymentType);

$request = new AnetAPI\CreateTransactionRequest();
$request->setMerchantAuthentication($merchantAuthentication);
$request->setRefId($refId);
$request->setTransactionRequest($transactionRequest);

$controller = new AnetController\CreateTransactionController($request);
$response = $controller->executeWithApiResponse(
    $isSandbox ? \net\authorize\api\constants\ANetEnvironment::SANDBOX : \net\authorize\api\constants\ANetEnvironment::PRODUCTION
);

// Prepare redirect URL back to invoice
$redirectHash = generateInvoiceHash($invoice['id'], $invoice['salt']); // Always recalc from DB
$baseUrl = "/invoice/secure/{$invoice['uuid']}/{$redirectHash}";

if ($response !== null && $response->getMessages()->getResultCode() === "Ok") {
    $tResponse = $response->getTransactionResponse();
    if ($tResponse && in_array($tResponse->getResponseCode(), ["1", 1])) {
        // Payment success, update invoice if not already paid
        if ($invoice['status'] !== 'paid') {
            $stmt = $conn->prepare("UPDATE invoices SET status='paid', paid_at=NOW(), authorize_transaction_id=? WHERE id=?");
            $stmt->bind_param("si", $tResponse->getTransId(), $invoiceId);
            $stmt->execute();
            $stmt->close();
        }

        // Redirect with txn ID
        header("Location: $baseUrl?status=success&txn=" . urlencode($tResponse->getTransId()));
        exit;
    } else {
        $errorText = $tResponse && $tResponse->getErrors() ? $tResponse->getErrors()[0]->getErrorText() : 'Transaction failed';
        header("Location: $baseUrl?status=failed&msg=" . urlencode($errorText));
        exit;
    }
} else {
    $errorText = $response && $response->getMessages()->getMessage() ? $response->getMessages()->getMessage()[0]->getText() : 'API error';
    header("Location: $baseUrl?status=failed&msg=" . urlencode($errorText));
    exit;
}

$conn->close();
ob_end_flush();
?>
