<?php

declare(strict_types=1);

use Bot\Domain\Service\AdminService;
use Bot\Domain\Service\ForcedJoinChannelService;
use Bot\Domain\Service\MediaService;
use Bot\Domain\Service\UserService;
use Bot\Domain\Service\AdsService;
use Bot\Domain\ValueObject\MediaType;
use SergiX44\Nutgram\Nutgram;

/**
 * هندلر پردازش ورودی‌های کاربر بر اساس state
 */
function registerMessageInputHandler(
    Nutgram $bot,
    UserService $userService,
    AdminService $adminService,
    MediaService $mediaService,
    AdsService $adsService,
    ?int $ownerTelegramId,
    array &$userStates,
    ForcedJoinChannelService $forcedJoinChannelService,
): void {
    $bot->onMessage(function (Nutgram $bot) use (
        $userService,
        $adminService,
        $mediaService,
        $adsService,
        $ownerTelegramId,
        &$userStates,
        $forcedJoinChannelService,
    ) {
        $from = $bot->user();
        if ($from === null) {
            return;
        }

        $telegramId = (int) $from->id;
        $message = $bot->message();
        if ($message === null) {
            return;
        }

        // نادیده گرفتن پیام‌های command (مثل /start) - این‌ها باید توسط onCommand پردازش شوند
        $text = $message->text ?? '';
        if (!empty($text) && str_starts_with($text, '/')) {
            return; // این یک command است، به handler command برو
        }

        // بررسی state
        if (!isset($userStates[$telegramId])) {
            return; // state وجود ندارد، به handler بعدی برو
        }

        $state = $userStates[$telegramId];
        $text = $message->text ?? '';
        $chatId = $bot->chatId();
        $editMessageId = $state['edit_message_id'] ?? null;

        // اگر پیام مدیا است و state برای ورودی متنی است، نادیده بگیر
        if (!empty($message->photo) || $message->video !== null || $message->document !== null) {
            if (in_array($state['action'], ['add_admin', 'remove_admin', 'create_ad', 'set_autodelete', 'broadcast', 'forced_join:add'], true)) {
                return; // به handler آپلود مدیا برو
            }
        }

        // پردازش state
        switch ($state['action']) {
            case 'add_admin':
                if ($ownerTelegramId === null || $telegramId !== $ownerTelegramId) {
                    $responseText = "فقط مالک ربات می‌تواند ادمین اضافه کند.";
                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    unset($userStates[$telegramId]);
                    return;
                }

                $newAdminId = (int) $text;
                if ($newAdminId === 0) {
                    $responseText = "شناسه تلگرام معتبر نیست. لطفاً یک عدد معتبر ارسال کنید.";
                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    return;
                }

                $admin = $adminService->addAdmin($newAdminId);
                $responseText = "ادمین با شناسه {$newAdminId} اضافه شد. ✅";
                if ($editMessageId !== null && $chatId !== null) {
                    try {
                        $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                    } catch (Throwable) {
                        $bot->sendMessage($responseText);
                    }
                } else {
                    $bot->sendMessage($responseText);
                }
                unset($userStates[$telegramId]);
                break;

            case 'remove_admin':
                if ($ownerTelegramId === null || $telegramId !== $ownerTelegramId) {
                    $responseText = "فقط مالک ربات می‌تواند ادمین حذف کند.";
                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    unset($userStates[$telegramId]);
                    return;
                }

                $adminIdToRemove = (int) $text;
                if ($adminIdToRemove === 0) {
                    $responseText = "شناسه تلگرام معتبر نیست. لطفاً یک عدد معتبر ارسال کنید.";
                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    return;
                }

                $removed = $adminService->removeAdmin($adminIdToRemove);
                $responseText = $removed 
                    ? "ادمین با شناسه {$adminIdToRemove} حذف شد. ✅"
                    : "ادمین یافت نشد یا نمی‌توان owner را حذف کرد.";
                
                if ($editMessageId !== null && $chatId !== null) {
                    try {
                        $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                    } catch (Throwable) {
                        $bot->sendMessage($responseText);
                    }
                } else {
                    $bot->sendMessage($responseText);
                }
                unset($userStates[$telegramId]);
                break;

            case 'create_ad':
                // دریافت یا ایجاد admin (اگر owner است)
                $admin = getOrCreateAdmin($adminService, $telegramId, $ownerTelegramId);
                
                if ($admin === null) {
                    $responseText = "فقط ادمین‌ها می‌توانند تبلیغ ایجاد کنند.";
                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    unset($userStates[$telegramId]);
                    return;
                }

                if (empty($text)) {
                    $responseText = "متن تبلیغ نمی‌تواند خالی باشد.";
                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    return;
                }

                $ad = $adsService->createAd($admin->getId(), $text);
                $responseText = "تبلیغ با شناسه #{$ad->getId()} اضافه شد. ✅";
                if ($editMessageId !== null && $chatId !== null) {
                    try {
                        $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                    } catch (Throwable) {
                        $bot->sendMessage($responseText);
                    }
                } else {
                    $bot->sendMessage($responseText);
                }
                unset($userStates[$telegramId]);
                break;

            case 'set_autodelete':
                $mediaId = $state['data']['media_id'] ?? 0;
                $media = $mediaService->findById($mediaId);
                
                if ($media === null) {
                    $responseText = "مدیا یافت نشد.";
                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    unset($userStates[$telegramId]);
                    return;
                }

                $admin = $adminService->getByTelegramId($telegramId);
                if ($admin === null || $media->getOwnerAdminId() !== $admin->getId()) {
                    $responseText = "شما دسترسی به این مدیا ندارید.";
                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    unset($userStates[$telegramId]);
                    return;
                }

                $seconds = (int) $text;
                $media->setAutoDeleteSeconds($seconds > 0 ? $seconds : null);
                $mediaService->updateMedia($media);

                $responseText = $seconds > 0
                    ? "Auto-delete timer برای مدیا #{$mediaId} روی {$seconds} ثانیه تنظیم شد. ✅"
                    : "Auto-delete timer برای مدیا #{$mediaId} غیرفعال شد. ✅";
                
                if ($editMessageId !== null && $chatId !== null) {
                    try {
                        $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                    } catch (Throwable) {
                        $bot->sendMessage($responseText);
                    }
                } else {
                    $bot->sendMessage($responseText);
                }
                unset($userStates[$telegramId]);
                break;

            case 'broadcast':
                $target = $state['data']['target'] ?? 'all';
                
                if ($state['step'] === 1) {
                    // دریافت media_id
                    $mediaId = (int) $text;
                    if ($mediaId === 0) {
                        $bot->sendMessage("شناسه مدیا معتبر نیست. لطفاً یک عدد معتبر ارسال کنید.");
                        return;
                    }

                    $media = $mediaService->findById($mediaId);
                    if ($media === null) {
                        $bot->sendMessage("مدیا با شناسه {$mediaId} یافت نشد.");
                        unset($userStates[$telegramId]);
                        return;
                    }

                    if ($target === 'all') {
                        // ارسال به همه کاربران
                        $users = $userService->getAll();
                        $responseText = "شروع ارسال به " . count($users) . " کاربر...";
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                        
                        $sentCount = 0;
                        $failedCount = 0;
                        
                        foreach ($users as $user) {
                            try {
                                $caption = $media->getCaption();
                                switch ($media->getType()) {
                                    case MediaType::PHOTO->value:
                                        $bot->sendPhoto($media->getTelegramFileId(), chat_id: $user->getTelegramId(), caption: $caption);
                                        break;
                                    case MediaType::VIDEO->value:
                                        $bot->sendVideo($media->getTelegramFileId(), chat_id: $user->getTelegramId(), caption: $caption);
                                        break;
                                    case MediaType::DOCUMENT->value:
                                    default:
                                        $bot->sendDocument($media->getTelegramFileId(), chat_id: $user->getTelegramId(), caption: $caption);
                                        break;
                                }
                                $sentCount++;
                                usleep(50000); // 50ms
                            } catch (Throwable $e) {
                                $failedCount++;
                            }
                        }
                        
                        $responseText = "ارسال انجام شد! ✅" . PHP_EOL .
                            "موفق: {$sentCount}" . PHP_EOL .
                            "ناموفق: {$failedCount}";
                        
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        // نیاز به دریافت chat_id
                        $userStates[$telegramId] = ['action' => 'broadcast', 'step' => 2, 'data' => ['target' => $target, 'media_id' => $mediaId], 'edit_message_id' => $editMessageId];
                        $responseText = "لطفاً شناسه کانال/گروه را ارسال کنید:" . PHP_EOL . "(مثال: -1001234567890)";
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                        return;
                    }
                } elseif ($state['step'] === 2) {
                    // دریافت chat_id
                    $targetChatId = $text;
                    $mediaId = $state['data']['media_id'] ?? 0;
                    $media = $mediaService->findById($mediaId);
                    
                    if ($media === null) {
                        $responseText = "مدیا یافت نشد.";
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                        unset($userStates[$telegramId]);
                        return;
                    }

                    try {
                        $caption = $media->getCaption();
                        switch ($media->getType()) {
                            case MediaType::PHOTO->value:
                                $bot->sendPhoto($media->getTelegramFileId(), chat_id: $targetChatId, caption: $caption);
                                break;
                            case MediaType::VIDEO->value:
                                $bot->sendVideo($media->getTelegramFileId(), chat_id: $targetChatId, caption: $caption);
                                break;
                            case MediaType::DOCUMENT->value:
                            default:
                                $bot->sendDocument($media->getTelegramFileId(), chat_id: $targetChatId, caption: $caption);
                                break;
                        }
                        $responseText = "ارسال به {$targetChatId} انجام شد! ✅";
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                    } catch (Throwable $e) {
                        $responseText = "خطا در ارسال به {$targetChatId}: " . $e->getMessage();
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                    }
                }
                
                unset($userStates[$telegramId]);
                break;

            case 'forced_join:add':
                // بررسی دسترسی ادمین
                $isAdmin = ($ownerTelegramId !== null && $telegramId === $ownerTelegramId) 
                    || $adminService->getByTelegramId($telegramId) !== null;
                
                if (!$isAdmin) {
                    $responseText = "فقط ادمین‌ها می‌توانند کانال اجباری اضافه کنند.";
                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    unset($userStates[$telegramId]);
                    return;
                }

                $step = $state['step'] ?? 1;

                if ($step === 1) {
                    // مرحله 1: دریافت username یا chat_id
                    if (empty($text)) {
                        $responseText = "username یا chat_id کانال نمی‌تواند خالی باشد.";
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                        return;
                    }

                    // پاک کردن @ از ابتدای username
                    $channelUsername = ltrim($text, '@');
                    
                    // تشخیص نوع کانال (اگر با - شروع شود، احتمالاً chat_id است)
                    $channelType = 'channel';
                    if (str_starts_with($channelUsername, '-')) {
                        $channelType = 'group';
                    }

                    // اگر chat_id است، باید invite link را هم بگیریم
                    if (str_starts_with($channelUsername, '-')) {
                        // ذخیره username در state و رفتن به مرحله 2
                        $userStates[$telegramId] = [
                            'action' => 'forced_join:add',
                            'step' => 2,
                            'channel_username' => $channelUsername,
                            'channel_type' => $channelType,
                            'edit_message_id' => $editMessageId,
                        ];
                        
                        $responseText = "✅ شناسه کانال دریافت شد: {$channelUsername}" . PHP_EOL . PHP_EOL;
                        $responseText .= "حالا لطفاً invite link کانال را ارسال کنید:" . PHP_EOL;
                        $responseText .= "مثال: https://t.me/joinchat/xxxxx" . PHP_EOL . PHP_EOL;
                        $responseText .= "برای لغو، /cancel را ارسال کنید.";
                        
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                        return;
                    } else {
                        // اگر username است، مستقیماً ایجاد می‌کنیم
                        try {
                            $channel = $forcedJoinChannelService->createChannel($channelUsername, $channelType);
                            $responseText = "✅ کانال اجباری {$channelUsername} با موفقیت اضافه شد!";
                        } catch (\RuntimeException $e) {
                            $responseText = "❌ خطا: " . $e->getMessage();
                        } catch (\Throwable $e) {
                            $responseText = "❌ خطا در افزودن کانال: " . $e->getMessage();
                        }

                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                        unset($userStates[$telegramId]);
                        return;
                    }
                } elseif ($step === 2) {
                    // مرحله 2: دریافت invite link برای chat_id
                    if (empty($text)) {
                        $responseText = "invite link نمی‌تواند خالی باشد.";
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                        return;
                    }

                    // بررسی اینکه آیا لینک معتبر است
                    $inviteLink = trim($text);
                    if (!str_starts_with($inviteLink, 'https://t.me/joinchat/') && 
                        !str_starts_with($inviteLink, 'https://t.me/+') &&
                        !str_starts_with($inviteLink, 't.me/joinchat/') &&
                        !str_starts_with($inviteLink, 't.me/+')) {
                        $responseText = "❌ لینک دعوت معتبر نیست!" . PHP_EOL . PHP_EOL;
                        $responseText .= "لطفاً یک لینک دعوت معتبر ارسال کنید:" . PHP_EOL;
                        $responseText .= "مثال: https://t.me/joinchat/xxxxx یا https://t.me/+xxxxx";
                        if ($editMessageId !== null && $chatId !== null) {
                            try {
                                $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                            } catch (Throwable) {
                                $bot->sendMessage($responseText);
                            }
                        } else {
                            $bot->sendMessage($responseText);
                        }
                        return;
                    }

                    // اضافه کردن https:// اگر وجود نداشته باشد
                    if (!str_starts_with($inviteLink, 'http')) {
                        $inviteLink = 'https://' . $inviteLink;
                    }

                    $channelUsername = $state['channel_username'] ?? '';
                    $channelType = $state['channel_type'] ?? 'group';

                    try {
                        $channel = $forcedJoinChannelService->createChannel($channelUsername, $channelType, $inviteLink);
                        $responseText = "✅ کانال اجباری {$channelUsername} با invite link با موفقیت اضافه شد!";
                    } catch (\RuntimeException $e) {
                        $responseText = "❌ خطا: " . $e->getMessage();
                    } catch (\Throwable $e) {
                        $responseText = "❌ خطا در افزودن کانال: " . $e->getMessage();
                    }

                    if ($editMessageId !== null && $chatId !== null) {
                        try {
                            $bot->editMessageText($responseText, chat_id: $chatId, message_id: $editMessageId);
                        } catch (Throwable) {
                            $bot->sendMessage($responseText);
                        }
                    } else {
                        $bot->sendMessage($responseText);
                    }
                    unset($userStates[$telegramId]);
                    return;
                }
                break;
        }
    });
}

