<?php

namespace App\Providers;

use App\Channels\FcmChannel;
use App\Jobs\Middleware\InitializeTenantContext;
use App\Services\Menu\IMenuRegistrarService;
use App\Services\Menu\MenuRegistrarService;
use Illuminate\Notifications\ChannelManager;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Vite;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        if ($this->app->isProduction() || str_starts_with(config('app.url'), 'https')) {
            URL::forceScheme('https');
        }

        // Register AttendanceCalculationService as singleton
        // This service is used by scheduled commands, controllers, and models
        $this->app->singleton(\App\Services\AttendanceCalculationService::class);

        // Register MenuRegistrarService as singleton
        // This service collects menu items from all modules for dynamic rendering
        $this->app->singleton(IMenuRegistrarService::class, MenuRegistrarService::class);
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // Register model observers
        \App\Models\LeaveRequest::observe(\App\Observers\LeaveRequestObserver::class);

        // Register custom FCM notification channel
        Notification::resolved(function (ChannelManager $service) {
            $service->extend('fcm', function ($app) {
                return new FcmChannel(
                    $app->make(\App\Services\FcmNotificationService::class)
                );
            });
        });

        // Register queue tenant awareness
        $this->registerQueueTenantAwareness();

        Vite::useStyleTagAttributes(function (?string $src, string $url, ?array $chunk, ?array $manifest) {
            if ($src !== null) {
                return [
                    'class' => preg_match("/(resources\/assets\/vendor\/scss\/(rtl\/)?core)-?.*/i", $src) ? 'template-customizer-core-css' :
                      (preg_match("/(resources\/assets\/vendor\/scss\/(rtl\/)?theme)-?.*/i", $src) ? 'template-customizer-theme-css' : ''),
                ];
            }

            return [];
        });

        /**
         * Register Custom Migration Paths
         */
        $this->loadMigrationsFrom([
            database_path().DIRECTORY_SEPARATOR.'migrations'.DIRECTORY_SEPARATOR.'tenant',
        ]);
    }

    /**
     * Register queue tenant awareness for multi-tenant system
     */
    protected function registerQueueTenantAwareness(): void
    {
        // Add tenant_id to all queued jobs automatically
        Queue::createPayloadUsing(function ($connection, $queue, $payload) {
            // Only add tenant context if in SaaS mode
            if (! isSaaSMode()) {
                return [];
            }

            $tenant = tenant();

            if ($tenant) {
                return [
                    'tenant_id' => $tenant->id,
                ];
            }

            return [];
        });

        // Apply tenant context middleware to all jobs
        Queue::before(function (\Illuminate\Queue\Events\JobProcessing $event) {
            // Skip if not in SaaS mode
            if (! isSaaSMode()) {
                return;
            }

            $middleware = new InitializeTenantContext;
            $middleware->handle($event->job, function ($job) {
                // Job continues processing
            });
        });
    }
}
