<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreUserRequest;
use App\Http\Requests\UpdateUserRequest;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\View\View;
use Spatie\Permission\Models\Role;

class UserController extends Controller
{
    /**
     * Display a listing of users with search, filter, and pagination.
     * 
     * Requires "view users" permission.
     */
    public function index(Request $request): View
    {
        // Check permission
        abort_unless(
            auth()->user()->can('view users'),
            403,
            'You do not have permission to view users.'
        );

        // Start query with eager loading to prevent N+1 queries
        $query = User::with('roles');

        // Search functionality - filter by name, email, or role name
        if ($request->filled('search')) {
            $search = $request->input('search');
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhereHas('roles', function ($roleQuery) use ($search) {
                      $roleQuery->where('name', 'like', "%{$search}%");
                  });
            });
        }

        // Role filter
        if ($request->filled('role')) {
            $query->whereHas('roles', function ($roleQuery) use ($request) {
                $roleQuery->where('id', $request->input('role'));
            });
        }

        // Status filter (active/inactive)
        if ($request->filled('status')) {
            $status = $request->input('status');
            if ($status === 'active') {
                $query->active();
            } elseif ($status === 'inactive') {
                $query->inactive();
            }
        }

        // Sorting
        $sortBy = $request->input('sort_by', 'created_at');
        $sortOrder = $request->input('sort_order', 'desc');
        $query->orderBy($sortBy, $sortOrder);

        // Pagination
        $perPage = $request->input('per_page', 15);
        $users = $query->paginate($perPage)->withQueryString();

        // Get all roles for filter dropdown
        $roles = Role::all();

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

    /**
     * Show the form for creating a new user.
     * 
     * Requires "create users" permission.
     */
    public function create(): View
    {
        // Check permission
        abort_unless(
            auth()->user()->can('create users'),
            403,
            'You do not have permission to create users.'
        );

        // Get all roles for role assignment
        $roles = Role::all();

        return view('users.create', compact('roles'));
    }

    /**
     * Store a newly created user in storage.
     * 
     * Requires "create users" permission (validated in StoreUserRequest).
     */
    public function store(StoreUserRequest $request): RedirectResponse
    {
        // Create user with validated data
        $user = User::create([
            'name'      => $request->input('name'),
            'email'     => $request->input('email'),
            'username'  => User::generateUsername($request->input('email')),
            'password'  => Hash::make($request->input('password')),
            'is_active' => $request->input('is_active', true),
        ]);

        // Assign roles
        if ($request->filled('roles')) {
            $user->syncRoles($request->input('roles'));
        }

        return redirect()->route('users.index')
            ->with('success', 'User created successfully.');
    }

    /**
     * Display the specified resource.
     * 
     * Not used in this implementation - profile viewing handled by ProfileController.
     */
    public function show(User $user): View
    {
        abort_unless(
            auth()->user()->can('view users'),
            403,
            'You do not have permission to view this user.'
        );

        return view('users.show', compact('user'));
    }

    /**
     * Show the form for editing the specified user.
     * 
     * Requires "edit users" permission.
     */
    public function edit(User $user): View
    {
        // Check permission
        abort_unless(
            auth()->user()->can('edit users'),
            403,
            'You do not have permission to edit users.'
        );

        // Get all roles for role assignment
        $roles = Role::all();

        return view('users.edit', compact('user', 'roles'));
    }

    /**
     * Update the specified user in storage.
     * 
     * Requires "edit users" permission (validated in UpdateUserRequest).
     */
    public function update(UpdateUserRequest $request, User $user): RedirectResponse
    {
        // Update user with validated data
        $user->update([
            'name' => $request->input('name'),
            'email' => $request->input('email'),
            'is_active' => $request->input('is_active', $user->is_active),
        ]);

        // Update password if provided
        if ($request->filled('password')) {
            $user->update([
                'password' => Hash::make($request->input('password')),
            ]);
        }

        // Update roles
        if ($request->filled('roles')) {
            $user->syncRoles($request->input('roles'));
        }

        return redirect()->route('users.index')
            ->with('success', 'User updated successfully.');
    }

    /**
     * Remove the specified resource from storage.
     * 
     * Not implemented - users should be deactivated instead of deleted.
     */
    public function destroy(User $user): RedirectResponse
    {
        abort_unless(
            auth()->user()->can('delete users'),
            403,
            'You do not have permission to delete users.'
        );

        // Soft delete or deactivate instead of hard delete
        $user->update(['is_active' => false]);

        return redirect()->route('users.index')
            ->with('success', 'User deactivated successfully.');
    }

    /**
     * Toggle user active status (AJAX endpoint).
     * 
     * Requires "manage users" permission.
     */
    public function toggleActive(User $user): JsonResponse
    {
        // Check permission
        if (!auth()->user()->can('manage users')) {
            return response()->json([
                'success' => false,
                'message' => 'You do not have permission to manage users.',
            ], 403);
        }

        // Prevent users from deactivating themselves
        if ($user->id === auth()->id()) {
            return response()->json([
                'success' => false,
                'message' => 'You cannot deactivate your own account.',
            ], 422);
        }

        // Toggle active status
        $user->update([
            'is_active' => !$user->is_active,
        ]);

        return response()->json([
            'success' => true,
            'message' => $user->is_active 
                ? 'User activated successfully.' 
                : 'User deactivated successfully.',
            'is_active' => $user->is_active,
        ]);
    }
}
