<?php

declare(strict_types=1);

namespace ImovelZapAi\Conversations\Application\Actions;

use Illuminate\Support\Str;
use ImovelZapAi\Conversations\Application\Services\EvolutionApiClient;
use ImovelZapAi\Conversations\Domain\Enums\MessagingConnectionStatus;
use ImovelZapAi\Conversations\Domain\Enums\MessagingProvider;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\TenantMessagingConfigModel;
use ImovelZapAi\Tenancy\Infrastructure\Persistence\Eloquent\TenantModel;
use RuntimeException;

final class ConnectEvolutionInstanceAction
{
    public function __construct(
        private readonly EvolutionApiClient $evolution,
    ) {}

    /**
     * @return array{config: TenantMessagingConfigModel, qr_base64: ?string}
     */
    public function execute(string $tenantId): array
    {
        $apiKey = (string) config('conversations.evolution.api_key', '');
        $baseUrl = (string) config('conversations.evolution.base_url', '');

        if ($apiKey === '' || $baseUrl === '') {
            throw new RuntimeException(
                'Evolution API não configurada. Defina EVOLUTION_API_URL e EVOLUTION_API_KEY no .env.',
            );
        }

        $tenant = TenantModel::query()->findOrFail($tenantId);
        $instanceName = $this->buildInstanceName($tenant);
        $webhookUrl = $this->webhookUrl();

        $existing = TenantMessagingConfigModel::query()->where('tenant_id', $tenantId)->first();

        /** @var TenantMessagingConfigModel $config */
        $config = TenantMessagingConfigModel::query()->updateOrCreate(
            ['tenant_id' => $tenantId],
            [
                'provider' => MessagingProvider::Evolution,
                'instance_name' => $instanceName,
                'connection_status' => MessagingConnectionStatus::Connecting,
                'is_active' => true,
                'automation_enabled' => $existing?->automation_enabled ?? true,
            ],
        );

        if ($config->instance_token === null || $config->instance_token === '') {
            $config->update(['instance_token' => Str::random(32)]);
            $config->refresh();
        }

        // Cria (ou reaproveita) a instância e configura POST /webhook/set/{instance}.
        $this->evolution->createInstance($instanceName, $webhookUrl, $config->instance_token);
        $qr = $this->evolution->connectInstance($instanceName);

        $config->update([
            'connection_status' => MessagingConnectionStatus::Connecting,
        ]);

        return [
            'config' => $config->fresh() ?? $config,
            'qr_base64' => $qr['base64'],
        ];
    }

    private function buildInstanceName(TenantModel $tenant): string
    {
        $slug = Str::slug((string) $tenant->slug, '-');

        return 'tenant-'.($slug !== '' ? $slug : (string) $tenant->id);
    }

    private function webhookUrl(): string
    {
        $base = rtrim((string) config('conversations.evolution.webhook_base_url', ''), '/');
        $path = (string) config('conversations.evolution.webhook_path', '/api/webhooks/evolution');

        if ($path === '' || ! str_starts_with($path, '/')) {
            $path = '/'.ltrim($path, '/');
        }

        return $base.$path;
    }
}
