<?php

declare(strict_types=1);

use Bot\Domain\Service\AdminService;
use Bot\Domain\Service\AnalyticsService;
use Bot\Domain\Service\PaymentService;
use Bot\Domain\Service\UserService;
use Bot\Infrastructure\Logging\SimpleLogger;
use Bot\Infrastructure\Payment\NextPayGateway;
use Bot\Infrastructure\Payment\ZarinPalGateway;
use SergiX44\Nutgram\Nutgram;

/**
 * هندلرهای پرداخت
 */
function registerPaymentHandlers(
    Nutgram $bot,
    UserService $userService,
    PaymentService $paymentService,
    AnalyticsService $analyticsService,
    string $nextpayApiKey,
    string $zarinpalMerchantId,
    bool $zarinpalSandbox,
    string $paymentCallbackBaseUrl,
    AdminService $adminService,
    ?int $ownerTelegramId,
): void {
    // هندلر PreCheckoutQuery برای بررسی قبل از پرداخت
    $bot->onPreCheckoutQuery(function (Nutgram $bot) use ($paymentService) {
        $preCheckoutQuery = $bot->preCheckoutQuery();
        if ($preCheckoutQuery === null) {
            return;
        }

        $payload = $preCheckoutQuery->invoice_payload ?? '';
        $payment = $paymentService->findByPayload($payload);

        // اگر payment پیدا نشد یا قبلاً پرداخت شده است
        if ($payment === null) {
            $bot->answerPreCheckoutQuery(
                ok: false,
                error_message: 'پرداخت یافت نشد. لطفاً دوباره تلاش کنید.',
            );
            return;
        }

        if ($payment->getStatus() !== 'pending') {
            $bot->answerPreCheckoutQuery(
                ok: false,
                error_message: 'این پرداخت قبلاً پردازش شده است.',
            );
            return;
        }

        // بررسی مبلغ
        $expectedAmount = $payment->getAmount();
        $actualAmount = $preCheckoutQuery->total_amount ?? 0;

        if ($actualAmount !== $expectedAmount) {
            $bot->answerPreCheckoutQuery(
                ok: false,
                error_message: 'مبلغ پرداخت با مبلغ مورد انتظار مطابقت ندارد.',
            );
            return;
        }

        // تأیید پرداخت
        $bot->answerPreCheckoutQuery(ok: true);
    });

    // هندلر SuccessfulPayment برای پرداخت موفق
    $bot->onSuccessfulPayment(function (Nutgram $bot) use (
        $userService,
        $paymentService,
        $analyticsService,
    ) {
        $from = $bot->user();
        if ($from === null) {
            return;
        }

        $telegramId = (int) $from->id;
        $successfulPayment = $bot->message()?->successful_payment;

        if ($successfulPayment === null) {
            return;
        }

        $payload = $successfulPayment->invoice_payload ?? '';
        $payment = $paymentService->findByPayload($payload);

        if ($payment === null) {
            $bot->sendMessage("خطا در پردازش پرداخت. لطفاً با پشتیبانی تماس بگیرید.");
            return;
        }

        // ثبت پرداخت موفق
        try {
            $externalId = $successfulPayment->telegram_payment_charge_id ?? '';
            $paymentService->markSuccess($payment, $externalId);

            // ارتقا کاربر به پریمیوم
            $user = $userService->getOrCreateByTelegramId($telegramId);
            $userService->upgradeToPremium($user);

            // ثبت آنالیتیکس
            $analyticsService->recordPayment($user->getId(), $payment->getId());

            SimpleLogger::info('پرداخت Telegram Stars موفق', [
                'user_id' => $user->getId(),
                'telegram_id' => $telegramId,
                'payment_id' => $payment->getId(),
                'external_id' => $externalId,
            ]);
        } catch (Throwable $e) {
            SimpleLogger::error('خطا در پردازش پرداخت Telegram Stars', [
                'telegram_id' => $telegramId,
                'error' => $e->getMessage(),
            ]);
            $bot->sendMessage("خطا در پردازش پرداخت. لطفاً با پشتیبانی تماس بگیرید.");
            return;
        }

        $bot->sendMessage(
            "پرداخت با موفقیت انجام شد! ✅" . PHP_EOL .
            "حساب شما به پریمیوم ارتقا یافت. 🎉" . PHP_EOL .
            "اکنون می‌توانید از دانلود نامحدود استفاده کنید."
        );
    });

    // دستور /premium - هدایت به منوی پرداخت
    $bot->onCommand('premium', function (Nutgram $bot) use (
        $userService,
        $adminService,
        $ownerTelegramId,
    ) {
        $from = $bot->user();
        if ($from === null) {
            return;
        }

        $telegramId = (int) $from->id;
        $user = $userService->getOrCreateByTelegramId($telegramId);
        $isAdmin = ($ownerTelegramId !== null && $telegramId === $ownerTelegramId) 
            || $adminService->getByTelegramId($telegramId) !== null;

        if ($user->getMode() === 'premium') {
            $bot->sendMessage("شما قبلاً حساب پریمیوم دارید! 🎉");
            return;
        }

        $bot->sendMessage(
            '⭐ ارتقا به حساب پریمیوم' . PHP_EOL . PHP_EOL .
            'لطفاً روش پرداخت را انتخاب کنید:',
            reply_markup: buildPremiumMenu()
        );
    });

    // دستور /premium_nextpay برای پرداخت با NextPay (برای سازگاری با نسخه‌های قدیمی)
    $bot->onCommand('premium_nextpay', function (Nutgram $bot) use (
        $userService,
        $paymentService,
        $nextpayApiKey,
        $paymentCallbackBaseUrl,
    ) {
        if (empty($nextpayApiKey)) {
            $bot->sendMessage("درگاه NextPay پیکربندی نشده است.");
            return;
        }

        $from = $bot->user();
        if ($from === null) {
            return;
        }

        $telegramId = (int) $from->id;
        $user = $userService->getOrCreateByTelegramId($telegramId);

        if ($user->getMode() === 'premium') {
            $bot->sendMessage("شما قبلاً حساب پریمیوم دارید! 🎉");
            return;
        }

        // ایجاد پرداخت pending
        $premiumPrice = 500000; // 500,000 ریال = 50,000 تومان
        $orderId = 'premium_nextpay_' . $telegramId . '_' . time();
        $payment = $paymentService->createPending(
            $user,
            'nextpay',
            $premiumPrice,
            $orderId,
        );

        // ایجاد لینک پرداخت
        $nextpay = new NextPayGateway($nextpayApiKey);
        $callbackUrl = $paymentCallbackBaseUrl . '?gateway=nextpay';
        $result = $nextpay->createPayment($premiumPrice, $callbackUrl, $orderId);

        if (!$result['success']) {
            $bot->sendMessage("خطا در ایجاد لینک پرداخت: " . ($result['error'] ?? 'خطای نامشخص'));
            return;
        }

        $bot->sendMessage(
            "برای پرداخت و ارتقا به حساب پریمیوم، روی لینک زیر کلیک کنید:" . PHP_EOL .
            $result['url'] . PHP_EOL . PHP_EOL .
            "مبلغ: " . number_format($premiumPrice) . " ریال"
        );
    });

    // دستور /premium_zarinpal برای پرداخت با ZarinPal (برای سازگاری با نسخه‌های قدیمی)
    $bot->onCommand('premium_zarinpal', function (Nutgram $bot) use (
        $userService,
        $paymentService,
        $zarinpalMerchantId,
        $zarinpalSandbox,
        $paymentCallbackBaseUrl,
    ) {
        if (empty($zarinpalMerchantId)) {
            $bot->sendMessage("درگاه ZarinPal پیکربندی نشده است.");
            return;
        }

        $from = $bot->user();
        if ($from === null) {
            return;
        }

        $telegramId = (int) $from->id;
        $user = $userService->getOrCreateByTelegramId($telegramId);

        if ($user->getMode() === 'premium') {
            $bot->sendMessage("شما قبلاً حساب پریمیوم دارید! 🎉");
            return;
        }

        // ایجاد پرداخت pending
        $premiumPrice = 500000; // 500,000 ریال = 50,000 تومان
        $authority = 'premium_zarinpal_' . $telegramId . '_' . time();
        $payment = $paymentService->createPending(
            $user,
            'zarinpal',
            $premiumPrice,
            $authority,
        );

        // ایجاد لینک پرداخت
        $zarinpal = new ZarinPalGateway($zarinpalMerchantId, $zarinpalSandbox);
        $callbackUrl = $paymentCallbackBaseUrl . '?gateway=zarinpal';
        $result = $zarinpal->createPayment($premiumPrice, $callbackUrl, 'ارتقا به حساب پریمیوم');

        if (!$result['success']) {
            $bot->sendMessage("خطا در ایجاد لینک پرداخت: " . ($result['error'] ?? 'خطای نامشخص'));
            return;
        }

        // ذخیره authority واقعی در external_id برای استفاده در callback
        $realAuthority = $result['authority'] ?? '';
        if (!empty($realAuthority)) {
            $payment = $paymentService->findByPayload($authority);
            if ($payment !== null) {
                // ذخیره authority در external_id بدون تغییر status
                $paymentService->setExternalId($payment, $realAuthority);
            }
        }

        $bot->sendMessage(
            "برای پرداخت و ارتقا به حساب پریمیوم، روی لینک زیر کلیک کنید:" . PHP_EOL .
            $result['url'] . PHP_EOL . PHP_EOL .
            "مبلغ: " . number_format($premiumPrice) . " ریال"
        );
    });
}

