<?php

namespace App\Console\Commands;

use App\Notify\Dispatcher;
use App\Notify\Message;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

/**
 * Send a test message to a single channel or all of them.
 *
 *   php artisan notify:test                  # send to ALL enabled channels
 *   php artisan notify:test 3                # only channel id 3
 *   php artisan notify:test --severity=critical
 *   php artisan notify:test --type=telegram  # all telegram channels
 */
class NotifyTest extends Command
{
    protected $signature = 'notify:test
        {id? : Channel id (omit to send to all enabled)}
        {--type= : Filter by channel type}
        {--severity=info : critical|high|medium|low|info}
        {--title= : Custom title}
        {--body= : Custom body}';

    protected $description = 'Send a test notification through one or all channels.';

    public function handle(Dispatcher $dispatcher): int
    {
        $message = new Message(
            event:    'test',
            title:    $this->option('title') ?: 'Test notification from HostSeba AI Portal',
            body:     $this->option('body')
                      ?: "This is a delivery test for the notification system.\n"
                       . "If you received this, the channel is wired correctly.\n\n"
                       . "Time: " . now()->toDateTimeString(),
            severity: $this->option('severity'),
            url:      rtrim((string) config('app.url'), '/') . '/settings',
        );

        $q = DB::table('notification_channels')->where('enabled', true);
        if ($id = $this->argument('id'))   $q->where('id', $id);
        if ($t  = $this->option('type'))    $q->where('type', $t);

        $channels = $q->get();
        if ($channels->isEmpty()) {
            $this->error('No matching enabled channels.');
            return self::FAILURE;
        }

        // Bypass dispatcher's event-subscription filter — for tests we always
        // want delivery regardless of which events the channel subscribed to.
        $rows = [];
        foreach ($channels as $row) {
            $impl = Dispatcher::resolve($row->type);
            if (! $impl) { $this->warn("[{$row->type}] no impl"); continue; }
            $config = json_decode($row->config ?? '{}', true) ?: [];
            foreach ($config as $k => $v) {
                if (is_string($v) && str_starts_with($v, 'enc:')) {
                    try { $config[$k] = decrypt(substr($v, 4)); } catch (\Throwable) {}
                }
            }
            $r = $impl->send($config, $message);
            $tag = "{$row->id} {$row->label} ({$row->type})";
            if ($r['ok']) $this->info("✓ {$tag}");
            else          $this->error("✗ {$tag}: " . ($r['error'] ?? 'unknown error'));
            $rows[] = ['id' => $row->id, 'type' => $row->type, 'ok' => $r['ok'], 'error' => $r['error'] ?? ''];
        }

        return self::SUCCESS;
    }
}
