<?php

namespace Services;

use Libs\BashExecutor;

class TokenTransferService
{
    private string $easyCliPath;

    public function __construct(?string $easyCliPath = null)
    {
        $this->easyCliPath = $easyCliPath ?? dirname(__DIR__) . '/bin/easycli';
    }

    public function transferFrom(string $fromAddress, string $toAddress, string $tokenExternalId): array
    {
        $from = trim($fromAddress);
        $to = trim($toAddress);
        $token = trim($tokenExternalId);

        if ($from === '' || $to === '' || $token === '') {
            throw new \InvalidArgumentException('Parâmetros inválidos para transferência de token.');
        }

        if (!is_file($this->easyCliPath) || !is_executable($this->easyCliPath)) {
            throw new \RuntimeException('easycli executable not found or not executable');
        }

        $command = sprintf(
            '%s token transfer --to %s --token-id %s',
            escapeshellarg($this->easyCliPath),
            escapeshellarg($to),
            escapeshellarg($token)
        );

        $result = BashExecutor::run($command, 120);
        $stdout = trim((string)($result['output'] ?? ''));
        $stderr = trim((string)($result['error'] ?? ''));

        $combinedOutput = trim(implode("\n", array_filter([$stdout, $stderr])));

        if (($result['exitCode'] ?? 1) !== 0) {
            $message = $combinedOutput !== '' ? $combinedOutput : 'Unknown easycli error';
            throw new \RuntimeException('easycli transfer failed: ' . $message);
        }

        if ($combinedOutput !== '' && preg_match('/execution\s+reverted/i', $combinedOutput)) {
            throw new \RuntimeException('easycli transfer failed: ' . $combinedOutput);
        }

        $txHash = $this->extractHashFromOutput($combinedOutput);

        return [
            'output' => $stdout,
            'error' => $stderr,
            'tx_hash' => $txHash,
        ];
    }

    private function extractHashFromOutput(string $output): ?string
    {
        if ($output === '') {
            return null;
        }

        if (preg_match('/0x[a-fA-F0-9]{64}/', $output, $matches)) {
            return $matches[0];
        }

        return null;
    }
}
