<?php

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

use App\Lottery\ErrorCode;
use App\Models\AgentNode;
use App\Support\ApiMessage;
use App\Support\ApiResponse;
use App\Services\AuditLogger;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Services\Agent\AgentNodeService;
use App\Support\AdminAgentNodeAccess;
use App\Support\AdminAgentScope;
use App\Support\AgentNodePresenter;
use Illuminate\Support\Facades\DB;

final class AgentNodeDestroyController extends Controller
{
    public function __invoke(
        \Illuminate\Http\Request $request,
        AgentNode $agent_node,
        AgentNodeService $service,
    ): JsonResponse {
        $admin = $request->lotteryAdmin();
        abort_if($admin === null, 401);

        $denied = AdminAgentNodeAccess::denyUnlessNodeVisible($admin, $agent_node);
        if ($denied !== null) {
            return $denied;
        }

        if (! AdminAgentScope::nodeManageableBy($admin, $agent_node)) {
            return AdminAgentNodeAccess::denyUnlessNodeVisible($admin, $agent_node)
                ?? AdminAgentNodeAccess::denyUnlessCanManageParent($admin, $agent_node);
        }

        if ($agent_node->isRoot()) {
            return ApiMessage::errorResponse($request, 'admin.agent_root_delete_denied', ErrorCode::ValidationFailed->value, null, 422);
        }

        if ($agent_node->children()->exists()) {
            return ApiMessage::errorResponse($request, 'admin.agent_node_has_children_cannot_delete', ErrorCode::ValidationFailed->value, null, 422);
        }

        if (DB::table('players')->where('agent_node_id', $agent_node->id)->exists()) {
            return ApiMessage::errorResponse($request, 'admin.agent_node_has_players_cannot_delete', ErrorCode::ValidationFailed->value, null, 422);
        }

        if ($service->hasBlockingCustomRoles($agent_node)) {
            return ApiMessage::errorResponse($request, 'admin.agent_node_has_roles_cannot_delete', ErrorCode::ValidationFailed->value, null, 422);
        }

        $before = AgentNodePresenter::item($agent_node);
        $service->destroy($agent_node);

        AuditLogger::recordForAdmin(
            $admin,
            $request,
            'system',
            'agent_node.destroy',
            'agent_node',
            (string) $agent_node->id,
            $before,
            null,
        );

        return ApiResponse::success(null);
    }
}
