<?php

namespace App\Http\Controllers\Api\V1\Admin\Player;

use App\Models\Player;
use Illuminate\Http\Request;
use App\Lottery\ErrorCode;
use App\Support\ApiMessage;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminApiList;
use App\Support\AdminScopePolicy;
use App\Support\PlayerApiPresenter;

/** GET /api/v1/admin/players */
final class AdminPlayerIndexController extends Controller
{
    public function __invoke(Request $request): JsonResponse
    {
        $admin = $request->lotteryAdmin();
        abort_if($admin === null, 401);

        if (
            ! $admin->isSuperAdmin()
            && ! $admin->hasPermissionCode('service.players.view')
            && ! $admin->hasPermissionCode('service.players.manage')
        ) {
            return ApiMessage::errorResponse(
                $request,
                'admin.permission_denied',
                ErrorCode::AdminForbidden->value,
                null,
                403,
            );
        }

        $p = AdminApiList::readPaging($request);
        $keyword = trim((string) $request->query('keyword', ''));
        $status = $request->query('status');
        $scope = AdminScopePolicy::resolveContext($request, $admin);

        $q = Player::query()
            ->with([
                'wallets' => static fn ($wq) => $wq->orderBy('wallet_type')->orderBy('currency_code'),
                'agentNode:id,code,name',
            ])
            ->orderByDesc('id');

        AdminScopePolicy::applyPlayerFilters($q, $scope);

        if ($keyword !== '') {
            $term = '%'.addcslashes($keyword, '%_\\').'%';
            $q->where(static function ($sub) use ($term, $keyword): void {
                $sub->where('site_player_id', 'like', $term)
                    ->orWhere('username', 'like', $term)
                    ->orWhere('nickname', 'like', $term);
                if (ctype_digit($keyword)) {
                    $sub->orWhere('id', (int) $keyword);
                }
            });
        }

        if ($status !== null && $status !== '') {
            $q->where('status', (int) $status);
        }

        $paginator = $q->paginate($p['perPage'], ['*'], 'page', $p['page']);

        return AdminApiList::json($paginator, fn (Player $player): array => PlayerApiPresenter::listItem($player));
    }
}
