<?php
declare(strict_types=1);

namespace App\Middleware;

use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\ApiErrorCodes;

final class PlayerApiAuthMiddleware
{
    public function handle(Request $request, callable $next): Response
    {
        $token = $request->bearerToken();
        if (!$token) {
            return (new Response())->json([
                'success' => false,
                'data' => null,
                'meta' => null,
                'errors' => ['code' => ApiErrorCodes::AUTH_REQUIRED, 'message' => 'Authentication required'],
            ], 401);
        }

        $db = App::getInstance()->db();
        $tokenRow = $db->selectOne(
            "SELECT player_id, expires_at FROM player_tokens WHERE token = ? AND is_revoked = 0",
            [$token]
        );

        if (!$tokenRow) {
            return (new Response())->json([
                'success' => false,
                'data' => null,
                'meta' => null,
                'errors' => ['code' => ApiErrorCodes::AUTH_INVALID, 'message' => 'Invalid token'],
            ], 401);
        }

        if ($tokenRow['expires_at'] && $tokenRow['expires_at'] < date('Y-m-d H:i:s')) {
            return (new Response())->json([
                'success' => false,
                'data' => null,
                'meta' => null,
                'errors' => ['code' => ApiErrorCodes::AUTH_EXPIRED, 'message' => 'Token expired'],
            ], 401);
        }

        $player = $db->selectOne(
            "SELECT * FROM players WHERE id = ? AND is_archived = 0",
            [(int) $tokenRow['player_id']]
        );

        if (!$player) {
            return (new Response())->json([
                'success' => false,
                'data' => null,
                'meta' => null,
                'errors' => ['code' => ApiErrorCodes::AUTH_INACTIVE, 'message' => 'Account inactive'],
            ], 401);
        }

        App::getInstance()->setCurrentPlayer((object) $player);

        $db->update('player_tokens', [
            'last_used_at' => date('Y-m-d H:i:s'),
        ], '`token` = ?', [$token]);

        return $next($request);
    }
}
