<?php

namespace App\Providers;

use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;

class ModuleServiceProvider extends ServiceProvider
{
    /**
     * Active modules and their base paths. Add an entry here when a new
     * product module (Kitanikah, Event, ...) starts being developed.
     */
    protected array $modules = [
        'Pilkades',
    ];

    public function register(): void
    {
        //
    }

    public function boot(): void
    {
        foreach ($this->modules as $module) {
            $this->loadModuleMigrations($module);
            $this->loadModuleViews($module);
        }
    }

    /**
     * Registers each module's routes. MUST be called after the app's core
     * web.php/auth.php routes (see bootstrap/app.php's withRouting `then`
     * callback) — a module's public wildcard (e.g. Pilkades'
     * {kabupaten}/{kecamatan}/{desa}) has the same shape as many system
     * routes and would otherwise win the match if registered first.
     */
    public function registerModuleRoutes(): void
    {
        foreach ($this->modules as $module) {
            $this->loadModuleRoutes($module);
        }
    }

    protected function loadModuleMigrations(string $module): void
    {
        $path = database_path('migrations/'.strtolower($module));

        if (is_dir($path)) {
            $this->loadMigrationsFrom($path);
        }
    }

    protected function loadModuleRoutes(string $module): void
    {
        $basePath = app_path("Modules/{$module}/routes");

        // "api" MUST be registered before "public": the public wildcard
        // ({kabupaten}/{kecamatan}/{desa}) is also a 3-segment GET pattern,
        // and would otherwise swallow requests like GET /api/super-admin/...
        // (api, super-admin, kabupaten) as a desa lookup — a 404, not the
        // intended API route. Same class of bug as the verify-email route
        // collision found in Phase 11 testing.
        $apiFile = "{$basePath}/{$module}-api.php";

        if (file_exists($apiFile)) {
            Route::middleware('api')
                ->prefix('api')
                ->group($apiFile);
        }

        foreach (['admin', 'public'] as $type) {
            $file = "{$basePath}/{$module}-{$type}.php";

            if (file_exists($file)) {
                // Must be explicitly wrapped in the "web" group: loadRoutesFrom()
                // alone does not apply it, which silently disables
                // SubstituteBindings (no route-model-binding), session, and CSRF
                // for every module route — a bug that only surfaces as routes
                // receiving an empty, unpersisted model instance instead of a 404.
                Route::middleware('web')->group($file);
            }
        }
    }

    protected function loadModuleViews(string $module): void
    {
        $path = resource_path('views/modules/'.strtolower($module));

        if (is_dir($path)) {
            $this->loadViewsFrom($path, strtolower($module));
        }
    }
}
