<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use PHPOpenSourceSaver\JWTAuth\Exceptions\JWTException;
use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth;
use Symfony\Component\HttpFoundation\Response;

class ApiDocsAuth
{
    public function handle(Request $request, Closure $next): Response
    {
        $user = Auth::user();
        if (!$user) {
            $authHeader = (string) $request->header('Authorization');
            if ($authHeader !== '' && stripos($authHeader, 'Bearer ') === 0) {
                $token = trim(substr($authHeader, 7));
                if ($token === '') {
                    return $this->deny('Missing token.', 401);
                }

                try {
                    $user = JWTAuth::setToken($token)->authenticate();
                    if ($user) {
                        Auth::setUser($user);
                    }
                } catch (JWTException $e) {
                    $user = null;
                }
            }
        }

        if (!$user) {
            return $this->deny('Unauthorized access to documentation.', 401);
        }

        if (!$this->userIsAdmin((int) $user->id)) {
            return $this->deny('Admin privileges required.', 403);
        }

        return $next($request);
    }

    private function userIsAdmin(int $userId): bool
    {
        return DB::table('user_roles as ur')
            ->join('roles as r', 'r.id', '=', 'ur.role_id')
            ->where('ur.user_id', $userId)
            ->whereNull('ur.deleted_at')
            ->whereRaw('LOWER(r.name) = ?', ['admin'])
            ->exists();
    }

    private function deny(string $message, int $status): Response
    {
        return response()->json([
            'status' => false,
            'message' => $message,
        ], $status);
    }
}
