<?php

namespace App\Console\Commands;

use App\Services\Paddle\PaddleClient;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;

class PaddleRegisterWebhooks extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'paddle:webhooks:register
        {--url= : Destination URL for Paddle webhooks}
        {--description= : Description for the webhook destination}
        {--events=* : Override event types to subscribe}
        {--traffic-source=all : platform|simulation|all}
        {--include-sensitive : Include sensitive fields in webhook payloads}
        {--show-secret : Output the endpoint secret key}
        {--dry-run : Output payload without creating the destination}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Register Paddle webhook notification settings.';

    /**
     * Execute the console command.
     */
    public function handle(PaddleClient $client): int
    {
        $destination = (string) ($this->option('url') ?: $this->defaultWebhookUrl());

        if ($destination === '') {
            $this->error('Webhook destination URL is required. Use --url=...');

            return self::FAILURE;
        }

        $events = collect((array) $this->option('events'))
            ->filter()
            ->map(fn ($event) => trim((string) $event))
            ->filter()
            ->values()
            ->all();

        if ($events === []) {
            $events = config('paddle.webhook_events', []);
        }

        if ($events === [] || ! is_array($events)) {
            $this->error('No webhook events configured. Set config(paddle.webhook_events) or pass --events.');

            return self::FAILURE;
        }

        $trafficSource = (string) $this->option('traffic-source');
        $allowedSources = ['platform', 'simulation', 'all'];

        if (! in_array($trafficSource, $allowedSources, true)) {
            $this->error(sprintf('Invalid traffic source. Use one of: %s', implode(', ', $allowedSources)));

            return self::FAILURE;
        }

        $payload = [
            'type' => 'url',
            'destination' => $destination,
            'description' => $this->resolveDescription(),
            'subscribed_events' => $events,
            'traffic_source' => $trafficSource,
            'include_sensitive_fields' => (bool) $this->option('include-sensitive'),
        ];

        if ((bool) $this->option('dry-run')) {
            $this->line(json_encode($payload, JSON_PRETTY_PRINT));

            return self::SUCCESS;
        }

        $response = $client->post('/notification-settings', $payload);
        $data = Arr::get($response, 'data', $response);
        $id = Arr::get($data, 'id');
        $secret = Arr::get($data, 'endpoint_secret_key');

        Log::channel('paddle-sync')->info('Paddle webhook registered', [
            'notification_setting_id' => $id,
            'destination' => $destination,
            'traffic_source' => $trafficSource,
        ]);

        $this->info('Paddle webhook registered.');

        if ($id) {
            $this->line('ID: '.$id);
        }

        if ($secret && $this->option('show-secret')) {
            $this->line('Secret: '.$secret);
        } elseif ($secret) {
            $this->line('Secret returned (hidden). Use --show-secret to display.');
        }

        return self::SUCCESS;
    }

    protected function defaultWebhookUrl(): string
    {
        $base = rtrim((string) config('app.url'), '/');

        return $base !== '' ? $base.'/paddle/webhook' : '';
    }

    protected function resolveDescription(): string
    {
        $description = (string) $this->option('description');

        if ($description !== '') {
            return $description;
        }

        $environment = (string) config('paddle.environment', 'production');

        return sprintf('Fotospiel Paddle webhooks (%s)', $environment);
    }
}
