<?php
/**
 * Bank Bot Webhook
 * POST /api/v1/payments/bot-webhook
 * 
 * Receives SMS notifications from the Android bot.
 * Extracts the reference number and amount.
 * Matches with pending payment requests to auto-activate subscriptions.
 */

declare(strict_types=1);

use App\Core\Database;
use App\Core\Security;
use App\Core\Validator;

$data = Security::sanitize(input());

// Simple Auth for the Bot
$botToken = env('BOT_WEBHOOK_TOKEN');
$providedToken = $_SERVER['HTTP_X_BOT_TOKEN'] ?? $data['token'] ?? '';

if ($providedToken !== $botToken) {
    json_error('Unauthorized', 401);
}

$errors = Validator::validate($data, [
    'raw_message' => 'required'
]);

if ($errors) {
    json_error('رسالة البنك مطلوبة.', 422);
}

$rawMessage = $data['raw_message'];
$bankReference = trim($data['bank_reference'] ?? '');
$amount = (float)($data['amount'] ?? 0);
$senderName = $data['sender_name'] ?? 'غير معروف';

// Robust Parsing Fallback (for Orange Money / CliQ Jordan)
if (empty($bankReference) || $amount <= 0) {
    // Try to extract amount: بمبلغ 15 دينار
    if (preg_match('/بمبلغ\s+([\d\.]+)\s+دينار/', $rawMessage, $matches)) {
        $amount = (float)$matches[1];
    }
    
    // Try to extract reference: بالرقم المرجعي JIBA...
    if (preg_match('/بالرقم المرجعي\s+([A-Z0-9a-z]+)/', $rawMessage, $matches)) {
        $bankReference = $matches[1];
    }

    // Try to extract sender: من FERAS...
    if (preg_match('/من\s+([^من]+)\s+من مزود/', $rawMessage, $matches)) {
        $senderName = trim($matches[1]);
    }
}

if (empty($bankReference) || $amount <= 0) {
    json_error('فشل استخراج بيانات التحويل من الرسالة.', 422);
}

$db = Database::getInstance();

try {
    $db->beginTransaction();

    // 1. Insert into bank_transactions
    $stmt = $db->prepare("
        INSERT INTO bank_transactions (bank_reference, amount, sender_name, raw_message, is_claimed, created_at)
        VALUES (?, ?, ?, ?, 0, NOW())
        ON DUPLICATE KEY UPDATE raw_message = VALUES(raw_message)
    ");
    $stmt->execute([$bankReference, $amount, $senderName, $rawMessage]);
    $transactionId = $db->lastInsertId();

    if (!$transactionId) {
        $transactionId = $db->query("SELECT id FROM bank_transactions WHERE bank_reference = '$bankReference'")->fetchColumn();
    }

    // 2. Check if there is a pending payment request waiting for this reference
    $stmt = $db->prepare("SELECT * FROM payment_requests WHERE bank_reference = ? AND status IN ('pending', 'uploaded')");
    $stmt->execute([$bankReference]);
    $payment = $stmt->fetch();

    $message = 'تم استلام وتخزين الحوالة البنكية.';

    if ($payment) {
        // Match found! Check amount
        $expectedAmount = (float)$payment['amount_jod'];

        if (abs($expectedAmount - $amount) < 0.01) {
            // Amount matches exactly -> Auto Approve
            activateSubscription($db, $payment, $payment['user_id']);

            $stmt = $db->prepare("UPDATE payment_requests SET status = 'approved', verified_at = NOW() WHERE id = ?");
            $stmt->execute([$payment['id']]);

            $stmt = $db->prepare("UPDATE bank_transactions SET is_claimed = 1 WHERE id = ?");
            $stmt->execute([$transactionId]);

            $message = 'تم استلام الحوالة ومطابقتها وتفعيل الاشتراك بنجاح.';
        } else {
            // Amount mismatch -> Needs manual review
            $stmt = $db->prepare("UPDATE payment_requests SET admin_notes = 'تم وصول الحوالة ولكن المبلغ غير متطابق' WHERE id = ?");
            $stmt->execute([$payment['id']]);
            $message = 'تم استلام الحوالة، لكن المبلغ لم يتطابق مع الطلب.';
        }
    }

    $db->commit();
    json_success(['status' => 'received'], $message);

} catch (\Throwable $e) {
    if ($db->inTransaction()) $db->rollBack();
    error_log("Bot Webhook Error: " . $e->getMessage());
    json_error('حدث خطأ أثناء معالجة رسالة البوت.', 500);
}

/**
 * Auto-activate subscription upon verified payment
 */
function activateSubscription(\PDO $db, array $payment, string $userId): void
{
    $stmt = $db->prepare("SELECT * FROM subscription_plans WHERE id = ? AND is_active = 1");
    $stmt->execute([$payment['plan_id']]);
    $plan = $stmt->fetch();

    if (!$plan) return;

    $startDate = date('Y-m-d H:i:s');
    $endDate   = date('Y-m-d H:i:s', strtotime('+30 days'));

    $stmt = $db->prepare("
        INSERT INTO subscriptions (tenant_id, plan_id, max_companies, max_invoices_per_month, max_users, price_jod, status, current_period_start, current_period_end, updated_at)
        VALUES (:t_id, :p_id, :max_c, :max_i, :max_u, :price, 'active', :start, :end, NOW())
        ON DUPLICATE KEY UPDATE
            plan_id = VALUES(plan_id),
            max_companies = VALUES(max_companies),
            max_invoices_per_month = VALUES(max_invoices_per_month),
            max_users = VALUES(max_users),
            price_jod = VALUES(price_jod),
            status = 'active',
            current_period_start = VALUES(current_period_start),
            current_period_end = VALUES(current_period_end),
            updated_at = NOW()
    ");

    $stmt->execute([
        't_id'  => $payment['tenant_id'],
        'p_id'  => $plan['id'],
        'max_c' => $plan['max_companies'],
        'max_i' => $plan['max_invoices_month'],
        'max_u' => $plan['max_users'],
        'price' => $plan['price_jod'],
        'start' => $startDate,
        'end'   => $endDate
    ]);

    // Log activation
    $logStmt = $db->prepare("INSERT INTO audit_logs (tenant_id, user_id, action, entity_type, entity_id, new_data) VALUES (?, ?, 'subscription.activated', 'payment', ?, ?)");
    $logStmt->execute([
        $payment['tenant_id'],
        $userId,
        $payment['id'],
        json_encode(['plan_id' => $plan['id'], 'auto_verified' => true, 'source' => 'bot_webhook'])
    ]);
}
