<?php
/**
 * imap-processor.php
 * Pure-PHP replacement for the Node.js IMAP daemon.
 * Called by checkout-status.php (non-blocking background request).
 */
require_once __DIR__ . '/../includes/functions.php';

if (($_GET['secret'] ?? '') !== CRON_SECRET) {
    http_response_code(403); echo 'Forbidden'; exit;
}

$userId = trim($_GET['user_id'] ?? '');
if (!$userId) {
    http_response_code(400); echo 'Missing user_id'; exit;
}

// 5-second lock per merchant to prevent Gmail spam
$lockFile = sys_get_temp_dir() . '/famgw_imap_' . $userId . '.lock';
if (file_exists($lockFile) && (time() - filemtime($lockFile)) < 5) {
    echo json_encode(['status' => 'locked']); exit;
}
file_put_contents($lockFile, time());

ignore_user_abort(true);
set_time_limit(30);

// Close the connection gracefully so the caller doesn't wait
if (function_exists('fastcgi_finish_request')) {
    fastcgi_finish_request();
} else {
    // Fallback for Apache/mod_php
    ob_end_clean();
    header("Connection: close");
    ob_start();
    echo "Processing in background...";
    $size = ob_get_length();
    header("Content-Length: $size");
    ob_end_flush();
    @ob_flush();
    @flush();
}

$user = getUserById($userId);
if (!$user || $user['status'] !== 'active' || !$user['gmail_connected']) {
    @unlink($lockFile); echo json_encode(['status' => 'skip']); exit;
}

$gmail = $user['fampay_gmail'] ?? '';
$appPassword = decryptData($user['fampay_app_password_encrypted'] ?? '');
if (!$gmail || !$appPassword) {
    @unlink($lockFile); echo json_encode(['status' => 'skip', 'message' => 'No Gmail credentials']); exit;
}

$inbox = @imap_open('{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX', $gmail, $appPassword, 0, 1, ['DISABLE_AUTHENTICATOR' => 'GSSAPI']);
if (!$inbox) {
    @unlink($lockFile);
    $err = imap_last_error();
    addSystemLog('PHP-IMAP', "IMAP connect failed for user {$userId}: " . $err);
    echo json_encode(['status' => 'error', 'message' => $err]); exit;
}

$sinceDate = date('d-M-Y', time() - 300);
$uids1 = imap_search($inbox, 'UNSEEN FROM "fampay.in" SINCE "' . $sinceDate . '"', SE_UID);
$uids2 = imap_search($inbox, 'UNSEEN FROM "famapp.in" SINCE "' . $sinceDate . '"', SE_UID);
$allUids = array_unique(array_merge($uids1 ?: [], $uids2 ?: []));

$processed = 0;

foreach ($allUids as $uid) {
    $msgNo = imap_msgno($inbox, $uid);
    if (!$msgNo) continue;

    $header = imap_headerinfo($inbox, $msgNo);
    $fromAddress = strtolower($header->fromaddress ?? '');
    if (!str_contains($fromAddress, '@fampay.in') && !str_contains($fromAddress, '@famapp.in')) continue;

    $rawBody = imap_body($inbox, $msgNo);
    $structure = imap_fetchstructure($inbox, $msgNo);
    if ($structure->encoding == 4) $body = quoted_printable_decode($rawBody);
    elseif ($structure->encoding == 3) $body = base64_decode($rawBody);
    else $body = $rawBody;

    $body = html_entity_decode(strip_tags($body), ENT_QUOTES | ENT_HTML5, 'UTF-8');
    $body = str_replace("\xC2\xA0", ' ', $body); // Convert UTF-8 non-breaking space to regular space
    $body = preg_replace('/[\x{200B}-\x{200D}\x{FEFF}\x{00AD}]/u', '', $body); // Remove zero-width spaces and soft hyphens
    $body = preg_replace('/\s+/u', ' ', $body);
    $subject = imap_utf8($header->subject ?? '');

    $cleanBody = str_replace(['₹', ','], '', $body);
    $cleanSubject = str_replace(['₹', ','], '', $subject);
    $amount = null;
    foreach (['/received\s*([\d\.]+)\s*from/iu', '/received\s*([\d\.]+)\s*in\s*your/iu', '/payment\s*of\s*([\d\.]+)\s*is\s*successful/iu', '/rs\.?\s*([\d\.]+)\s*(?:has been |was )?(?:received|credited)/iu'] as $p) {
        if (preg_match($p, $cleanBody, $m) || preg_match($p, $cleanSubject, $m)) { $amount = floatval($m[1]); break; }
    }

    imap_setflag_full($inbox, (string)$uid, '\\Seen', ST_UID);
    if (!$amount || $amount <= 0) continue;

    $pureBody = preg_replace('/[^A-Za-z0-9:_+-]/u', '', $body);

    $txnId = ''; 
    if (preg_match('/transactionid:?([A-Za-z0-9]+)date:/iu', $pureBody, $m)) $txnId = $m[1];
    elseif (preg_match('/transaction\s*id\s*:?\s*([A-Za-z0-9]+)/iu', $body, $m)) $txnId = $m[1];

    $utr = '';   
    if (preg_match('/utr:?(\d+)purpose:/iu', $pureBody, $m)) $utr = $m[1];
    elseif (preg_match('/UTR\s*:?\s*(\d+)/iu', $body, $m)) $utr = $m[1];

    $senderName = ''; 
    if (preg_match('/from\s+([A-Za-z\s]+?)\s+(?:at|transaction|Date|UTR|on)/iu', $body, $m)) $senderName = trim($m[1]);

    $extractedOrderId = ''; 
    if (preg_match('/purpose:paymentfororder([A-Za-z0-9_-]+?)ifthiswasnotdone/iu', $pureBody, $m)) $extractedOrderId = $m[1];
    elseif (preg_match('/Purpose\s*:\s*Payment for Order\s*([A-Za-z0-9_-]+)/iu', $body, $m)) $extractedOrderId = $m[1];

    $paymentTimestamp = property_exists($header, 'udate') ? $header->udate : time();

    addSystemLog('PHP-IMAP', "[{$userId}] Parsed: Rs.{$amount} from '{$senderName}' | Order: " . ($extractedOrderId ?: 'Unknown') . " | TxnId: '{$txnId}'");

    $ch = curl_init(getBaseUrl() . '/api/internal-process-payment.php');
    curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_TIMEOUT => 10,
        CURLOPT_POSTFIELDS => http_build_query(['secret' => CRON_SECRET, 'merchant_id' => $userId, 'amount' => $amount,
            'transaction_id' => $txnId, 'utr' => $utr, 'sender_name' => $senderName,
            'order_id' => $extractedOrderId, 'payment_timestamp' => $paymentTimestamp])]);
    $result = curl_exec($ch); curl_close($ch);
    addSystemLog('PHP-IMAP', "[{$userId}] Webhook: " . $result);
    $processed++;
}

imap_close($inbox);
@unlink($lockFile);
echo json_encode(['status' => 'ok', 'checked' => count($allUids), 'processed' => $processed]);
