<?php
namespace Bot\Commands\AdminCommands;

use Bot\Services\PaymentMethodService;
use Longman\TelegramBot\Commands\AdminCommand;
use Longman\TelegramBot\Entities\ServerResponse;
use Longman\TelegramBot\Request;

class AdminpayCommand extends AdminCommand
{
    protected $name = 'adminpay';
    protected $description = 'Manage payment methods';
    protected $usage = '/adminpay add <buy|sell>|Name|Instructions|[Contact]|[User prompt]';
    protected $version = '1.0.0';

    private PaymentMethodService $service;

    public function __construct($telegram, $update)
    {
        parent::__construct($telegram, $update);
        $this->service = new PaymentMethodService();
    }

    public function execute(): ServerResponse
    {
        $message = $this->getMessage();
        $text = trim($message->getText(true) ?? '');
        if ($text === '') {
            return $this->replyUsage();
        }
        [$command, $payload] = array_pad(explode(' ', $text, 2), 2, '');
        $command = strtolower($command);
        try {
            return match ($command) {
                'add'     => $this->handleAdd($payload),
                'edit'    => $this->handleEdit($payload),
                'enable'  => $this->handleToggle($payload, true),
                'disable' => $this->handleToggle($payload, false),
                'delete'  => $this->handleDelete($payload),
                'list'    => $this->handleList(),
                default   => $this->replyUsage(),
            };
        } catch (\Throwable $e) {
            return Request::sendMessage([
                'chat_id' => $message->getChat()->getId(),
                'text'    => 'Error: ' . $e->getMessage(),
            ]);
        }
    }

    private function handleAdd(string $payload): ServerResponse
    {
        [$direction, $name, $instructions, $contact, $prompt] = array_map(
            'trim',
            explode('|', $payload, 5) + ['', '', '', '', '']
        );
        if ($direction === '' || $name === '' || $instructions === '') {
            throw new \InvalidArgumentException('Usage: `/adminpay add buy|Name|Instructions|[Contact]|[User prompt]` ');
        }
        $direction = strtolower($direction) === 'sell' ? 'sell' : 'buy';
        $id = $this->service->create($name, $instructions, $contact, $direction, $prompt);
        return $this->sendAdminReply(sprintf('✅ Added payment method #%d (%s).', $id, $name));
    }

    private function handleEdit(string $payload): ServerResponse
    {
        [$id, $instructions, $contact, $direction, $prompt] = array_map(
            'trim',
            explode('|', $payload, 5) + ['', '', '', '', '']
        );
        if (!ctype_digit($id) || $instructions === '') {
            throw new \InvalidArgumentException('Usage: `/adminpay edit <id>|New instructions|[Contact]|[Direction]|[User prompt]` ');
        }
        $contactValue = $contact === '' ? null : $contact;
        $directionValue = $direction === '' ? null : (strtolower($direction) === 'sell' ? 'sell' : 'buy');
        $promptValue = $prompt === '' ? null : $prompt;
        $this->service->update((int) $id, $instructions, $contactValue, $directionValue, $promptValue);
        return $this->sendAdminReply('✅ Instructions updated.');
    }

    private function handleToggle(string $payload, bool $active): ServerResponse
    {
        $id = trim($payload);
        if (!ctype_digit($id)) {
            throw new \InvalidArgumentException('Usage: `/adminpay ' . ($active ? 'enable' : 'disable') . ' <id>` ');
        }
        $this->service->setActive((int) $id, $active);
        return $this->sendAdminReply($active ? 'Method enabled.' : 'Method disabled.');
    }

    private function handleDelete(string $payload): ServerResponse
    {
        $id = trim($payload);
        if (!ctype_digit($id)) {
            throw new \InvalidArgumentException('Usage: `/adminpay delete <id>` ');
        }
        $this->service->delete((int) $id);
        return $this->sendAdminReply('🔪 Method deleted.');
    }

    private function handleList(): ServerResponse
    {
        $methods = $this->service->getAll();
        if (!$methods) {
            return $this->sendAdminReply('🥺 No payment methods configured.');
        }
        $lines = [];
        foreach ($methods as $method) {
            $contactLine = $method['contact_details'] ? " Contact: {$method['contact_details']}" : '';
            $promptLine = $method['details_prompt'] ? " Prompt: {$method['details_prompt']}" : '';
            $lines[] = sprintf(
                '#%d %s (%s) [%s]%s %s',
                $method['id'],
                $method['name'],
                strtoupper($method['direction'] ?? 'buy'),
                $method['is_active'] ? 'active' : 'disabled',
                $contactLine,
                $promptLine
            );
        }
        return $this->sendAdminReply(implode("\n", $lines));
    }

    private function replyUsage(): ServerResponse
    {
        $text = "Payment method commands:\n" .
                " `/adminpay add buy|Name|Instructions|[Contact]|[User prompt]` \n" .
                " `/adminpay edit <id>|New instructions|[Contact]|[Direction]|[User prompt]` \n" .
                " `/adminpay enable <id>` \n" .
                " `/adminpay disable <id>` \n" .
                " `/adminpay delete <id>` \n" .
                " `/adminpay list` ";
        return $this->sendAdminReply($text);
    }

    private function sendAdminReply(string $text): ServerResponse
    {
        return Request::sendMessage([
            'chat_id' => $this->getMessage()->getChat()->getId(),
            'text'    => $text,
        ]);
    }
}
