<?php

namespace App\Providers;

use App\Hooks\HookManager;
use Illuminate\Support\ServiceProvider;

/**
 * Wires up the action / filter dispatcher.
 *
 *   - `register()` binds {@see HookManager} as a singleton so every
 *      call into `app(HookManager::class)` (and therefore every
 *      `do_action` / `apply_filters` helper) shares the same registry.
 *
 *   - `boot()` is where built-in listeners belong. Plugin packages get
 *      their own service providers; this one is reserved for the
 *      hooks that ship with core (e.g. audit-log defaults).
 */
class HookServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(HookManager::class, fn () => new HookManager());
    }

    public function boot(HookManager $hooks): void
    {
        // ── Admin bell notifications ──────────────────────────────────────
        // Each listener turns a domain event into a database notification for
        // super-admins. Failures here never break the originating operation —
        // HookManager catches listener exceptions.

        $hooks->addAction('updater.update_available', function ($version, $release = null) {
            $key = 'update_available:'.$version;
            if (! admins_have_unread_notification($key)) {
                notify_admins(
                    $key,
                    __('notifications.update.title'),
                    __('notifications.update.message', ['version' => $version]),
                    'download',
                    route('admin.settings.updates.index'),
                    'updater.check',
                );
            }
        });

        $hooks->addAction('backup.failed', function ($log = null, $e = null) {
            notify_admins(
                'backup_failed:'.(optional($log)->id ?? ''),
                __('notifications.backup.title'),
                __('notifications.backup.message'),
                'database',
                route('admin.settings.backup.edit'),
                'backup.run',
            );
        });

        $hooks->addAction('sale.after_void', function ($sale) {
            $number = $sale->number ?? $sale->sale_number ?? ('#'.$sale->id);
            notify_admins(
                'sale_voided:'.$sale->id,
                __('notifications.void.title'),
                __('notifications.void.message', ['number' => $number]),
                'refund',
                url('/admin/sales/'.$sale->id),
                'sales.view_all',
            );
        });

        $hooks->addAction('sale.after_return', function ($return) {
            $saleId = $return->sale_id ?? null;
            $number = optional($return->sale ?? null)->number ?? ('#'.($saleId ?? $return->id));
            notify_admins(
                'sale_returned:'.$return->id,
                __('notifications.return.title'),
                __('notifications.return.message', ['number' => $number]),
                'refund',
                $saleId ? url('/admin/sales/'.$saleId) : null,
                'sales.view_all',
            );
        });
    }
}
