<?php

namespace App\Http\Middleware;

use App\Models\User;
use Closure;
use Illuminate\Auth\Middleware\RedirectIfAuthenticated as BaseMiddleware;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

class RedirectIfAuthenticated extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     */
    public function handle(Request $request, Closure $next, string ...$guards): Response
    {
        $guards = $guards === [] ? [null] : $guards;

        foreach ($guards as $guard) {
            if (! Auth::guard($guard)->check()) {
                continue;
            }

            $user = Auth::guard($guard)->user();

            if ($this->shouldBypassForTenantAdmin($request, $user)) {
                continue;
            }

            if ($user && $user->role === 'tenant_admin') {
                $this->storeTenantAdminTarget($request);
            }

            return redirect($this->redirectPath($user));
        }

        return $next($request);
    }

    private function shouldBypassForTenantAdmin(Request $request, ?User $user): bool
    {
        if (! $user || $user->role !== 'tenant_admin') {
            return false;
        }

        $encoded = $request->string('return_to')->trim()->toString();

        if ($encoded === '') {
            return false;
        }

        $decoded = $this->decodeReturnTo($encoded);

        if ($decoded === null) {
            return false;
        }

        $path = $this->normalizePath($decoded);

        return str_starts_with($path, '/event-admin');
    }

    private function decodeReturnTo(string $value): ?string
    {
        $padded = str_pad($value, strlen($value) + ((4 - (strlen($value) % 4)) % 4), '=');
        $normalized = strtr($padded, '-_', '+/');
        $decoded = base64_decode($normalized, true);

        return $decoded === false ? null : $decoded;
    }

    private function normalizePath(string $target): string
    {
        $trimmed = trim($target);

        if ($trimmed === '') {
            return '';
        }

        if (str_starts_with($trimmed, '/')) {
            return $trimmed;
        }

        $parsed = parse_url($trimmed);

        if ($parsed === false || ! isset($parsed['path'])) {
            return '';
        }

        $path = $parsed['path'];

        if (! str_starts_with($path, '/')) {
            $path = '/'.$path;
        }

        if (isset($parsed['query'])) {
            $path .= '?'.$parsed['query'];
        }

        if (isset($parsed['fragment'])) {
            $path .= '#'.$parsed['fragment'];
        }

        return $path;
    }

    private function redirectPath(?User $user): string
    {
        if ($user && $user->role === 'tenant_admin') {
            return '/event-admin/dashboard';
        }

        if ($user && $user->isSuperAdmin()) {
            return '/super-admin';
        }

        if ($user && $user->role === 'user') {
            return '/packages';
        }

        return '/dashboard';
    }

    private function storeTenantAdminTarget(Request $request): void
    {
        $encoded = $request->string('return_to')->trim()->toString();

        if ($encoded === '') {
            return;
        }

        $decoded = $this->decodeReturnTo($encoded);

        if ($decoded === null) {
            return;
        }

        $path = $this->normalizePath($decoded);

        if (! str_starts_with($path, '/event-admin')) {
            return;
        }

        $request->session()->put('tenant_admin.return_to', $path);
    }
}
