<?php

namespace App\Http\Controllers\Admin;

/*
 * UserAdminController — управление пользователями и правами в административной панели.
 *
 * index()       — список всех пользователей (только для users.view)
 * create()      — форма создания нового пользователя с назначением роли и прав
 * store()       — сохранение нового пользователя
 * edit()        — форма редактирования роли и прав конкретного пользователя
 * update()      — сохранение роли и индивидуальных override-прав
 * destroy()     — удаление пользователя (superadmin удалить нельзя)
 *
 * Управлять можно только теми, кем текущий пользователь canManage() — защита иерархии.
 */

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\UserPermission;
use App\Services\PermissionService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;

class UserAdminController extends Controller
{
    public function index(): View
    {
        $this->authorize('users.view');

        $users = User::with('userPermissions')->orderBy('id')->get();
        $roleLabels = PermissionService::roleLabels();

        return view('admin.users.index', compact('users', 'roleLabels'));
    }

    public function create(): View
    {
        $this->authorize('users.manage');

        $permissions = PermissionService::all();
        $roleLabels = PermissionService::roleLabels();

        return view('admin.users.create', compact('permissions', 'roleLabels'));
    }

    public function store(Request $request): RedirectResponse
    {
        $this->authorize('users.manage');

        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|max:255|unique:users,email',
            'password' => 'required|string|min:8|confirmed',
            'role' => 'nullable|in:superadmin,admin,editor,viewer',
            'permissions' => 'nullable|array',
            'permissions.*' => 'nullable|in:allow,deny',
        ]);

        $newRole = $request->input('role');

        // Только superadmin может назначать роль superadmin или admin
        if (in_array($newRole, ['superadmin', 'admin']) && Auth::user()->role !== 'superadmin') {
            abort(403, 'Только суперадминистратор может назначать эту роль.');
        }

        $user = User::create([
            'name' => $request->input('name'),
            'email' => $request->input('email'),
            'password' => $request->input('password'),
            'role' => $newRole ?: null,
            'is_admin' => ! empty($newRole),
        ]);

        $allKeys = PermissionService::keys();
        foreach ($request->input('permissions', []) as $key => $action) {
            if (! in_array($key, $allKeys, true)) {
                continue;
            }
            if (! in_array($action, ['allow', 'deny'], true)) {
                continue;
            }

            UserPermission::create([
                'user_id' => $user->id,
                'permission' => $key,
                'action' => $action,
            ]);
        }

        return redirect()->route('admin.users.index')
            ->with('success', 'Пользователь «'.$user->name.'» создан.');
    }

    public function edit(User $user): View
    {
        $this->authorize('users.manage');
        abort_unless(Auth::user()->canManage($user), 403, 'Недостаточно прав для управления этим пользователем.');

        $user->load('userPermissions');
        $permissions = PermissionService::all();
        $roleLabels = PermissionService::roleLabels();
        $roleDefaults = $user->role ? PermissionService::roleDefaults($user->role) : [];
        $overrides = $user->userPermissions->keyBy('permission');

        return view('admin.users.edit', compact('user', 'permissions', 'roleLabels', 'roleDefaults', 'overrides'));
    }

    public function update(Request $request, User $user): RedirectResponse
    {
        $this->authorize('users.manage');
        abort_unless(Auth::user()->canManage($user), 403, 'Недостаточно прав для управления этим пользователем.');

        $request->validate([
            'role' => 'nullable|in:superadmin,admin,editor,viewer',
            'permissions' => 'nullable|array',
            'permissions.*' => 'nullable|in:allow,deny',
        ]);

        // superadmin не может снять роль superadmin сам у себя, если он единственный
        if ($user->role === 'superadmin' && $request->input('role') !== 'superadmin') {
            $superCount = User::where('role', 'superadmin')->count();
            abort_if($superCount <= 1, 422, 'Нельзя снять роль у единственного суперадминистратора.');
        }

        // Только superadmin может назначать роль superadmin или admin
        $newRole = $request->input('role');
        if (in_array($newRole, ['superadmin', 'admin']) && Auth::user()->role !== 'superadmin') {
            abort(403, 'Только суперадминистратор может назначать эту роль.');
        }

        $user->update([
            'role' => $newRole ?: null,
            'is_admin' => ! empty($newRole), // синхронизируем legacy-флаг
        ]);

        // Перезаписываем индивидуальные overrides
        UserPermission::where('user_id', $user->id)->delete();

        $allKeys = PermissionService::keys();
        foreach ($request->input('permissions', []) as $key => $action) {
            if (! in_array($key, $allKeys, true)) {
                continue;
            }
            if (! in_array($action, ['allow', 'deny'], true)) {
                continue;
            }

            UserPermission::create([
                'user_id' => $user->id,
                'permission' => $key,
                'action' => $action,
            ]);
        }

        return redirect()->route('admin.users.index')
            ->with('success', 'Пользователь «'.$user->name.'» обновлён.');
    }

    public function destroy(User $user): RedirectResponse
    {
        $this->authorize('users.manage');
        abort_unless(Auth::user()->canManage($user), 403);
        abort_if($user->id === Auth::id(), 422, 'Нельзя удалить самого себя.');

        $user->delete();

        return redirect()->route('admin.users.index')
            ->with('success', 'Пользователь удалён.');
    }
}
