<?php

declare(strict_types=1);

namespace App\Scenario;

use App\Util\ParsedCommand;
use Pkirillw\MaxBotApi\Builder\Message as MessageBuilder;
use Pkirillw\MaxBotApi\Scheme\ChatPatch;
use Pkirillw\MaxBotApi\Scheme\Enum\Format;
use Pkirillw\MaxBotApi\Scheme\Enum\SenderAction;
use Pkirillw\MaxBotApi\Scheme\PinMessageBody;
use Pkirillw\MaxBotApi\Scheme\Update\MessageCreatedUpdate;
use Pkirillw\MaxBotApi\Scheme\UserIdsList;

final class ChatAdminScenario extends AbstractScenario
{
    public function handle(MessageCreatedUpdate $update, ParsedCommand $command): void
    {
        switch ($command->name) {
            case 'members':
                $this->listMembers($update, $command);
                return;
            case 'admins':
                $this->listAdmins($update, $command);
                return;
            case 'action':
                $this->sendAction($update, $command);
                return;
            case 'pin':
                $this->pinMessage($update, $command);
                return;
            case 'edit_chat':
                $this->editChat($update, $command);
                return;
            case 'add_member':
                $this->addMember($update, $command);
                return;
            case 'remove_member':
                $this->removeMember($update, $command);
                return;
            case 'leave':
                $this->leaveChat($update, $command);
                return;
        }
    }

    private function listMembers(MessageCreatedUpdate $update, ParsedCommand $command): void
    {
        $chatId = $command->argInt(0);
        if ($chatId <= 0) {
            $this->replyMarkdown($update, 'Usage: `/members <chatId>`');
            return;
        }
        $members = $this->api->chats->getChatMembers($chatId, count: 20);
        $lines = [];
        foreach ($members->members as $m) {
            $lines[] = sprintf('• %d %s @%s owner=%s admin=%s', $m->userId, $m->name, $m->username ?? '', $m->isOwner ? '✓' : '·', $m->isAdmin ? '✓' : '·');
        }
        $text = "*Members of $chatId*\n" . ($lines === [] ? '(empty)' : implode("\n", $lines));

        // Also demo getSpecificChatMembers + getChatAdmins.
        $userIds = array_slice(array_map(fn($m) => $m->userId, $members->members), 0, 3);
        $specificNote = '';
        if ($userIds !== []) {
            $specific = $this->api->chats->getSpecificChatMembers($chatId, $userIds);
            $specificNote = sprintf("\n\ngetSpecificChatMembers(%s): %d hit(s)", implode(',', $userIds), count($specific->members));
        }
        $admins = $this->api->chats->getChatAdmins($chatId);
        $adminNote = sprintf("\ngetChatAdmins(): %d admin(s)", count($admins->members));

        $this->api->messages->send(
            MessageBuilder::new()->setChat($update->getChatId())->setText($text . $specificNote . $adminNote)->setFormat(Format::Markdown),
        );
    }

    private function listAdmins(MessageCreatedUpdate $update, ParsedCommand $command): void
    {
        $chatId = $command->argInt(0);
        if ($chatId <= 0) {
            $this->replyMarkdown($update, 'Usage: `/admins <chatId>`');
            return;
        }
        $admins = $this->api->chats->getChatAdmins($chatId);
        $lines = [];
        foreach ($admins->members as $m) {
            $lines[] = sprintf('• %d %s (owner=%s)', $m->userId, $m->name, $m->isOwner ? '✓' : '·');
        }
        $this->replyMarkdown($update, "*Admins of $chatId*\n" . ($lines === [] ? '(none)' : implode("\n", $lines)));
    }

    private function sendAction(MessageCreatedUpdate $update, ParsedCommand $command): void
    {
        $chatId = $command->argInt(0);
        $actionStr = $command->arg(1);
        if ($chatId <= 0 || $actionStr === null) {
            $valid = implode(', ', array_map(fn($c) => $c->value, SenderAction::cases()));
            $this->replyMarkdown($update, "Usage: `/action <chatId> <$valid>`");
            return;
        }
        $action = SenderAction::tryFrom($actionStr);
        if ($action === null) {
            $this->replyMarkdown($update, "Unknown action `$actionStr`");
            return;
        }
        $this->api->chats->sendAction($chatId, $action);
        $this->replyMarkdown($update, "sendAction `$action->value` sent to `$chatId`");
    }

    private function pinMessage(MessageCreatedUpdate $update, ParsedCommand $command): void
    {
        $chatId = $command->argInt(0);
        $messageId = $command->arg(1);
        if ($chatId <= 0 || $messageId === null) {
            $this->replyMarkdown($update, 'Usage: `/pin <chatId> <messageId>`');
            return;
        }
        $this->api->chats->pinMessage($chatId, new PinMessageBody(messageId: $messageId, notify: true));
        $this->replyMarkdown($update, "Pinned `$messageId` in chat `$chatId`");
    }

    private function editChat(MessageCreatedUpdate $update, ParsedCommand $command): void
    {
        $chatId = $command->argInt(0);
        $title = $command->arg(1);
        if ($chatId <= 0 || $title === null) {
            $this->replyMarkdown($update, 'Usage: `/edit_chat <chatId> <newTitle>`');
            return;
        }
        $chat = $this->api->chats->editChat($chatId, new ChatPatch(title: $title));
        $this->replyMarkdown($update, "Chat `$chatId` title updated to *$chat->title*");
    }

    private function addMember(MessageCreatedUpdate $update, ParsedCommand $command): void
    {
        $chatId = $command->argInt(0);
        $userId = $command->argInt(1);
        if ($chatId <= 0 || $userId <= 0) {
            $this->replyMarkdown($update, 'Usage: `/add_member <chatId> <userId>`');
            return;
        }
        $result = $this->api->chats->addMember($chatId, new UserIdsList(userIds: [$userId]));
        $this->replyMarkdown($update, sprintf('addMember result: success=%s', $result->success ? 'true' : 'false'));
    }

    private function removeMember(MessageCreatedUpdate $update, ParsedCommand $command): void
    {
        $chatId = $command->argInt(0);
        $userId = $command->argInt(1);
        if ($chatId <= 0 || $userId <= 0) {
            $this->replyMarkdown($update, 'Usage: `/remove_member <chatId> <userId>`');
            return;
        }
        $result = $this->api->chats->removeMember($chatId, $userId);
        $this->replyMarkdown($update, sprintf('removeMember result: success=%s', $result->success ? 'true' : 'false'));
    }

    private function leaveChat(MessageCreatedUpdate $update, ParsedCommand $command): void
    {
        $chatId = $command->argInt(0);
        if ($chatId <= 0) {
            $this->replyMarkdown($update, 'Usage: `/leave <chatId>`');
            return;
        }
        $result = $this->api->chats->leaveChat($chatId);
        $this->replyMarkdown($update, sprintf('Left chat %d: success=%s', $chatId, $result->success ? 'true' : 'false'));
    }
}
