<?php

namespace App\Providers;

use App\Models\Creative;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use Livewire\Mechanisms\FrontendAssets\FrontendAssets;
use Livewire\Mechanisms\HandleRequests\HandleRequests;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        // Livewire's own getUpdateUri() always requests a domain-root-relative
        // path (Laravel's relative-URL generator strips any subdirectory the app
        // is served from), which breaks when the app is deployed under a URL
        // subpath (e.g. local dev at /php85/{user}/arb.admedia.com/public).
        // Forcing it absolute keeps the correct path in every environment,
        // subdirectory or domain root, with no per-environment config needed.
        //
        // NOTE: This override was originally added for subdirectory deployment.
        // After migrating to `artisan serve` at the domain root, verify if this
        // is still needed. If not, this override can be removed entirely.
        $this->app->extend(HandleRequests::class, function (HandleRequests $originalHandler) {
            // Create a new instance that extends HandleRequests, preserving
            // any properties that were set on the original handler by Livewire.
            $subclass = new class($originalHandler) extends HandleRequests
            {
                private HandleRequests $original;

                public function __construct(HandleRequests $original)
                {
                    $this->original = $original;
                    // Copy over any properties from the original instance
                    // (though in practice, Livewire hasn't set many at this point)
                    foreach (get_object_vars($original) as $key => $value) {
                        $this->{$key} = $value;
                    }
                }

                public function getUpdateUri()
                {
                    $route = $this->updateRoute ?? $this->findUpdateRoute();

                    return (string) app('url')->toRoute($route, [], true);
                }
            };

            return $subclass;
        });
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Paginator::useBootstrapFive();

        // Same subdirectory issue for the Livewire JS asset's <script src>:
        // it defaults to a bare "/livewire/livewire.js" (or .min.js in
        // production) unless this is set. Building it from the actual
        // registered route's URI + url() keeps it correct in any environment
        // (subdirectory in dev, plain domain in staging/prod) without
        // hardcoding the debug/production filename ourselves.
        if ($jsRoute = app(FrontendAssets::class)->javaScriptRoute) {
            config(['livewire.asset_url' => url('/'.ltrim($jsRoute->uri(), '/'))]);
        }

        // The AdStudio nav panel (recent creatives) is shared shell chrome, rendered on
        // every page via partials.mb.sidebar — a composer avoids threading this through
        // every page controller/Livewire component that renders the mb layout.
        View::composer('partials.mb.sidebar', function ($view) {
            $view->with('recentCreatives', auth()->check()
                ? auth()->user()->creatives()->latest()->limit(8)->get()
                : collect());
        });
    }
}
