<?php

declare(strict_types=1);

/**
 * FinoviaPay Telegram Bot - International Transfer Verification Functions
 * Phase 1: Verification-only access flow for International Transfers
 */

if (!function_exists('botIntTransferStatePrefix')) {
    function botIntTransferStatePrefix(): string
    {
        return 'INT_TRANSFER_VERIFY_';
    }
}

if (!function_exists('botIntTransferAllowedVerificationStates')) {
    function botIntTransferAllowedVerificationStates(): array
    {
        return [
            'INT_TRANSFER_VERIFY_INTRO',
            'INT_TRANSFER_VERIFY_FULL_NAME',
            'INT_TRANSFER_VERIFY_DOB',
            'INT_TRANSFER_VERIFY_COUNTRY',
            'INT_TRANSFER_VERIFY_NATIONALITY',
            'INT_TRANSFER_VERIFY_OCCUPATION',
            'INT_TRANSFER_VERIFY_SOURCE_OF_FUNDS',
            'INT_TRANSFER_VERIFY_MONTHLY_VOLUME',
            'INT_TRANSFER_VERIFY_PURPOSE',
            'INT_TRANSFER_VERIFY_RELATIONSHIP',
            'INT_TRANSFER_VERIFY_DOC_NUMBER',
            'INT_TRANSFER_VERIFY_DOC_FRONT',
            'INT_TRANSFER_VERIFY_DOC_BACK',
            'INT_TRANSFER_VERIFY_SELFIE',
            'INT_TRANSFER_VERIFY_VIDEO',
            'INT_TRANSFER_VERIFY_REVIEW',
        ];
    }
}

if (!function_exists('botIntTransferResolveUserId')) {
    function botIntTransferResolveUserId(array $state): int
    {
        $candidates = [
            $state['identified_user_id'] ?? null,
            $state['user_id'] ?? null,
            $state['user']['id'] ?? null,
            $state['blocked_user']['id'] ?? null,
        ];

        foreach ($candidates as $candidate) {
            if (is_numeric($candidate) && (int)$candidate > 0) {
                return (int)$candidate;
            }
        }

        return 0;
    }
}

if (!function_exists('botIntTransferGetLatestVerification')) {
    function botIntTransferGetLatestVerification(PDO $pdo, int $userId): ?array
    {
        if ($userId <= 0) {
            return null;
        }

        $sql = "SELECT * FROM bot_int_transfer_verifications WHERE user_id = :user_id ORDER BY id DESC LIMIT 1";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([':user_id' => $userId]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        return is_array($row) ? $row : null;
    }
}

if (!function_exists('botIsIntTransferEnabled')) {
    function botIsIntTransferEnabled(PDO $pdo, int $userId): bool
    {
        $row = botIntTransferGetLatestVerification($pdo, $userId);
        if (!$row) {
            return false;
        }

        return (int)($row['service_enabled'] ?? 0) === 1;
    }
}

if (!function_exists('botIntTransferMaskDocumentNumber')) {
    function botIntTransferMaskDocumentNumber(?string $documentNumber): string
    {
        $value = trim((string)$documentNumber);
        if ($value === '') {
            return 'Not Provided';
        }

        $length = mb_strlen($value);
        if ($length <= 4) {
            return str_repeat('*', $length);
        }

        return str_repeat('*', max(0, $length - 4)) . mb_substr($value, -4);
    }
}

if (!function_exists('botIntTransferGenerateReference')) {
    function botIntTransferGenerateReference(): string
    {
        try {
            $random = strtoupper(bin2hex(random_bytes(3)));
        } catch (Throwable $e) {
            $random = strtoupper(substr(md5((string)microtime(true)), 0, 6));
        }

        return 'ITV-' . date('Ymd') . '-' . $random;
    }
}


if (!function_exists('botIntTransferFindMailerFile')) {
    function botIntTransferFindMailerFile(): ?string
    {
        $candidates = [
            __DIR__ . '/../lib/mailer.php',
            __DIR__ . '/lib/mailer.php',
            __DIR__ . '/../ebankinguser/lib/mailer.php',
            __DIR__ . '/ebankinguser/lib/mailer.php',
            dirname(__DIR__) . '/ebankinguser/lib/mailer.php',
        ];

        foreach ($candidates as $candidate) {
            if (is_file($candidate)) {
                return $candidate;
            }
        }

        return null;
    }
}

if (!function_exists('botIntTransferGetUserEmail')) {
    function botIntTransferGetUserEmail(PDO $pdo, int $userId): string
    {
        if ($userId <= 0) {
            return '';
        }

        try {
            $stmt = $pdo->prepare("SELECT email FROM users WHERE id = :id LIMIT 1");
            $stmt->execute([':id' => $userId]);
            $email = (string)($stmt->fetchColumn() ?: '');
            return filter_var(trim($email), FILTER_VALIDATE_EMAIL) ? trim($email) : '';
        } catch (Throwable $e) {
            error_log('BOT ERROR: Unable to fetch verification email address: ' . $e->getMessage());
            return '';
        }
    }
}

if (!function_exists('botIntTransferBuildSubmissionEmailHtml')) {
    function botIntTransferBuildSubmissionEmailHtml(array $draft, string $reference, int $userId): string
    {
        $fullName = htmlspecialchars((string)($draft['full_name'] ?? 'Valued Customer'), ENT_QUOTES, 'UTF-8');
        $submittedAt = htmlspecialchars(date('d M Y H:i'), ENT_QUOTES, 'UTF-8');
        $country = htmlspecialchars((string)($draft['country_of_residence'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8');
        $source = htmlspecialchars((string)($draft['source_of_funds'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8');
        $volume = htmlspecialchars((string)($draft['expected_monthly_volume_eur'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8');
        $purpose = htmlspecialchars((string)($draft['transfer_purpose'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8');
        $docType = htmlspecialchars((string)($draft['document_type'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8');
        $docNumber = htmlspecialchars(botIntTransferMaskDocumentNumber((string)($draft['document_number'] ?? '')), ENT_QUOTES, 'UTF-8');
        $relationship = htmlspecialchars((string)($draft['beneficiary_relationship'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8');
        $referenceSafe = htmlspecialchars($reference, ENT_QUOTES, 'UTF-8');

        return '<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>International Transfer Verification Submitted</title>
</head>
<body style="margin:0;padding:0;background:#f4f7fb;font-family:Segoe UI,Arial,sans-serif;color:#1f2937;">
  <table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background:#f4f7fb;padding:24px 12px;">
    <tr>
      <td align="center">
        <table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="max-width:680px;background:#ffffff;border-radius:16px;overflow:hidden;">
          <tr>
            <td style="background:#0b3d91;padding:24px 28px;color:#ffffff;">
              <div style="font-size:13px;letter-spacing:.5px;opacity:.9;">FinoviaPay Compliance Department</div>
              <div style="font-size:28px;font-weight:700;margin-top:8px;">Verification Request Received</div>
              <div style="font-size:14px;margin-top:8px;opacity:.95;">International Transfer Service Activation</div>
            </td>
          </tr>
          <tr>
            <td style="padding:30px 28px;">
              <p style="margin:0 0 18px;font-size:16px;line-height:1.7;">Dear ' . $fullName . ',</p>
              <p style="margin:0 0 18px;font-size:15px;line-height:1.8;">
                Thank you for submitting your International Transfer verification request with FinoviaPay.
                This email confirms that your compliance request has been received successfully and is now pending review by our banking compliance team.
              </p>

              <table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="margin:22px 0;background:#f8fbff;border:1px solid #dbe7f6;border-radius:12px;">
                <tr><td style="padding:18px 20px;">
                  <div style="font-size:18px;font-weight:700;color:#0b3d91;margin-bottom:12px;">Submission Details</div>
                  <div style="font-size:14px;line-height:1.9;">
                    <strong>Reference ID:</strong> ' . $referenceSafe . '<br>
                    <strong>Submission Date:</strong> ' . $submittedAt . '<br>
                    <strong>Customer ID:</strong> ' . (int)$userId . '<br>
                    <strong>Country of Residence:</strong> ' . $country . '<br>
                    <strong>Source of Funds:</strong> ' . $source . '<br>
                    <strong>Expected Monthly Volume:</strong> EUR ' . $volume . '<br>
                    <strong>Transfer Purpose:</strong> ' . $purpose . '<br>
                    <strong>Beneficiary Relationship:</strong> ' . $relationship . '<br>
                    <strong>Document Type:</strong> ' . $docType . '<br>
                    <strong>Document Number:</strong> ' . $docNumber . '
                  </div>
                </td></tr>
              </table>

              <p style="margin:0 0 16px;font-size:15px;line-height:1.8;">
                Our compliance team will review your submission within <strong>24 to 72 hours</strong>.
                If further clarification or a re-upload is required, you will be notified through your registered communication channels.
              </p>

              <p style="margin:0 0 16px;font-size:15px;line-height:1.8;">
                Please note that International Transfer services remain restricted until your verification has been reviewed and formally approved.
              </p>

              <table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="margin:24px 0;background:#fff8e8;border:1px solid #f0dca3;border-radius:12px;">
                <tr><td style="padding:16px 18px;font-size:14px;line-height:1.8;color:#5b4b1a;">
                  <strong>Security Notice:</strong> FinoviaPay will never request your password, OTP, or confidential access credentials by email.
                  If you receive any suspicious communication, please contact our support team immediately.
                </td></tr>
              </table>

              <p style="margin:0 0 8px;font-size:15px;line-height:1.8;">
                We appreciate your cooperation and thank you for banking with FinoviaPay.
              </p>
              <p style="margin:18px 0 0;font-size:15px;line-height:1.8;">
                Sincerely,<br>
                <strong>FinoviaPay Compliance Department</strong><br>
                Worldwide Digital Internet Banking
              </p>
            </td>
          </tr>
          <tr>
            <td style="padding:18px 28px;background:#f7f9fc;border-top:1px solid #e5edf6;font-size:12px;color:#6b7280;line-height:1.7;">
              This is an automated confirmation email regarding your International Transfer verification request.
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>
</html>';
    }
}

if (!function_exists('botIntTransferSendSubmissionEmail')) {
    function botIntTransferSendSubmissionEmail(PDO $pdo, int $userId, array $draft, string $reference): bool
    {
        $to = botIntTransferGetUserEmail($pdo, $userId);
        if ($to === '') {
            error_log('BOT ERROR: Verification email skipped because no valid email was found for user ID ' . $userId);
            return false;
        }

        $subject = 'International Transfer Verification Submitted - FinoviaPay';
        $html = botIntTransferBuildSubmissionEmailHtml($draft, $reference, $userId);

        $mailerFile = botIntTransferFindMailerFile();
        if ($mailerFile && !function_exists('sendMail')) {
            require_once $mailerFile;
        }

        if (function_exists('sendMail')) {
            try {
                if (@sendMail($to, $subject, $html)) {
                    return true;
                }
            } catch (Throwable $e) {
                error_log('BOT ERROR: sendMail failed for verification email: ' . $e->getMessage());
            }
        }

        $headers = "MIME-Version: 1.0\r\n";
        $headers .= "Content-type:text/html;charset=UTF-8\r\n";
        $headers .= "From: FinoviaPay <no-reply@finoviapay.com>\r\n";

        $result = @mail($to, $subject, $html, $headers);
        if (!$result) {
            error_log('BOT ERROR: Fallback mail() failed for verification email to ' . $to);
        }

        return $result;
    }
}



if (!function_exists('botIntTransferDownloadTelegramFile')) {
    function botIntTransferDownloadTelegramFile(string $fileId, string $prefix = 'int_transfer'): ?array
    {
        global $token;

        if ($fileId === '' || !function_exists('botTelegramApiRequest') || empty($token)) {
            return null;
        }

        $meta = botTelegramApiRequest('getFile', ['file_id' => $fileId]);
        if (!is_array($meta) || empty($meta['ok']) || empty($meta['result']['file_path'])) {
            return null;
        }

        $telegramPath = (string)$meta['result']['file_path'];
        $ext = strtolower((string)pathinfo($telegramPath, PATHINFO_EXTENSION));
        if ($ext === '') {
            $ext = 'jpg';
        }

        $dir = __DIR__ . '/uploads/int_transfer_verification';
        if (!is_dir($dir)) {
            @mkdir($dir, 0775, true);
        }
        if (!is_dir($dir) || !is_writable($dir)) {
            return null;
        }

        try {
            $random = bin2hex(random_bytes(4));
        } catch (Throwable $e) {
            $random = substr(md5((string)microtime(true)), 0, 8);
        }

        $safePrefix = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $prefix);
        $filename = $safePrefix . '_' . date('Ymd_His') . '_' . $random . '.' . $ext;
        $absolutePath = $dir . '/' . $filename;
        $downloadUrl = "https://api.telegram.org/file/bot{$token}/{$telegramPath}";
        $binary = @file_get_contents($downloadUrl);

        if ($binary === false) {
            return null;
        }

        if (@file_put_contents($absolutePath, $binary) === false) {
            return null;
        }

        return [
            'absolute_path' => $absolutePath,
            'relative_path' => 'uploads/int_transfer_verification/' . $filename,
            'filename' => $filename,
            'telegram_file_id' => $fileId,
        ];
    }
}

if (!function_exists('botIntTransferVerificationKeyboard')) {
    function botIntTransferVerificationKeyboard(): array
    {
        return [
            'inline_keyboard' => [
                [
                    ['text' => '✅ Start Int Transfer Verification', 'callback_data' => 'int_transfer_start_verification'],
                ],
                [
                    ['text' => '📊 Verification Status', 'callback_data' => 'int_transfer_verification_status'],
                ],
                [
                    ['text' => '🆘 Int Transfer Help', 'callback_data' => 'int_transfer_help'],
                ],
                [
                    ['text' => '⬅️ Back', 'callback_data' => 'transfer_management_menu'],
                ],
            ],
        ];
    }
}

if (!function_exists('botIntTransferFullServiceKeyboard')) {
    function botIntTransferFullServiceKeyboard(): array
    {
        return [
            'inline_keyboard' => [
                [['text' => '🌍 Make a Int Transfer', 'callback_data' => 'int_transfer_make_transfer']],
                [['text' => '📈 Int Transfer Limit Management', 'callback_data' => 'int_transfer_limits']],
                [['text' => '🧾 Int Transfer History', 'callback_data' => 'int_transfer_history']],
                [['text' => '📡 Int Transfer Status', 'callback_data' => 'int_transfer_status']],
                [['text' => '🆘 Int Support / Help', 'callback_data' => 'int_transfer_help']],
                [['text' => '⬅️ Back', 'callback_data' => 'transfer_management_menu']],
            ],
        ];
    }
}

if (!function_exists('botIntTransferDocTypeKeyboard')) {
    function botIntTransferDocTypeKeyboard(): array
    {
        return [
            'inline_keyboard' => [
                [
                    ['text' => '🪪 National ID Card', 'callback_data' => 'int_transfer_doc_type_national_id_card'],
                ],
                [
                    ['text' => '📘 Passport', 'callback_data' => 'int_transfer_doc_type_passport'],
                ],
                [
                    ['text' => '🏠 Residence Permit', 'callback_data' => 'int_transfer_doc_type_residence_permit'],
                ],
                [
                    ['text' => '❌ Cancel Verification', 'callback_data' => 'int_transfer_cancel_verification'],
                ],
            ],
        ];
    }
}

if (!function_exists('botIntTransferYesNoKeyboard')) {
    function botIntTransferYesNoKeyboard(string $yesCallback, string $noCallback): array
    {
        return [
            'inline_keyboard' => [
                [
                    ['text' => 'Yes', 'callback_data' => $yesCallback],
                    ['text' => 'No', 'callback_data' => $noCallback],
                ],
                [
                    ['text' => '❌ Cancel Verification', 'callback_data' => 'int_transfer_cancel_verification'],
                ],
            ],
        ];
    }
}

if (!function_exists('botIntTransferSelfieKeyboard')) {
    function botIntTransferSelfieKeyboard(): array
    {
        return [
            'inline_keyboard' => [
                [['text' => '⏭️ Skip Selfie', 'callback_data' => 'int_transfer_skip_selfie']],
                [['text' => '❌ Cancel Verification', 'callback_data' => 'int_transfer_cancel_verification']],
            ],
        ];
    }
}

if (!function_exists('botIntTransferReviewKeyboard')) {
    function botIntTransferReviewKeyboard(): array
    {
        return [
            'inline_keyboard' => [
                [['text' => '✅ Submit Verification', 'callback_data' => 'int_transfer_submit_verification']],
                [['text' => '🔄 Cancel and Restart', 'callback_data' => 'int_transfer_restart_verification']],
                [['text' => '❌ Cancel', 'callback_data' => 'int_transfer_cancel_verification']],
            ],
        ];
    }
}

if (!function_exists('botIntTransferSubmittedKeyboard')) {
    function botIntTransferSubmittedKeyboard(): array
    {
        return [
            'inline_keyboard' => [
                [['text' => '📊 Check Status', 'callback_data' => 'int_transfer_verification_status']],
                [['text' => '⬅️ Back', 'callback_data' => 'int_transfer_management_menu']],
            ],
        ];
    }
}

if (!function_exists('botIntTransferSetStep')) {
    function botIntTransferSetStep(array &$states, string $stateFile, $chatId, string $step): void
    {
        if (!isset($states[$chatId]) || !is_array($states[$chatId])) {
            $states[$chatId] = [];
        }
        $states[$chatId]['step'] = $step;
        saveStates($states, $stateFile);
    }
}

if (!function_exists('botIntTransferClearDraft')) {
    function botIntTransferClearDraft(array &$states, string $stateFile, $chatId): void
    {
        if (!isset($states[$chatId]) || !is_array($states[$chatId])) {
            return;
        }

        unset($states[$chatId]['int_transfer_verification']);
        saveStates($states, $stateFile);
    }
}

if (!function_exists('botIntTransferSaveDraftField')) {
    function botIntTransferSaveDraftField(array &$states, string $stateFile, $chatId, string $field, $value): void
    {
        if (!isset($states[$chatId]) || !is_array($states[$chatId])) {
            $states[$chatId] = [];
        }

        if (!isset($states[$chatId]['int_transfer_verification']) || !is_array($states[$chatId]['int_transfer_verification'])) {
            $states[$chatId]['int_transfer_verification'] = [];
        }

        $states[$chatId]['int_transfer_verification'][$field] = $value;
        saveStates($states, $stateFile);
    }
}

if (!function_exists('botIntTransferGetDraft')) {
    function botIntTransferGetDraft(array $states, $chatId): array
    {
        $draft = $states[$chatId]['int_transfer_verification'] ?? [];
        return is_array($draft) ? $draft : [];
    }
}

if (!function_exists('botIntTransferResetVerificationSession')) {
    function botIntTransferResetVerificationSession(array &$states, string $stateFile, $chatId): void
    {
        botIntTransferClearDraft($states, $stateFile, $chatId);
        if (!isset($states[$chatId]) || !is_array($states[$chatId])) {
            $states[$chatId] = [];
        }
        $states[$chatId]['step'] = 'int_transfer_management_menu';
        saveStates($states, $stateFile);
    }
}

if (!function_exists('botShowIntTransferManagementMenu')) {
    function botShowIntTransferManagementMenu(PDO $pdo, array &$states, string $stateFile, $chatId): void
    {
        $state = $states[$chatId] ?? [];
        $userId = botIntTransferResolveUserId($state);

        if ($userId > 0 && botIsIntTransferEnabled($pdo, $userId)) {
            $message = "🌍 <b>International Transfer Management</b>\n\n"
                . "Your International Transfer service is active on your FinoviaPay profile. "
                . "Please select one of the available service options below.";
            $states[$chatId]['step'] = 'int_transfer_management_menu';
            saveStates($states, $stateFile);
            sendMessage($chatId, $message, botIntTransferFullServiceKeyboard());
            return;
        }

        $message = "🌍 <b>International Transfer Management</b>\n\n"
            . "International Transfer services are not enabled by default.\n\n"
            . "Before activation, you are required to complete a mandatory verification process, including:\n"
            . "• Basic AML information\n"
            . "• Identity document verification\n"
            . "• Short video identity confirmation\n\n"
            . "Please choose one of the options below to proceed.";

        $states[$chatId]['step'] = 'int_transfer_management_menu';
        saveStates($states, $stateFile);
        sendMessage($chatId, $message, botIntTransferVerificationKeyboard());
    }
}

if (!function_exists('botShowIntTransferHelp')) {
    function botShowIntTransferHelp($chatId): void
    {
        $message = "🆘 <b>International Transfer Help</b>\n\n"
            . "To activate International Transfer services, you must first complete the required compliance verification.\n\n"
            . "<b>This includes:</b>\n"
            . "• Basic AML information\n"
            . "• Identity document verification\n"
            . "• Short video confirmation\n\n"
            . "<b>Important guidance:</b>\n"
            . "• Please provide accurate information only\n"
            . "• Ensure your document images are clear and readable\n"
            . "• Record your video in good lighting\n"
            . "• Your face and document must be clearly visible\n\n"
            . "You may use the verification option to begin your request.";

        sendMessage($chatId, $message, botIntTransferVerificationKeyboard());
    }
}

if (!function_exists('botFormatIntTransferVerificationStatus')) {
    function botFormatIntTransferVerificationStatus(?array $verification): string
    {
        if (!$verification) {
            return "📊 <b>Verification Status</b>\n\n"
                . "No International Transfer verification request has been submitted yet.\n\n"
                . "Please start your verification to proceed.";
        }

        $status = strtoupper(trim((string)($verification['status'] ?? 'PENDING_REVIEW')));
        $reference = htmlspecialchars((string)($verification['reference_code'] ?? 'Not Available'), ENT_QUOTES, 'UTF-8');
        $serviceEnabled = (int)($verification['service_enabled'] ?? 0) === 1 ? 'Enabled' : 'Not Enabled';
        $createdAtRaw = trim((string)($verification['created_at'] ?? ''));
        $submittedAt = $createdAtRaw !== '' ? date('d M Y H:i', strtotime($createdAtRaw)) : 'Not Available';
        $notes = trim((string)($verification['admin_notes'] ?? ''));

        $statusMessage = [
            'PENDING_REVIEW' => 'Your verification request has been submitted successfully and is currently awaiting compliance review.',
            'UNDER_REVIEW' => 'Your verification request is currently under review by our compliance team.',
            'ADDITIONAL_INFO_REQUIRED' => 'Additional information is required before your request can be completed.',
            'APPROVED' => 'Your verification request has been approved successfully.',
            'REJECTED' => 'Your verification request could not be approved at this time.',
            'CANCELLED' => 'Your verification request has been cancelled.',
        ][$status] ?? 'Your latest verification request has been recorded in our system.';

        $lines = [
            "📊 <b>Verification Status</b>",
            '',
            $statusMessage,
            '',
            "<b>Reference ID:</b> {$reference}",
            "<b>Current Status:</b> " . htmlspecialchars($status, ENT_QUOTES, 'UTF-8'),
            "<b>Service Access:</b> {$serviceEnabled}",
            "<b>Submitted On:</b> " . htmlspecialchars($submittedAt, ENT_QUOTES, 'UTF-8'),
        ];

        if ($notes !== '') {
            $lines[] = '<b>Compliance Note:</b> ' . htmlspecialchars($notes, ENT_QUOTES, 'UTF-8');
        }

        if ((int)($verification['service_enabled'] ?? 0) === 1) {
            $lines[] = '';
            $lines[] = 'You may now access International Transfer services through your FinoviaPay Telegram Banking Desk.';
        }

        return implode("\n", $lines);
    }
}

if (!function_exists('botShowIntTransferVerificationStatus')) {
    function botShowIntTransferVerificationStatus(PDO $pdo, array $states, $chatId): void
    {
        $state = $states[$chatId] ?? [];
        $userId = botIntTransferResolveUserId($state);
        $verification = $userId > 0 ? botIntTransferGetLatestVerification($pdo, $userId) : null;
        sendMessage($chatId, botFormatIntTransferVerificationStatus($verification), botIntTransferVerificationKeyboard());
    }
}

if (!function_exists('botBuildIntTransferReviewMessage')) {
    function botBuildIntTransferReviewMessage(array $draft): string
    {
        $selfieStatus = !empty($draft['selfie_file_id']) ? 'Received' : 'Skipped';
        $frontStatus = !empty($draft['document_front_file_id']) ? 'Received' : 'Pending';
        $backStatus = !empty($draft['document_back_file_id']) ? 'Received' : 'Pending';
        $videoStatus = !empty($draft['video_file_id']) ? 'Received' : 'Pending';

        return "📑 <b>Verification Summary</b>\n\n"
            . "Please review your submitted information carefully:\n\n"
            . "• <b>Full Name:</b> " . htmlspecialchars((string)($draft['full_name'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Date of Birth:</b> " . htmlspecialchars((string)($draft['date_of_birth'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Country of Residence:</b> " . htmlspecialchars((string)($draft['country_of_residence'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Nationality:</b> " . htmlspecialchars((string)($draft['nationality'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Occupation:</b> " . htmlspecialchars((string)($draft['occupation'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Source of Funds:</b> " . htmlspecialchars((string)($draft['source_of_funds'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Expected Monthly Volume:</b> " . htmlspecialchars((string)($draft['expected_monthly_volume_eur'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . " EUR\n"
            . "• <b>Transfer Purpose:</b> " . htmlspecialchars((string)($draft['transfer_purpose'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Beneficiary Relationship:</b> " . htmlspecialchars((string)($draft['beneficiary_relationship'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Politically Exposed Person:</b> " . htmlspecialchars(strtoupper((string)($draft['is_pep'] ?? 'Not Provided')), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Third-Party Transactions:</b> " . htmlspecialchars(strtoupper((string)($draft['is_third_party'] ?? 'Not Provided')), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Legal Funds Confirmed:</b> " . htmlspecialchars(strtoupper((string)($draft['legal_funds_confirmed'] ?? 'Not Provided')), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Prior Transfer Experience:</b> " . htmlspecialchars(strtoupper((string)($draft['prior_transfer_experience'] ?? 'Not Provided')), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Document Type:</b> " . htmlspecialchars((string)($draft['document_type'] ?? 'Not Provided'), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Document Number:</b> " . htmlspecialchars(botIntTransferMaskDocumentNumber((string)($draft['document_number'] ?? '')), ENT_QUOTES, 'UTF-8') . "\n"
            . "• <b>Document Front:</b> {$frontStatus}\n"
            . "• <b>Document Back:</b> {$backStatus}\n"
            . "• <b>Selfie:</b> {$selfieStatus}\n"
            . "• <b>Video Verification:</b> {$videoStatus}\n\n"
            . "⚠️ <b>Declaration:</b> By proceeding, you confirm that all provided information is accurate and complete. "
            . "Providing false or misleading information may result in the rejection of your request.";
    }
}

if (!function_exists('botValidateIntTransferFullName')) {
    function botValidateIntTransferFullName(string $value): bool
    {
        $value = trim($value);
        return mb_strlen($value) >= 3;
    }
}

if (!function_exists('botValidateIntTransferDob')) {
    function botValidateIntTransferDob(string $value): bool
    {
        $value = trim($value);
        if (!preg_match('/^(\d{2})\/(\d{2})\/(\d{4})$/', $value, $matches)) {
            return false;
        }

        return checkdate((int)$matches[2], (int)$matches[1], (int)$matches[3]);
    }
}

if (!function_exists('botValidateIntTransferSimpleText')) {
    function botValidateIntTransferSimpleText(string $value, int $minLength = 2): bool
    {
        return mb_strlen(trim($value)) >= $minLength;
    }
}

if (!function_exists('botValidateIntTransferAmount')) {
    function botValidateIntTransferAmount(string $value): bool
    {
        $normalized = str_replace([',', ' '], ['', ''], trim($value));
        return is_numeric($normalized) && (float)$normalized > 0;
    }
}

if (!function_exists('botPromptIntTransferVerificationStart')) {
    function botPromptIntTransferVerificationStart(array &$states, string $stateFile, $chatId): void
    {
        botIntTransferClearDraft($states, $stateFile, $chatId);
        botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_INTRO');

        $message = "🌍 <b>International Transfer Service Activation</b>\n\n"
            . "Thank you for your interest in activating International Transfer services with FinoviaPay.\n\n"
            . "For your security and to comply with international regulatory requirements, this service is not enabled by default.\n\n"
            . "Before activation, all customers are required to complete a mandatory verification process, which includes:\n\n"
            . "• Basic AML information\n"
            . "• Identity document verification\n"
            . "• Short video identity confirmation\n\n"
            . "⏱ <b>Estimated completion time:</b> 2–3 minutes\n"
            . "🕒 <b>Review time:</b> 24–72 hours\n\n"
            . "Please choose an option below to proceed.";

        sendMessage($chatId, $message, [
            'inline_keyboard' => [
                [['text' => '✅ Continue Verification', 'callback_data' => 'int_transfer_continue_verification']],
                [['text' => '❌ Cancel', 'callback_data' => 'int_transfer_cancel_verification']],
            ],
        ]);
    }
}

if (!function_exists('botPromptIntTransferQuestion')) {
    function botPromptIntTransferQuestion(array &$states, string $stateFile, $chatId, string $step): void
    {
        botIntTransferSetStep($states, $stateFile, $chatId, $step);

        switch ($step) {
            case 'INT_TRANSFER_VERIFY_FULL_NAME':
                sendMessage($chatId, "👤 <b>Full Name</b>\n\nPlease enter your full legal name exactly as it appears on your identification document.");
                return;

            case 'INT_TRANSFER_VERIFY_DOB':
                sendMessage($chatId, "📅 <b>Date of Birth</b>\n\nPlease enter your date of birth in the following format:\n\nDD/MM/YYYY");
                return;

            case 'INT_TRANSFER_VERIFY_COUNTRY':
                sendMessage($chatId, "🌍 <b>Country of Residence</b>\n\nPlease enter your current country of residence.");
                return;

            case 'INT_TRANSFER_VERIFY_NATIONALITY':
                sendMessage($chatId, "🪪 <b>Nationality</b>\n\nPlease specify your nationality as per your official identification.");
                return;

            case 'INT_TRANSFER_VERIFY_OCCUPATION':
                sendMessage($chatId, "💼 <b>Occupation</b>\n\nPlease provide your current occupation or employment status.");
                return;

            case 'INT_TRANSFER_VERIFY_SOURCE_OF_FUNDS':
                sendMessage($chatId, "💰 <b>Source of Funds</b>\n\nPlease specify the primary source of funds you intend to use for international transfers.\n\nExamples:\n• Salary / Employment Income\n• Business Income\n• Savings\n• Investments\n• Other (please specify)");
                return;

            case 'INT_TRANSFER_VERIFY_MONTHLY_VOLUME':
                sendMessage($chatId, "📊 <b>Expected Monthly Transfer Volume</b>\n\nPlease indicate your expected monthly transfer amount in EUR.\n\nExample: 500, 1000, 5000");
                return;

            case 'INT_TRANSFER_VERIFY_PURPOSE':
                sendMessage($chatId, "🎯 <b>Purpose of Transfers</b>\n\nPlease specify the main purpose of your international transfers.\n\nExamples:\n• Family Support\n• Personal Transfers\n• Business Payments\n• Education Expenses\n• Medical Support");
                return;

            case 'INT_TRANSFER_VERIFY_RELATIONSHIP':
                sendMessage($chatId, "🤝 <b>Beneficiary Relationship</b>\n\nPlease specify your relationship with the intended recipient(s).\n\nExamples:\n• Family Member\n• Personal Contact\n• Business Partner\n• Own Account");
                return;

            case 'INT_TRANSFER_VERIFY_DOC_NUMBER':
                sendMessage($chatId, "🔢 <b>Document Number</b>\n\nPlease enter your identification document number exactly as shown on your document.");
                return;

            case 'INT_TRANSFER_VERIFY_DOC_FRONT':
                sendMessage($chatId, "📸 <b>Document Upload – Front Side</b>\n\nPlease upload a clear image of the front side of your identification document.\n\nEnsure:\n• All text is readable\n• No glare or blur\n• Full document is visible");
                return;

            case 'INT_TRANSFER_VERIFY_DOC_BACK':
                sendMessage($chatId, "📸 <b>Document Upload – Back Side</b>\n\nPlease upload a clear image of the back side of your identification document.\n\nIf your document does not have a back side, you may upload the same document again for record purposes.");
                return;

            case 'INT_TRANSFER_VERIFY_SELFIE':
                sendMessage($chatId, "🤳 <b>Identity Confirmation</b>\n\nPlease upload a selfie holding your identification document.\n\nThis step is optional but recommended to help speed up your verification process.", botIntTransferSelfieKeyboard());
                return;

            case 'INT_TRANSFER_VERIFY_VIDEO':
                sendMessage($chatId, "🎥 <b>Video Verification Required</b>\n\nPlease record and upload a short video for identity confirmation.\n\n<b>Instructions:</b>\n• Your face must be clearly visible\n• Do not wear sunglasses, cap, or face covering\n• Hold your identification document in your hand\n• Clearly state the following:\n\n\"My name is [Your Name], today’s date is [DD/MM/YYYY], and I am submitting this verification for my FinoviaPay International Transfer activation.\"\n\nEnsure good lighting and a stable recording.\n\nThis step is mandatory for security verification.");
                return;

            default:
                sendMessage($chatId, "Unable to continue the verification flow at this stage. Please restart your request.", botIntTransferVerificationKeyboard());
                return;
        }
    }
}

if (!function_exists('botHandleIntTransferCallback')) {
    function botHandleIntTransferCallback(PDO $pdo, array &$states, string $stateFile, $chatId, string $callbackData): bool
    {
        switch ($callbackData) {
            case 'int_transfer_management_menu':
                botShowIntTransferManagementMenu($pdo, $states, $stateFile, $chatId);
                return true;

            case 'int_transfer_start_verification':
                botPromptIntTransferVerificationStart($states, $stateFile, $chatId);
                return true;

            case 'int_transfer_continue_verification':
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_FULL_NAME');
                return true;

            case 'int_transfer_verification_status':
                botShowIntTransferVerificationStatus($pdo, $states, $chatId);
                return true;

            case 'int_transfer_help':
                botShowIntTransferHelp($chatId);
                return true;

            case 'int_transfer_cancel_verification':
                botIntTransferResetVerificationSession($states, $stateFile, $chatId);
                sendMessage($chatId, "Your International Transfer verification session has been cancelled.", botIntTransferVerificationKeyboard());
                return true;

            case 'int_transfer_restart_verification':
                botPromptIntTransferVerificationStart($states, $stateFile, $chatId);
                return true;

            case 'int_transfer_pep_yes':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'is_pep', 'yes');
                sendMessage($chatId, "⚠️ <b>Third-Party Transactions</b>\n\nAre you acting on behalf of another individual or entity for these transfers?", botIntTransferYesNoKeyboard('int_transfer_third_party_yes', 'int_transfer_third_party_no'));
                botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_THIRD_PARTY_CALLBACK');
                return true;

            case 'int_transfer_pep_no':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'is_pep', 'no');
                sendMessage($chatId, "⚠️ <b>Third-Party Transactions</b>\n\nAre you acting on behalf of another individual or entity for these transfers?", botIntTransferYesNoKeyboard('int_transfer_third_party_yes', 'int_transfer_third_party_no'));
                botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_THIRD_PARTY_CALLBACK');
                return true;

            case 'int_transfer_third_party_yes':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'is_third_party', 'yes');
                sendMessage($chatId, "📜 <b>Source of Funds Declaration</b>\n\nDo you confirm that all funds used for international transfers are obtained from legal and verifiable sources?", botIntTransferYesNoKeyboard('int_transfer_legal_funds_yes', 'int_transfer_legal_funds_no'));
                botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_LEGAL_FUNDS_CALLBACK');
                return true;

            case 'int_transfer_third_party_no':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'is_third_party', 'no');
                sendMessage($chatId, "📜 <b>Source of Funds Declaration</b>\n\nDo you confirm that all funds used for international transfers are obtained from legal and verifiable sources?", botIntTransferYesNoKeyboard('int_transfer_legal_funds_yes', 'int_transfer_legal_funds_no'));
                botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_LEGAL_FUNDS_CALLBACK');
                return true;

            case 'int_transfer_legal_funds_yes':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'legal_funds_confirmed', 'yes');
                sendMessage($chatId, "🌐 <b>Transfer Experience</b>\n\nHave you previously used international banking or remittance services?", botIntTransferYesNoKeyboard('int_transfer_experience_yes', 'int_transfer_experience_no'));
                botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_TRANSFER_EXPERIENCE_CALLBACK');
                return true;

            case 'int_transfer_legal_funds_no':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'legal_funds_confirmed', 'no');
                sendMessage($chatId, "🌐 <b>Transfer Experience</b>\n\nHave you previously used international banking or remittance services?", botIntTransferYesNoKeyboard('int_transfer_experience_yes', 'int_transfer_experience_no'));
                botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_TRANSFER_EXPERIENCE_CALLBACK');
                return true;

            case 'int_transfer_experience_yes':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'prior_transfer_experience', 'yes');
                sendMessage($chatId, "🪪 <b>Identity Verification</b>\n\nPlease select the type of identification document you would like to submit.\n\nEnsure that the document is valid and clearly visible.", botIntTransferDocTypeKeyboard());
                botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_DOC_TYPE_CALLBACK');
                return true;

            case 'int_transfer_experience_no':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'prior_transfer_experience', 'no');
                sendMessage($chatId, "🪪 <b>Identity Verification</b>\n\nPlease select the type of identification document you would like to submit.\n\nEnsure that the document is valid and clearly visible.", botIntTransferDocTypeKeyboard());
                botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_DOC_TYPE_CALLBACK');
                return true;

            case 'int_transfer_doc_type_national_id_card':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'document_type', 'National ID Card');
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_DOC_NUMBER');
                return true;

            case 'int_transfer_doc_type_passport':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'document_type', 'Passport');
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_DOC_NUMBER');
                return true;

            case 'int_transfer_doc_type_residence_permit':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'document_type', 'Residence Permit');
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_DOC_NUMBER');
                return true;

            case 'int_transfer_skip_selfie':
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'selfie_file_id', '');
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_VIDEO');
                return true;

            case 'int_transfer_submit_verification':
                return botSubmitIntTransferVerification($pdo, $states, $stateFile, $chatId);

            case 'int_transfer_make_transfer':
            case 'int_transfer_limits':
            case 'int_transfer_history':
            case 'int_transfer_status':
                sendMessage($chatId, "This menu section will be activated in the next development phase. Your verification foundation is ready.", botIntTransferFullServiceKeyboard());
                return true;
        }

        return false;
    }
}

if (!function_exists('botSubmitIntTransferVerification')) {
    function botSubmitIntTransferVerification(PDO $pdo, array &$states, string $stateFile, $chatId): bool
    {
        $state = $states[$chatId] ?? [];
        $userId = botIntTransferResolveUserId($state);
        if ($userId <= 0) {
            sendMessage($chatId, "We were unable to identify your FinoviaPay customer profile for this verification request. Please return to the customer banking menu and try again.");
            return true;
        }

        $draft = botIntTransferGetDraft($states, $chatId);
        $required = [
            'full_name', 'date_of_birth', 'country_of_residence', 'nationality', 'occupation',
            'source_of_funds', 'expected_monthly_volume_eur', 'transfer_purpose', 'beneficiary_relationship',
            'is_pep', 'is_third_party', 'legal_funds_confirmed', 'prior_transfer_experience',
            'document_type', 'document_number', 'document_front_file_id', 'document_back_file_id', 'video_file_id',
        ];

        foreach ($required as $key) {
            if (!isset($draft[$key]) || trim((string)$draft[$key]) === '') {
                sendMessage($chatId, "Your verification form is incomplete. Please restart the verification process and complete all required steps.", botIntTransferReviewKeyboard());
                return true;
            }
        }

        $reference = botIntTransferGenerateReference();
        $pdo->beginTransaction();

        try {
            $sql = "INSERT INTO bot_int_transfer_verifications (
                        user_id, reference_code,
                        full_name, date_of_birth, country_of_residence, nationality, occupation,
                        source_of_funds, expected_monthly_volume_eur, transfer_purpose, beneficiary_relationship,
                        is_pep, is_third_party, legal_funds_confirmed, prior_transfer_experience,
                        document_type, document_number,
                        document_front_file_id, document_front_file_path,
                        document_back_file_id, document_back_file_path,
                        selfie_file_id, selfie_file_path,
                        video_file_id, video_file_path,
                        status, service_enabled, all_required_data_completed, created_at
                    ) VALUES (
                        :user_id, :reference_code,
                        :full_name, :date_of_birth, :country_of_residence, :nationality, :occupation,
                        :source_of_funds, :expected_monthly_volume_eur, :transfer_purpose, :beneficiary_relationship,
                        :is_pep, :is_third_party, :legal_funds_confirmed, :prior_transfer_experience,
                        :document_type, :document_number,
                        :document_front_file_id, :document_front_file_path,
                        :document_back_file_id, :document_back_file_path,
                        :selfie_file_id, :selfie_file_path,
                        :video_file_id, :video_file_path,
                        'PENDING_REVIEW', 0, 1, NOW()
                    )";

            $stmt = $pdo->prepare($sql);
            $stmt->execute([
                ':user_id' => $userId,
                ':reference_code' => $reference,
                ':full_name' => (string)$draft['full_name'],
                ':date_of_birth' => (string)$draft['date_of_birth'],
                ':country_of_residence' => (string)$draft['country_of_residence'],
                ':nationality' => (string)$draft['nationality'],
                ':occupation' => (string)$draft['occupation'],
                ':source_of_funds' => (string)$draft['source_of_funds'],
                ':expected_monthly_volume_eur' => (float)$draft['expected_monthly_volume_eur'],
                ':transfer_purpose' => (string)$draft['transfer_purpose'],
                ':beneficiary_relationship' => (string)$draft['beneficiary_relationship'],
                ':is_pep' => (string)$draft['is_pep'],
                ':is_third_party' => (string)$draft['is_third_party'],
                ':legal_funds_confirmed' => (string)$draft['legal_funds_confirmed'],
                ':prior_transfer_experience' => (string)$draft['prior_transfer_experience'],
                ':document_type' => (string)$draft['document_type'],
                ':document_number' => (string)$draft['document_number'],
                ':document_front_file_id' => (string)($draft['document_front_file_id'] ?? ''),
                ':document_front_file_path' => (string)($draft['document_front_file_path'] ?? ''),
                ':document_back_file_id' => (string)($draft['document_back_file_id'] ?? ''),
                ':document_back_file_path' => (string)($draft['document_back_file_path'] ?? ''),
                ':selfie_file_id' => (string)($draft['selfie_file_id'] ?? ''),
                ':selfie_file_path' => (string)($draft['selfie_file_path'] ?? ''),
                ':video_file_id' => (string)($draft['video_file_id'] ?? ''),
                ':video_file_path' => (string)($draft['video_file_path'] ?? ''),
            ]);

            $verificationId = (int)$pdo->lastInsertId();

            $historySql = "INSERT INTO bot_int_transfer_verification_status_history (
                                verification_id, status_code, status_title, remarks, changed_by, created_at
                           ) VALUES (
                                :verification_id, 'PENDING_REVIEW', 'Verification Submitted', :remarks, 'BOT', NOW()
                           )";
            $historyStmt = $pdo->prepare($historySql);
            $historyStmt->execute([
                ':verification_id' => $verificationId,
                ':remarks' => 'International Transfer verification request submitted by customer through Telegram bot.',
            ]);

            $pdo->commit();
        } catch (Throwable $e) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }
            sendMessage($chatId, "We were unable to submit your verification request at the moment. Please try again.");
            return true;
        }

        $emailSent = botIntTransferSendSubmissionEmail($pdo, $userId, $draft, $reference);

        botIntTransferResetVerificationSession($states, $stateFile, $chatId);

        $message = "✅ <b>Verification Submitted Successfully</b>\n\n"
            . "Dear Customer,\n\n"
            . "Your International Transfer verification request has been submitted successfully.\n\n"
            . "📌 <b>Reference ID:</b> " . htmlspecialchars($reference, ENT_QUOTES, 'UTF-8') . "\n"
            . "📅 <b>Submission Date:</b> " . htmlspecialchars(date('d/m/Y H:i'), ENT_QUOTES, 'UTF-8') . "\n\n"
            . "Our compliance team will review your request within 24–72 hours.\n\n"
            . ($emailSent
                ? "A confirmation email has also been sent to your registered email address.\n\n"
                : "We were unable to send the confirmation email at this moment, however your verification request has been received successfully.\n\n")
            . "You will be notified once your verification has been completed.\n\n"
            . "— FinoviaPay Compliance Department\nWorldwide Digital Internet Banking";

        sendMessage($chatId, $message, botIntTransferSubmittedKeyboard());
        return true;
    }
}

if (!function_exists('botHandleIntTransferUploads')) {
    function botHandleIntTransferUploads(array &$states, string $stateFile, array $update, $chatId): bool
    {
        $currentStep = (string)($states[$chatId]['step'] ?? '');
        if ($currentStep === '') {
            return false;
        }

        $message = $update['message'] ?? [];
        $photos = $message['photo'] ?? [];
        $video = $message['video'] ?? null;

        if ($currentStep === 'INT_TRANSFER_VERIFY_DOC_FRONT') {
            if (!is_array($photos) || empty($photos)) {
                sendMessage($chatId, "Please upload a clear image of the front side of your identification document.");
                return true;
            }
            $file = end($photos);
            $fileId = (string)($file['file_id'] ?? '');
            if ($fileId === '') {
                sendMessage($chatId, "We were unable to read the uploaded image. Please upload the document again.");
                return true;
            }
            $saved = botIntTransferDownloadTelegramFile($fileId, 'doc_front');
            botIntTransferSaveDraftField($states, $stateFile, $chatId, 'document_front_file_id', $fileId);
            botIntTransferSaveDraftField($states, $stateFile, $chatId, 'document_front_file_path', (string)($saved['relative_path'] ?? ''));
            botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_DOC_BACK');
            return true;
        }

        if ($currentStep === 'INT_TRANSFER_VERIFY_DOC_BACK') {
            if (!is_array($photos) || empty($photos)) {
                sendMessage($chatId, "Please upload a clear image of the back side of your identification document.");
                return true;
            }
            $file = end($photos);
            $fileId = (string)($file['file_id'] ?? '');
            if ($fileId === '') {
                sendMessage($chatId, "We were unable to read the uploaded image. Please upload the document again.");
                return true;
            }
            $saved = botIntTransferDownloadTelegramFile($fileId, 'doc_back');
            botIntTransferSaveDraftField($states, $stateFile, $chatId, 'document_back_file_id', $fileId);
            botIntTransferSaveDraftField($states, $stateFile, $chatId, 'document_back_file_path', (string)($saved['relative_path'] ?? ''));
            botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_SELFIE');
            return true;
        }

        if ($currentStep === 'INT_TRANSFER_VERIFY_SELFIE') {
            if (!is_array($photos) || empty($photos)) {
                sendMessage($chatId, "Please upload a selfie holding your identification document, or use the Skip Selfie option.", botIntTransferSelfieKeyboard());
                return true;
            }
            $file = end($photos);
            $fileId = (string)($file['file_id'] ?? '');
            if ($fileId === '') {
                sendMessage($chatId, "We were unable to read the uploaded image. Please upload the selfie again.", botIntTransferSelfieKeyboard());
                return true;
            }
            $saved = botIntTransferDownloadTelegramFile($fileId, 'selfie');
            botIntTransferSaveDraftField($states, $stateFile, $chatId, 'selfie_file_id', $fileId);
            botIntTransferSaveDraftField($states, $stateFile, $chatId, 'selfie_file_path', (string)($saved['relative_path'] ?? ''));
            botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_VIDEO');
            return true;
        }

        if ($currentStep === 'INT_TRANSFER_VERIFY_VIDEO') {
            if (!is_array($video) || empty($video)) {
                sendMessage($chatId, "Please upload your short video verification to continue.");
                return true;
            }
            $fileId = (string)($video['file_id'] ?? '');
            if ($fileId === '') {
                sendMessage($chatId, "We were unable to read the uploaded video. Please upload the video again.");
                return true;
            }
            $saved = botIntTransferDownloadTelegramFile($fileId, 'video');
            botIntTransferSaveDraftField($states, $stateFile, $chatId, 'video_file_id', $fileId);
            botIntTransferSaveDraftField($states, $stateFile, $chatId, 'video_file_path', (string)($saved['relative_path'] ?? ''));
            $draft = botIntTransferGetDraft($states, $chatId);
            botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_REVIEW');
            sendMessage($chatId, botBuildIntTransferReviewMessage($draft), botIntTransferReviewKeyboard());
            return true;
        }

        return false;
    }
}

if (!function_exists('botHandleIntTransferTextStep')) {
    function botHandleIntTransferTextStep(PDO $pdo, array &$states, string $stateFile, $chatId, string $text): bool
    {
        $text = trim($text);
        $step = (string)($states[$chatId]['step'] ?? '');
        if ($text === '' || $step === '') {
            return false;
        }

        switch ($step) {
            case 'INT_TRANSFER_VERIFY_FULL_NAME':
                if (!botValidateIntTransferFullName($text)) {
                    sendMessage($chatId, "Please enter a valid full legal name exactly as shown on your identification document.");
                    return true;
                }
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'full_name', $text);
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_DOB');
                return true;

            case 'INT_TRANSFER_VERIFY_DOB':
                if (!botValidateIntTransferDob($text)) {
                    sendMessage($chatId, "The date format appears incorrect. Please enter your date of birth as DD/MM/YYYY.");
                    return true;
                }
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'date_of_birth', $text);
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_COUNTRY');
                return true;

            case 'INT_TRANSFER_VERIFY_COUNTRY':
                if (!botValidateIntTransferSimpleText($text, 2)) {
                    sendMessage($chatId, "Please enter a valid country of residence.");
                    return true;
                }
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'country_of_residence', $text);
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_NATIONALITY');
                return true;

            case 'INT_TRANSFER_VERIFY_NATIONALITY':
                if (!botValidateIntTransferSimpleText($text, 2)) {
                    sendMessage($chatId, "Please enter a valid nationality.");
                    return true;
                }
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'nationality', $text);
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_OCCUPATION');
                return true;

            case 'INT_TRANSFER_VERIFY_OCCUPATION':
                if (!botValidateIntTransferSimpleText($text, 2)) {
                    sendMessage($chatId, "Please enter your current occupation or employment status.");
                    return true;
                }
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'occupation', $text);
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_SOURCE_OF_FUNDS');
                return true;

            case 'INT_TRANSFER_VERIFY_SOURCE_OF_FUNDS':
                if (!botValidateIntTransferSimpleText($text, 3)) {
                    sendMessage($chatId, "Please provide a valid source of funds.");
                    return true;
                }
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'source_of_funds', $text);
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_MONTHLY_VOLUME');
                return true;

            case 'INT_TRANSFER_VERIFY_MONTHLY_VOLUME':
                if (!botValidateIntTransferAmount($text)) {
                    sendMessage($chatId, "Please enter a valid expected monthly transfer amount in EUR. Example: 500 or 1000");
                    return true;
                }
                $normalized = str_replace([',', ' '], ['', ''], $text);
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'expected_monthly_volume_eur', number_format((float)$normalized, 2, '.', ''));
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_PURPOSE');
                return true;

            case 'INT_TRANSFER_VERIFY_PURPOSE':
                if (!botValidateIntTransferSimpleText($text, 3)) {
                    sendMessage($chatId, "Please provide the purpose of your international transfers.");
                    return true;
                }
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'transfer_purpose', $text);
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_RELATIONSHIP');
                return true;

            case 'INT_TRANSFER_VERIFY_RELATIONSHIP':
                if (!botValidateIntTransferSimpleText($text, 2)) {
                    sendMessage($chatId, "Please specify your relationship with the intended recipient.");
                    return true;
                }
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'beneficiary_relationship', $text);
                sendMessage($chatId, "⚖️ <b>Politically Exposed Person (PEP)</b>\n\nAre you or any of your close associates a politically exposed person?", botIntTransferYesNoKeyboard('int_transfer_pep_yes', 'int_transfer_pep_no'));
                botIntTransferSetStep($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_PEP_CALLBACK');
                return true;

            case 'INT_TRANSFER_VERIFY_DOC_NUMBER':
                if (!botValidateIntTransferSimpleText($text, 4)) {
                    sendMessage($chatId, "Please enter a valid identification document number exactly as shown on your document.");
                    return true;
                }
                botIntTransferSaveDraftField($states, $stateFile, $chatId, 'document_number', $text);
                botPromptIntTransferQuestion($states, $stateFile, $chatId, 'INT_TRANSFER_VERIFY_DOC_FRONT');
                return true;
        }

        return false;
    }
}
