<?php

declare(strict_types=1);

namespace Maestro\Core\Providers;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
use Maestro\Core\Console\Commands\CoreInstallCommand;
use Maestro\Core\Modules\Customers\Providers\CustomersModuleServiceProvider;
use Maestro\Core\Services\AutoSyncPackageStubs;
use Maestro\Core\Support\AuthUserResolver;

class CoreServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->mergeConfigFrom(__DIR__.'/../../config/core.php', 'core');
    }

    public function boot(): void
    {
        $this->bindUserRouteParameter();

        $this->loadModules();

        $this->loadMigrationsFrom(__DIR__.'/../../database/migrations');
        $this->loadRoutesFrom(__DIR__.'/../../routes/core.php');
        $this->loadViewsFrom(__DIR__.'/../../resources/views', 'maestro-core');

        if ($this->app->runningInConsole()) {
            (new AutoSyncPackageStubs)->syncIfStubsAreNewer();
            $this->commands([CoreInstallCommand::class]);
        }

        $this->publishes([
            __DIR__.'/../../config/core.php' => config_path('core.php'),
        ], 'core-config');
    }

    private function loadModules(): void
    {
        if (config('core.modules.customers') === true) {
            $this->app->register(CustomersModuleServiceProvider::class);
        }
    }

    /**
     * Ensure `api/users/{user}` resolves the same User class as login (auth.providers.users.model),
     * so Spatie pivots stay on a consistent `model_type`.
     *
     * Apps may override with their own Route::bind('user', ...) registered after this provider.
     */
    private function bindUserRouteParameter(): void
    {
        Route::bind('user', function (string $value): Model {
            $class = AuthUserResolver::eloquentModelClass();

            /** @var Model $model */
            $model = $class::query()->whereKey($value)->firstOrFail();

            return $model;
        });
    }
}
