<?php

namespace App\Http\Middleware;

use App\Models\Theme;
use App\Services\ThemeService;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class InjectTheme
{
    private ThemeService $themeService;

    public function __construct(ThemeService $themeService)
    {
        $this->themeService = $themeService;
    }

    /**
     * Handle an incoming request.
     *
     * Injects the active theme CSS variables into all authenticated views.
     * When a user is authenticated, their role's assigned theme takes priority
     * over the globally active theme. Falls back to the global active theme
     * if no role-specific theme is found.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        try {
            $theme = $this->resolveTheme($request);

            view()->share('activeTheme', $theme);
            view()->share('themeCssVariables', $theme
                ? $theme->toCssVariables()
                : $this->themeService->getThemeCssVariables()
            );
        } catch (\Throwable $e) {
            // Never let a theme resolution failure crash the request.
            // Share safe defaults so views that reference these variables don't break.
            view()->share('activeTheme', null);
            view()->share('themeCssVariables', []);
        }

        return $next($request);
    }

    /**
     * Resolve the theme to use for this request.
     *
     * Priority order:
     * 1. Authenticated user's primary role theme (via roles.theme slug)
     * 2. Globally active theme (is_active = true)
     * 3. null (CSS defaults in app.css will apply)
     */
    private function resolveTheme(Request $request): ?Theme
    {
        // Try role-specific theme for authenticated users
        if ($request->user()) {
            $role = $request->user()->roles->first();

            if ($role && !empty($role->theme) && $role->theme !== 'default') {
                $roleTheme = Theme::where('slug', $role->theme)->first();

                if ($roleTheme) {
                    return $roleTheme;
                }
            }
        }

        // Fall back to globally active theme
        return $this->themeService->getActiveTheme();
    }
}
