<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\AssignRolesRequest;
use App\Http\Requests\Admin\CreateAdminUserRequest;
use App\Http\Requests\Admin\UpdateAdminUserRequest;
use App\Models\User;
use App\Services\AdminUserService;
use Illuminate\Http\JsonResponse;

class AdminUserController extends Controller
{
    public function __construct(private AdminUserService $adminUserService) {}

    /**
     * List all admin users with their roles.
     */
    public function index(): JsonResponse
    {
        $users = User::with('roles')->orderBy('name')->get()->map(fn ($u) => $this->formatUser($u));

        return response()->json(['data' => $users]);
    }

    /**
     * Show a single admin user with roles and permissions.
     */
    public function show(User $user): JsonResponse
    {
        $user->load('roles', 'permissions');

        return response()->json(['data' => $this->formatUser($user, detailed: true)]);
    }

    /**
     * Create a new admin user.
     */
    public function store(CreateAdminUserRequest $request): JsonResponse
    {
        $user = $this->adminUserService->create($request->validated());

        return response()->json(
            ['message' => 'Admin user created successfully.', 'data' => $this->formatUser($user->load('roles'))],
            201
        );
    }

    /**
     * Update an admin user's name or email.
     */
    public function update(UpdateAdminUserRequest $request, User $user): JsonResponse
    {
        $user = $this->adminUserService->update($user, $request->validated());

        return response()->json(['message' => 'Admin user updated successfully.', 'data' => $this->formatUser($user->load('roles'))]);
    }

    /**
     * Delete an admin user.
     */
    public function destroy(User $user): JsonResponse
    {
        $this->adminUserService->delete(auth()->user(), $user);

        return response()->json(['message' => 'Admin user deleted successfully.']);
    }

    /**
     * Assign (sync) roles to an admin user — replaces existing roles.
     */
    public function assignRoles(AssignRolesRequest $request, User $user): JsonResponse
    {
        $user = $this->adminUserService->syncRoles($user, $request->validated('roles'));

        return response()->json(['message' => 'Roles assigned successfully.', 'data' => $this->formatUser($user->load('roles'))]);
    }

    /**
     * Get the currently authenticated admin user with full role/permission detail.
     */
    public function me(): JsonResponse
    {
        $user = auth()->user()->load('roles', 'permissions');

        return response()->json(['data' => $this->formatUser($user, detailed: true)]);
    }

    private function formatUser(User $user, bool $detailed = false): array
    {
        $data = [
            'id'               => $user->id,
            'name'             => $user->name,
            'email'            => $user->email,
            'two_factor_setup' => $user->hasCompletedTwoFactorSetup(),
            'roles'            => $user->roles->pluck('name'),
            'created_at'       => $user->created_at?->toISOString(),
        ];

        if ($detailed) {
            $data['direct_permissions'] = $user->permissions->pluck('name');
            $data['all_permissions']    = $user->getAllPermissions()->pluck('name');
        }

        return $data;
    }
}
