<?php

namespace App\Providers;

use App\Domain\Identity\Services\PermissionService;
use App\Domain\Shared\Context\BranchContext;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        // One branch context per request — and per Livewire round-trip, since
        // each of those is its own request.
        $this->app->scoped(BranchContext::class);
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // Only for the 500-error handler's diagnostics. Left on unconditionally
        // it retains every statement of every request in memory for no benefit.
        if (config('app.debug')) {
            DB::enableQueryLog();
        }

        Gate::before(function ($user, $ability) {
            return app(PermissionService::class)->can($user, $ability) ?: null;
        });

        Blade::if('permission', function (string $permission) {
            $user = auth()->user();
            if (!$user) {
                return false;
            }
            return app(PermissionService::class)->can($user, $permission);
        });

        $this->configureRateLimiting();
    }

    private function configureRateLimiting(): void
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
        });

        RateLimiter::for('api-auth', function (Request $request) {
            return Limit::perMinute(10)->by($request->ip());
        });

        RateLimiter::for('api-otp', function (Request $request) {
            return Limit::perMinute(3)->by($request->input('phone', $request->ip()));
        });

        RateLimiter::for('api-payments', function (Request $request) {
            return Limit::perMinute(5)->by($request->user()?->id ?: $request->ip());
        });
    }
}
