<?php

namespace App\Http\Controllers\Administracion;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;
use Spatie\Permission\Models\Role;

class UserController extends Controller
{
    public function index(Request $request)
    {
        try {
            $query = User::with('roles');

            if ($request->filled('buscar')) {
                $query->where(function ($q) use ($request) {
                    $q->where('name', 'like', "%{$request->buscar}%")
                      ->orWhere('email', 'like', "%{$request->buscar}%");
                });
            }

            if ($request->filled('rol')) {
                $query->whereHas('roles', function ($q) use ($request) {
                    $q->where('name', $request->rol);
                });
            }

            $usuarios = $query->orderBy('id', 'desc')->paginate(15);

            $usuarios->getCollection()->transform(function ($user) {
                return [
                    'id'         => $user->id,
                    'name'       => $user->name,
                    'email'      => $user->email,
                    'roles'      => $user->getRoleNames(),
                    'created_at' => $user->created_at,
                ];
            });

            return response()->json([
                'success' => true,
                'data'    => $usuarios,
            ]);
        } catch (\Exception $e) {
            Log::error('Error al listar usuarios', ['error' => $e->getMessage()]);
            return response()->json(['success' => false, 'message' => 'Error al obtener usuarios'], 500);
        }
    }

    public function store(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'name'                  => 'required|string|max:255|regex:/^[\pL\s\-]+$/u',
                'email'                 => 'required|email|unique:users,email|max:255',
                'password'              => 'required|string|min:8|confirmed',
                'rol'                   => 'required|string|exists:roles,name',
            ], [
                'name.regex'    => 'El nombre solo puede contener letras y espacios.',
                'rol.exists'    => 'El rol seleccionado no existe.',
                'email.unique'  => 'Este correo ya está registrado.',
            ]);

            if ($validator->fails()) {
                return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
            }

            $user = User::create([
                'name'     => strip_tags(trim($request->name)),
                'email'    => strtolower(trim($request->email)),
                'password' => Hash::make($request->password),
            ]);

            $user->assignRole($request->rol);

            Log::info('Usuario creado por admin', [
                'admin_id'      => $request->user()->id,
                'nuevo_user_id' => $user->id,
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Usuario creado correctamente',
                'data'    => [
                    'id'         => $user->id,
                    'name'       => $user->name,
                    'email'      => $user->email,
                    'roles'      => $user->getRoleNames(),
                    'created_at' => $user->created_at,
                ],
            ], 201);
        } catch (\Exception $e) {
            Log::error('Error al crear usuario', ['error' => $e->getMessage()]);
            return response()->json(['success' => false, 'message' => 'Error al crear usuario'], 500);
        }
    }

    public function update(Request $request, $id)
    {
        try {
            $user = User::findOrFail($id);

            $validator = Validator::make($request->all(), [
                'name'  => 'required|string|max:255|regex:/^[\pL\s\-]+$/u',
                'email' => 'required|email|max:255|unique:users,email,' . $user->id,
                'rol'   => 'required|string|exists:roles,name',
            ], [
                'name.regex'   => 'El nombre solo puede contener letras y espacios.',
                'rol.exists'   => 'El rol seleccionado no existe.',
                'email.unique' => 'Este correo ya está registrado.',
            ]);

            if ($validator->fails()) {
                return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
            }

            $user->update([
                'name'  => strip_tags(trim($request->name)),
                'email' => strtolower(trim($request->email)),
            ]);

            $user->syncRoles([$request->rol]);

            Log::info('Usuario actualizado', [
                'admin_id' => $request->user()->id,
                'user_id'  => $user->id,
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Usuario actualizado correctamente',
                'data'    => [
                    'id'         => $user->id,
                    'name'       => $user->name,
                    'email'      => $user->email,
                    'roles'      => $user->getRoleNames(),
                    'created_at' => $user->created_at,
                ],
            ]);
        } catch (\Exception $e) {
            Log::error('Error al actualizar usuario', ['error' => $e->getMessage()]);
            return response()->json(['success' => false, 'message' => 'Error al actualizar usuario'], 500);
        }
    }

    public function changePassword(Request $request, $id)
    {
        try {
            $user     = User::findOrFail($id);
            $authUser = $request->user();

            $rules = ['password' => 'required|string|min:8|confirmed'];

            if ($authUser->id === $user->id) {
                $rules['current_password'] = 'required|string';
            }

            $validator = Validator::make($request->all(), $rules);

            if ($validator->fails()) {
                return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
            }

            if ($authUser->id === $user->id) {
                if (!Hash::check($request->current_password, $user->password)) {
                    return response()->json([
                        'success' => false,
                        'errors'  => ['current_password' => ['La contraseña actual no es correcta']],
                    ], 422);
                }
            } else {
                // Al cambiar la contraseña de otro usuario, revocar sus tokens
                $user->tokens()->delete();
            }

            $user->update(['password' => Hash::make($request->password)]);

            Log::info('Contraseña cambiada', [
                'admin_id' => $authUser->id,
                'user_id'  => $user->id,
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Contraseña actualizada correctamente',
            ]);
        } catch (\Exception $e) {
            Log::error('Error al cambiar contraseña', ['error' => $e->getMessage()]);
            return response()->json(['success' => false, 'message' => 'Error al cambiar contraseña'], 500);
        }
    }

    public function destroy(Request $request, $id)
    {
        try {
            $user = User::findOrFail($id);

            if ($request->user()->id === $user->id) {
                return response()->json([
                    'success' => false,
                    'message' => 'No puedes eliminar tu propia cuenta',
                ], 403);
            }

            $user->tokens()->delete();
            $user->delete();

            Log::info('Usuario eliminado', [
                'admin_id' => $request->user()->id,
                'user_id'  => $id,
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Usuario eliminado correctamente',
            ]);
        } catch (\Exception $e) {
            Log::error('Error al eliminar usuario', ['error' => $e->getMessage()]);
            return response()->json(['success' => false, 'message' => 'Error al eliminar usuario'], 500);
        }
    }

    public function roles()
    {
        try {
            $roles = Role::orderBy('name')->get(['id', 'name']);
            return response()->json(['success' => true, 'data' => $roles]);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Error al obtener roles'], 500);
        }
    }
}
