<?php
/**
 * SMS Bank Integration — Receive & Auto-Match Payments
 * POST /v1/sms/receive
 * 
 * Flow:
 * 1. Android SMS Bot intercepts bank/wallet SMS
 * 2. Sends it here: { "sender": "BANK_NAME", "message": "تم تحويل 45 دينار..." }
 * 3. We save it in raw_sms_log with status "pending"
 * 4. We immediately try to match it against pending payment requests
 * 5. If matched → confirm payment → update subscription → notify user
 */

declare(strict_types=1);

use App\Core\Database;
use App\Core\AuditLogger;

// Auth: Verify webhook secret (shared between Android bot and server)
$webhookSecret = env('SMS_WEBHOOK_SECRET', '');
$incomingSecret = $_SERVER['HTTP_X_WEBHOOK_SECRET'] ?? $_SERVER['HTTP_X_SMS_SECRET'] ?? '';

if (!empty($webhookSecret) && !hash_equals($webhookSecret, $incomingSecret)) {
    http_response_code(401);
    echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
    exit;
}

$json_data = file_get_contents('php://input');
$data = json_decode($json_data, true);

if (!$data || empty($data['sender']) || empty($data['message'])) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'بيانات غير مكتملة. يجب إرسال sender و message.']);
    exit;
}

$sender  = trim($data['sender']);
$message = trim($data['message']);

$db = Database::getInstance();

try {
    // 1. Save raw SMS log
    $smsId = \App\Core\Database::generateUuid();
    $stmt = $db->prepare("
        INSERT INTO raw_sms_log (id, sender, message_body, status, received_at) 
        VALUES (?, ?, ?, 'pending', NOW())
    ");
    $stmt->execute([$smsId, $sender, $message]);

    // 2. Try to auto-match with pending payments
    $matchResult = matchPayment($db, $smsId, $sender, $message);

    http_response_code(200);
    echo json_encode([
        'status'  => 'success',
        'message' => 'SMS received and processed.',
        'matched' => $matchResult['matched'],
        'details' => $matchResult['details'] ?? null,
    ], JSON_UNESCAPED_UNICODE);

} catch (\Exception $e) {
    error_log("[sms/receive] Error: " . $e->getMessage());
    http_response_code(200); // Return 200 so bot doesn't retry
    echo json_encode(['status' => 'error', 'message' => 'خطأ داخلي في المعالجة.']);
}

/**
 * Try to match the incoming SMS with a pending payment request.
 * 
 * Matching logic:
 * 1. Extract reference number from SMS (formats: MSQ-XXXX, REF-XXXX, or plain digits)
 * 2. Extract amount from SMS
 * 3. Find pending payment request matching reference OR amount
 * 4. If matched → confirm payment → activate/extend subscription
 */
function matchPayment(\PDO $db, string $smsId, string $sender, string $message): array
{
    // Extract reference number (MSQ-XXXX pattern or any 6+ digit number)
    $reference = null;
    if (preg_match('/MSQ-([A-Z0-9]{4,10})/i', $message, $m)) {
        $reference = 'MSQ-' . strtoupper($m[1]);
    } elseif (preg_match('/REF[:\s-]*([A-Z0-9]{4,12})/i', $message, $m)) {
        $reference = $m[1];
    }

    // Extract amount (Arabic or English digits)
    $amount = null;
    $msgNormalized = strtr($message, ['٠'=>'0','١'=>'1','٢'=>'2','٣'=>'3','٤'=>'4','٥'=>'5','٦'=>'6','٧'=>'7','٨'=>'8','٩'=>'9']);
    if (preg_match('/(\d+[\.,]?\d{0,3})\s*(دينار|JOD|JD)/iu', $msgNormalized, $m)) {
        $amount = (float)str_replace(',', '.', $m[1]);
    } elseif (preg_match('/(\d+[\.,]\d{2})/', $msgNormalized, $m)) {
        $amount = (float)str_replace(',', '.', $m[1]);
    }

    if (!$reference && !$amount) {
        // Can't match — mark SMS as unmatched
        $db->prepare("UPDATE raw_sms_log SET status = 'unmatched', processed_at = NOW() WHERE id = ?")->execute([$smsId]);
        return ['matched' => false, 'details' => 'لم يتم العثور على مرجع أو مبلغ في الرسالة'];
    }

    // Search for pending payment request
    $where = "pr.status = 'pending'";
    $params = [];

    if ($reference) {
        $where .= " AND pr.reference_number = ?";
        $params[] = $reference;
    }
    if ($amount) {
        $where .= " AND pr.amount = ?";
        $params[] = $amount;
    }

    $stmt = $db->prepare("
        SELECT pr.*, t.name as tenant_name
        FROM payment_requests pr
        LEFT JOIN tenants t ON pr.tenant_id = t.id
        WHERE {$where}
        ORDER BY pr.created_at DESC
        LIMIT 1
    ");
    $stmt->execute($params);
    $payment = $stmt->fetch();

    if (!$payment) {
        $db->prepare("UPDATE raw_sms_log SET status = 'unmatched', extracted_ref = ?, extracted_amount = ?, processed_at = NOW() WHERE id = ?")
            ->execute([$reference, $amount, $smsId]);
        return ['matched' => false, 'details' => "مرجع: {$reference}, مبلغ: {$amount} — لم يتطابق مع أي طلب دفع"];
    }

    // MATCH FOUND — Process payment
    $db->beginTransaction();

    try {
        // 1. Update payment request → confirmed
        $db->prepare("
            UPDATE payment_requests SET status = 'confirmed', sms_log_id = ?, confirmed_at = NOW() WHERE id = ?
        ")->execute([$smsId, $payment['id']]);

        // 2. Update SMS log → matched
        $db->prepare("
            UPDATE raw_sms_log SET status = 'matched', payment_request_id = ?, extracted_ref = ?, extracted_amount = ?, processed_at = NOW() WHERE id = ?
        ")->execute([$payment['id'], $reference, $amount, $smsId]);

        // 3. Activate/extend subscription
        $planMonths = (int)($payment['plan_months'] ?? 1);
        $db->prepare("
            UPDATE subscriptions 
            SET is_active = 1, 
                started_at = COALESCE(started_at, NOW()),
                expires_at = DATE_ADD(COALESCE(expires_at, NOW()), INTERVAL ? MONTH),
                updated_at = NOW()
            WHERE tenant_id = ?
        ")->execute([$planMonths, $payment['tenant_id']]);

        // 4. Notify user
        \App\Services\SmartNotifications::send(
            $payment['tenant_id'],
            $payment['user_id'] ?? '',
            'payment_confirmed',
            '✅ تم تأكيد الدفع!',
            "تم تأكيد دفعة بقيمة {$payment['amount']} دينار. اشتراكك فعّال الآن.",
            ['payment_id' => $payment['id'], 'amount' => $payment['amount']]
        );

        // 5. Audit log
        AuditLogger::log('payment.auto_confirmed', 'payment', $payment['id'], null, [
            'sms_id'    => $smsId,
            'sender'    => $sender,
            'reference' => $reference,
            'amount'    => $amount,
        ], ['user_id' => 'system', 'tenant_id' => $payment['tenant_id'], 'role' => 'system']);

        $db->commit();

        return [
            'matched' => true,
            'details' => "تم مطابقة الدفعة: {$payment['amount']} دينار — الاشتراك مُفعّل",
        ];

    } catch (\Exception $e) {
        $db->rollBack();
        error_log("[sms/match] Failed: " . $e->getMessage());
        return ['matched' => false, 'details' => 'خطأ أثناء تأكيد الدفعة'];
    }
}
