<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use App\Rules\PasswordRule;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Password;
use Illuminate\Validation\ValidationException;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

class UserController extends Controller
{
    public $collapsedGroups = [];

    public function index()
    {
        $this->authorize('viewAny', User::class);
        $users = User::paginate(10);
        return view('users.index', ['users' => $users,
                                    'showSidebar' => 'true',]);
    }

    public function create()
    {
        $this->authorize('create', User::class);
        $roles = Role::all();
        $user = new User();
        return view('users.create', ['user' => $user, 
                                     'roles' => $roles,
                                     'showSidebar' => 'true',
                                    ]);
    }

    public function store(Request $request)
    {
        $this->authorize('create', User::class);
        try {
            // Validación de datos
            $validated = $request->validate([
                'title' => 'nullable|string|max:10',
                'first_name' => 'required|string|max:50',
                'last_name' => 'required|string|max:50',
                'username' => 'required|string|unique:users|max:30',
                'password' => ['required',
                                new PasswordRule(
                                    minLength: 12,
                                    requireUppercase: true,
                                    requireNumeric: true,
                                    requireSpecialCharacter: true,
                                    //uncompromised: true, // Verificar contra Have I Been Pwned
                                    //requireLetters: true
                                ),
                                Password::defaults()->mixedCase()->numbers()->symbols()
                                    ->uncompromised(3) // Número mínimo de apariciones en brechas
            ],
                'start_date' => 'nullable|date',
                'end_date' => 'nullable|date|after_or_equal:start_date',
                'email' => 'required|email|unique:users',
                'phone' => 'nullable|string|max:20',
                'address' => 'nullable|string|max:255',
                'user_type' => 'required|integer|in:0,1,2',
                'company_id' => 'nullable|exists:companies,id', // Si se usa una relación con empresas
                'profile_photo_path' => 'nullable|string' // Ruta de la imagen subida por Livewire
            ]);

            // Creación del usuario
            $user = User::create([
                'title' => $validated['title'],
                'first_name' => $validated['first_name'],
                'last_name' => $validated['last_name'],
                'username' => $validated['username'],
                'password' => Hash::make($validated['password']),
                'email' => $validated['email'],
                'phone' => $validated['phone'],
                'address' => $validated['address'],
                'access_start' => $validated['start_date'],
                'access_end' => $validated['end_date'],
                'is_active' => $validated['is_active'] ?? false, // Por defecto, inactivo
                'user_type' => $validated['user_type'] ?? 0, // 0: Usuario, 1: Administrador, 2: Super Admin
                'company_id' => $validated['company_id'] ?? null, // Si se usa una relación con empresas
                'profile_photo_path' => $validated['profile_photo_path'] ?? null
            ]);

            if ($request->hasFile('image_path')) {
                $path = $request->file('image_path')->store('public/photos');
                $user->profile_photo_path = basename($path);
                $user->save();
            }

            // Asignación de roles (opcional, usando Spatie Permissions)
            // $user->assignRole('user');

            return redirect()->route('users.index')->with('success', 'Usuario creado exitosamente.')->with('temp_password', $validated['password']);;
        } catch (\Exception $e) {
            return back()->withInput()->with('error', 'Error al crear el usuario: ' . $e->getMessage());
        }
    }

    public function edit(User $user)
    {
        $this->authorize('update', $user);
        $roles = Role::all();
        $userRoles = $user->roles->pluck('id')->toArray();
        return view('users.create', compact('user', 'roles', 'userRoles'));
    }

    public function update(Request $request, User $user)
    {
        try {
            // Validación de datos
            $validated = $request->validate([
                'title' => 'nullable|string|max:10',
                'first_name' => 'required|string|max:50',
                'last_name' => 'required|string|max:50',
                'username' => [
                    'required',
                    'string',
                    'max:30',
                    Rule::unique('users')->ignore($user->id)
                ],
                'password' => [
                    'nullable',
                    Password::min(12)
                        ->mixedCase()
                        ->numbers()
                        ->symbols()
                        ->uncompromised(3)
                ],
                'start_date' => 'nullable|date',
                'end_date' => 'nullable|date|after_or_equal:start_date',
                'email' => [
                    'required',
                    'email',
                    Rule::unique('users')->ignore($user->id)
                ],
                'phone' => 'nullable|string|max:20',
                'address' => 'nullable|string|max:255',
                'profile_photo_path' => 'nullable|string', // Añadido para la ruta de la imagen
                //'is_active' => 'nullable|boolean' // Añadido para el estado activo
            ]);
    
            // Preparar datos para actualización
            $updateData = [
                'title' => $validated['title'],
                'first_name' => $validated['first_name'],
                'last_name' => $validated['last_name'],
                'username' => $validated['username'],
                'email' => $validated['email'],
                'phone' => $validated['phone'],
                'address' => $validated['address'],
                'access_start' => $validated['start_date'],
                'access_end' => $validated['end_date'],
                'is_active' => $validated['is_active'] ?? false,
                'profile_photo_path' => $validated['profile_photo_path'] ?? $user->profile_photo_path
            ];
    
            // Actualizar contraseña solo si se proporciona
            if (!empty($validated['password'])) {
                $updateData['password'] = Hash::make($validated['password']);
            }
    
            // Eliminar imagen anterior si se está actualizando
            if (isset($validated['profile_photo_path']) && $user->profile_photo_path) {
                Storage::disk('public')->delete($user->profile_photo_path);
            }
    
            // Actualizar el usuario
            $user->update($updateData);
    
            // Redireccionar con mensaje de éxito
            return redirect()->route('users.show', $user)
                ->with('success', 'Usuario actualizado exitosamente');
    
        } catch (ValidationException $e) {
            return redirect()->back()->withErrors($e->validator)->withInput();
                
        } catch (QueryException $e) {
            $errorCode = $e->errorInfo[1];
            $errorMessage = 'Error al actualizar el usuario: ';
            
            if ($errorCode == 1062) {
                $errorMessage .= 'El nombre de usuario o correo electrónico ya está en uso';
            } else {
                $errorMessage .= 'Error en la base de datos';
            }
    
            Log::error("Error actualizando usuario ID {$user->id}: " . $e->getMessage());
            return redirect()->back()->with('error', $errorMessage)->withInput();
    
        } catch (\Exception $e) {
            Log::error("Error general actualizando usuario ID {$user->id}: " . $e->getMessage());
            return redirect()->back()->with('error', 'Ocurrió un error inesperado al actualizar el usuario')->withInput();
        }
    }

    public function show(User $user)
    {
        $previousUser = User::where('id', '<', $user->id)->latest('id')->first();
        $nextUser = User::where('id', '>', $user->id)->oldest('id')->first();
        $permissionGroups = $this->getPermissionGroups($user);

        return view('users.show', [
            'user' => $user,
            'previousUser' => $previousUser,
            'nextUser' => $nextUser,
            'permissionGroups' => $permissionGroups,
            'showSidebar' => true,
            'collapsedGroups' => $this->collapsedGroups,
        ]);
    }

    public function updatePassword(Request $request, User $user)
    {
        $this->authorize('update', $user);
        
        $request->validate([
            'password' => 'required|min:8|confirmed'
        ]);
        
        $user->update([
            'password' => Hash::make($request->password)
        ]);
        
        return redirect()->back()
            ->with('success', 'Contraseña actualizada correctamente');
    }

    public function destroy(User $user)
    {
        $this->authorize('delete', $user);
        
        if($user->is_protected) {
            return redirect()->back()
                ->with('error', 'No se puede eliminar un usuario protegido');
        }
        
        $user->delete();
        return redirect()->route('users.index')
            ->with('success', 'Usuario eliminado correctamente');
    }

    private function getPermissionGroups(User $user)
    {
        // Obtener todos los permisos disponibles
        $allPermissions = Permission::all();
        
        // Agrupar permisos por tipo (asumiendo que los nombres siguen el formato "tipo.acción")
        $grouped = $allPermissions->groupBy(function ($permission) {
            return explode('.', $permission->name)[0]; // Extrae "user" de "user.create"
        });
        
        // Formatear para la vista
        $groups = [];
        foreach ($grouped as $groupName => $permissions) {
            $groups[$groupName] = [
                'name' => ucfirst($groupName),
                'permissions' => $permissions->map(function ($permission) use ($user) {
                    return [
                        'id' => $permission->id,
                        'name' => $permission->name,
                        'description' => $this->getPermissionDescription($permission->name),
                        'enabled' => $user->hasPermissionTo($permission)
                    ];
                })
            ];
        }
        
        return $groups;
    }

    private function getPermissionDescription($permissionName)
    {
        $descriptions = [
            'user.create' => 'Crear nuevos usuarios',
            'user.edit' => 'Editar usuarios existentes',
            'document.view' => 'Ver documentos',
            // Agrega más descripciones según necesites
        ];
        
        return $descriptions[$permissionName] ?? str_replace('.', ' ', $permissionName);
    }

    public function toggleGroupCollapse($groupName)
    {
        if (in_array($groupName, $this->collapsedGroups)) {
            $this->collapsedGroups = array_diff($this->collapsedGroups, [$groupName]);
        } else {
            $this->collapsedGroups[] = $groupName;
        }
    }

}