<?php

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

use App\Models\AdminRole;
use App\Lottery\ErrorCode;
use App\Support\ApiMessage;
use App\Support\ApiResponse;
use App\Services\AuditLogger;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminAccountScopeGuard;
use App\Support\AdminRoleApiPresenter;
use App\Support\PlatformSystemRoles;
use App\Http\Requests\Admin\AdminRoleUpdateRequest;

final class AdminRoleUpdateController extends Controller
{
    public function __invoke(AdminRoleUpdateRequest $request, AdminRole $admin_role): JsonResponse
    {
        AdminAccountScopeGuard::assertSystemRole($admin_role);

        if ($admin_role->slug === PlatformSystemRoles::SLUG_SUPER_ADMIN) {
            return ApiMessage::errorResponse(
                $request,
                'admin.role_super_admin_metadata_fixed',
                ErrorCode::ValidationFailed->value,
                null,
                422,
            );
        }

        $before = AdminRoleApiPresenter::item($admin_role);

        $payload = [];
        foreach (['slug', 'name', 'description', 'status'] as $field) {
            if ($request->has($field)) {
                $payload[$field] = $request->validated($field);
            }
        }
        if (isset($payload['slug'])) {
            $nextSlug = strtolower(trim((string) $payload['slug']));
            if (
                PlatformSystemRoles::isFixedSlug($nextSlug)
                && $nextSlug !== (string) $admin_role->slug
            ) {
                return ApiMessage::errorResponse(
                    $request,
                    'admin.role_slug_reserved',
                    ErrorCode::ValidationFailed->value,
                    ['slug' => $nextSlug],
                    422,
                );
            }
            $payload['slug'] = $nextSlug;
            $payload['code'] = $nextSlug;
        }

        $admin_role->fill($payload);
        $admin_role->save();
        $admin_role->refresh();

        AuditLogger::recordForAdmin(
            $request->lotteryAdmin(),
            $request,
            'system',
            'admin_role.update',
            'admin_role',
            (string) $admin_role->id,
            $before,
            AdminRoleApiPresenter::item($admin_role),
        );

        return ApiResponse::success(AdminRoleApiPresenter::item($admin_role));
    }
}
