<?php
ini_set('error_log', 'error_log');
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../botapi.php';
require_once __DIR__ . '/../panels.php';
require_once __DIR__ . '/../function.php';
require_once __DIR__ . '/../keyboard.php';
require_once __DIR__ . '/../jdf.php';
require __DIR__ . '/../vendor/autoload.php';

$ManagePanel = new ManagePanel();
$setting = select("setting", "*");
$paymentreports = select("topicid", "idreport", "report", "paymentreport", "select")['idreport'];
$errorreport = select("topicid", "idreport", "report", "errorreport", "select")['idreport'];
$textbotlang = languagechange();

header('Content-Type: application/json');

$rawBody = file_get_contents("php://input");
$data = json_decode($rawBody, true);

// TonPays sends: invoice_id, order_id, request_amount, final_amount, status, paid
if (!is_array($data) || empty($data['invoice_id']) || empty($data['order_id'])) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'invalid_payload']);
    return;
}

$invoice_id = htmlspecialchars((string) $data['invoice_id'], ENT_QUOTES, 'UTF-8');
$order_id = htmlspecialchars((string) $data['order_id'], ENT_QUOTES, 'UTF-8');

$Payment_report = select("Payment_report", "*", "id_order", $order_id, "select");

// Unknown order_id -> never confirm.
if (!$Payment_report || $Payment_report['Payment_Method'] != "tonpays") {
    http_response_code(200);
    echo json_encode(['ok' => true, 'ignored' => 'unknown_order']);
    return;
}

// Invoice must match the one we stored when the invoice was created.
if ($Payment_report['dec_not_confirmed'] != $invoice_id) {
    http_response_code(200);
    echo json_encode(['ok' => true, 'ignored' => 'invoice_mismatch']);
    return;
}

// Idempotency: already paid, do nothing (prevents duplicate delivery on repeated callbacks).
if ($Payment_report['payment_Status'] == "paid") {
    http_response_code(200);
    echo json_encode(['ok' => true, 'already_paid' => true]);
    return;
}

// Never trust the raw webhook body alone: re-verify the invoice status directly
// with TonPays using our server-side API key before granting anything.
$verified = checkPayTonPays($invoice_id);

if (!empty($verified['error'])) {
    $ErrorsLinkPayment = sprintf($textbotlang['hardcoded']['tonpaysWebhookError'], json_encode($verified), $Payment_report['id_user'], $order_id);
    if (strlen($setting['Channel_Report']) > 0) {
        telegram('sendmessage', [
            'chat_id' => $setting['Channel_Report'],
            'message_thread_id' => $errorreport,
            'text' => $ErrorsLinkPayment,
            'parse_mode' => "HTML"
        ]);
    }
    http_response_code(200);
    echo json_encode(['ok' => false, 'error' => 'verify_failed']);
    return;
}

$verifiedInvoiceId = isset($verified['invoice_id']) ? (string) $verified['invoice_id'] : null;
$verifiedOrderId = array_key_exists('order_id', $verified) && $verified['order_id'] !== null ? (string) $verified['order_id'] : null;
$verifiedPaid = !empty($verified['paid']);
$verifiedAmount = isset($verified['request_amount']) ? intval($verified['request_amount']) : null;

// invoice_id is the authoritative link (we already resolved order_id -> Payment_report
// ourselves and confirmed dec_not_confirmed == invoice_id above, so the two are already
// bound securely). TonPays' check endpoint documents order_id as nullable, so only
// enforce the order_id match when they actually return one — a null here must never
// block crediting a genuinely paid invoice.
if ($verifiedInvoiceId !== $invoice_id || ($verifiedOrderId !== null && $verifiedOrderId !== $order_id)) {
    http_response_code(200);
    echo json_encode(['ok' => true, 'ignored' => 'verify_mismatch']);
    return;
}

if (!$verifiedPaid) {
    // status is rejected/expired/pending -> nothing to deliver.
    http_response_code(200);
    echo json_encode(['ok' => true, 'paid' => false]);
    return;
}

// Amount must match exactly what we asked the user to pay for this order.
if ($verifiedAmount === null || $verifiedAmount != intval($Payment_report['price'])) {
    $ErrorsLinkPayment = sprintf($textbotlang['hardcoded']['tonpaysWebhookError'], json_encode($verified), $Payment_report['id_user'], $order_id);
    if (strlen($setting['Channel_Report']) > 0) {
        telegram('sendmessage', [
            'chat_id' => $setting['Channel_Report'],
            'message_thread_id' => $errorreport,
            'text' => $ErrorsLinkPayment,
            'parse_mode' => "HTML"
        ]);
    }
    http_response_code(200);
    echo json_encode(['ok' => false, 'error' => 'amount_mismatch']);
    return;
}

// Re-check right before writing, to close the race window between two callbacks
// arriving at nearly the same time.
$Payment_report = select("Payment_report", "*", "id_order", $order_id, "select");
if ($Payment_report['payment_Status'] == "paid") {
    http_response_code(200);
    echo json_encode(['ok' => true, 'already_paid' => true]);
    return;
}

update("Payment_report", "payment_Status", "paid", "id_order", $Payment_report['id_order']);

DirectPayment($Payment_report['id_order'], "../images.jpg");

$pricecashback = select("PaySetting", "ValuePay", "NamePay", "chashbacktonpays", "select")['ValuePay'];
$Balance_id = select("user", "*", "id", $Payment_report['id_user'], "select");
if ($pricecashback != "0") {
    $result = ($Payment_report['price'] * $pricecashback) / 100;
    $Balance_confrim = intval($Balance_id['Balance']) + $result;
    update("user", "Balance", $Balance_confrim, "id", $Balance_id['id']);
    $pricecashback = number_format($pricecashback);
    $text_report = sprintf($textbotlang['paymentGateway']['giftReport'], $result);
    sendmessage($Balance_id['id'], $text_report, null, 'HTML');
}

$price_format = number_format($Payment_report['price']);
$text_reportpayment = sprintf($textbotlang['paymentGateway']['reportTonPays'], $Payment_report['id_user'], $Balance_id['username'], $price_format, $invoice_id);
if (strlen($setting['Channel_Report']) > 0) {
    telegram('sendmessage', [
        'chat_id' => $setting['Channel_Report'],
        'message_thread_id' => $paymentreports,
        'text' => $text_reportpayment,
        'parse_mode' => "HTML"
    ]);
}

http_response_code(200);
echo json_encode(['ok' => true, 'paid' => true]);
