<?php

declare(strict_types=1);

namespace App\Middleware;

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\RequestHandlerInterface;
use App\Models\User;

final class JwtMiddleware implements \Psr\Http\Server\MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $authHeader = $request->getHeaderLine('Authorization') ?? '';

        if (!str_starts_with($authHeader, 'Bearer ')) {
            $body = json_encode(['message' => 'Missing or invalid Authorization header']);
            return new \Slim\Psr7\Response(401)
                ->withHeader('Content-Type', 'application/json')
                ->withBody((new \Slim\Psr7\Factory\StreamFactory())->createStream($body));
        }

        $token = substr($authHeader, 7);

        try {
            $secret = $_ENV['JWT_SECRET'] ?? 'this-is-a-32-character-secret-key-for-testing';
            $decoded = JWT::decode($token, new Key($secret, 'HS256'));
        } catch (\Throwable $e) {
            $body = json_encode(['message' => 'Invalid or expired token']);
            return new \Slim\Psr7\Response(401)
                ->withHeader('Content-Type', 'application/json')
                ->withBody((new \Slim\Psr7\Factory\StreamFactory())->createStream($body));
        }

        // Load user from DB
        $user = User::find($decoded->sub);

        if (!$user) {
            $body = json_encode(['message' => 'User not found']);
            return new \Slim\Psr7\Response(401)
                ->withHeader('Content-Type', 'application/json')
                ->withBody((new \Slim\Psr7\Factory\StreamFactory())->createStream($body));
        }

        if (!$user->is_active) {
            $body = json_encode(['message' => 'Account disabled']);
            return new \Slim\Psr7\Response(401)
                ->withHeader('Content-Type', 'application/json')
                ->withBody((new \Slim\Psr7\Factory\StreamFactory())->createStream($body));
        }

        // Attach user and tenant to request
        $request = $request->withAttribute('user', $user->toArray());
        $request = $request->withAttribute('tenant_id', $user->tenant_id);

        return $handler->handle($request);
    }
}