#!/bin/bash
#
# Synex Control - Users and Groups Management Module
# src/modules/synex-control-users
#

# Source common library
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/../lib/common.sh"

# Check root privileges
check_root "$@"

# ============================================================================
# LANGUAGE STRINGS - SPANISH
# ============================================================================

declare -A USERS_ES=(
    [menu_title]="Gestión de Usuarios y Grupos"
    [menu_option_1]="1) Crear nuevo usuario"
    [menu_option_2]="2) Eliminar usuario"
    [menu_option_3]="3) Modificar usuario"
    [menu_option_4]="4) Listar usuarios"
    [menu_option_5]="5) Gestionar grupos"
    [menu_option_0]="0) Volver al menú principal"
    [select_option]="Selecciona una opción"
    [invalid_option]="Opción inválida"
    [enter_username]="Nombre de usuario"
    [enter_password]="Contraseña"
    [confirm_password]="Confirmar contraseña"
    [password_mismatch]="Las contraseñas no coinciden"
    [user_exists]="El usuario ya existe"
    [user_created]="Usuario creado exitosamente"
    [user_not_found]="Usuario no encontrado"
    [user_deleted]="Usuario eliminado exitosamente"
    [user_modified]="Usuario modificado exitosamente"
    [confirm_delete]="¿Estás seguro de que deseas eliminar este usuario?"
    [enter_shell]="Shell (presiona ENTER para /bin/bash)"
    [enter_home]="Directorio home (presiona ENTER para /home/USERNAME)"
    [enter_comment]="Comentario/Nombre completo"
    [add_to_sudo]="¿Agregar a grupo sudo?"
    [add_to_group]="¿Agregar a otros grupos?"
    [enter_groups]="Ingresa grupos separados por comas (sin espacios)"
    [user_list]="LISTA DE USUARIOS"
    [system_users]="USUARIOS DEL SISTEMA"
    [regular_users]="USUARIOS REGULARES"
    [group_menu]="GESTION DE GRUPOS"
    [create_group]="Crear grupo"
    [delete_group]="Eliminar grupo"
    [list_groups]="Listar grupos"
    [enter_groupname]="Nombre del grupo"
    [group_exists]="El grupo ya existe"
    [group_created]="Grupo creado exitosamente"
    [group_deleted]="Grupo eliminado exitosamente"
    [group_not_found]="Grupo no encontrado"
    [confirm_group_delete]="¿Estás seguro de que deseas eliminar este grupo?"
    [user_added_to_group]="Usuario agregado al grupo exitosamente"
    [operation_cancelled]="Operación cancelada"
    [user_available_users]="Usuarios disponibles:"
    [user_enter_username_or_cancel]="Nombre de usuario (ENTER para cancelar): "
    [user_operation_cancelled]="Operación cancelada"
    [user_change_password]="¿Cambiar contraseña?"
    [user_new_password_prompt]="¿Cambiar contraseña? (s/N): "
    [user_password_changed]="Contraseña cambiada correctamente"
    [user_password_change_failed]="Error al cambiar contraseña"
)

# ============================================================================
# LANGUAGE STRINGS - ENGLISH
# ============================================================================

declare -A USERS_EN=(
    [menu_title]="Users and Groups Management"
    [menu_option_1]="1) Create new user"
    [menu_option_2]="2) Delete user"
    [menu_option_3]="3) Modify user"
    [menu_option_4]="4) List users"
    [menu_option_5]="5) Manage groups"
    [menu_option_0]="0) Return to main menu"
    [select_option]="Select an option"
    [invalid_option]="Invalid option"
    [enter_username]="Username"
    [enter_password]="Password"
    [confirm_password]="Confirm password"
    [password_mismatch]="Passwords do not match"
    [user_exists]="User already exists"
    [user_created]="User created successfully"
    [user_not_found]="User not found"
    [user_deleted]="User deleted successfully"
    [user_modified]="User modified successfully"
    [confirm_delete]="Are you sure you want to delete this user?"
    [enter_shell]="Shell (press ENTER for /bin/bash)"
    [enter_home]="Home directory (press ENTER for /home/USERNAME)"
    [enter_comment]="Comment/Full name"
    [add_to_sudo]="Add to sudo group?"
    [add_to_group]="Add to other groups?"
    [enter_groups]="Enter groups separated by commas (no spaces)"
    [user_list]="USER LIST"
    [system_users]="SYSTEM USERS"
    [regular_users]="REGULAR USERS"
    [group_menu]="GROUPS MANAGEMENT"
    [create_group]="Create group"
    [delete_group]="Delete group"
    [list_groups]="List groups"
    [enter_groupname]="Group name"
    [group_exists]="Group already exists"
    [group_created]="Group created successfully"
    [group_deleted]="Group deleted successfully"
    [group_not_found]="Group not found"
    [confirm_group_delete]="Are you sure you want to delete this group?"
    [user_added_to_group]="User added to group successfully"
    [operation_cancelled]="Operation cancelled"
    [user_available_users]="Available users:"
    [user_enter_username_or_cancel]="Username (ENTER to cancel): "
    [user_operation_cancelled]="Operation cancelled"
    [user_change_password]="Change password?"
    [user_new_password_prompt]="Change password? (y/N): "
    [user_password_changed]="Password changed successfully"
    [user_password_change_failed]="Failed to change password"
)

# ============================================================================
# MESSAGE FUNCTION (USERS SPECIFIC)
# ============================================================================

user_msg() {
    local key="$1"

    if [ "$LANG_CHOICE" = "es" ]; then
        echo "${USERS_ES[$key]:-$key}"
    else
        echo "${USERS_EN[$key]:-$key}"
    fi
}

# ============================================================================
# LIST NORMAL USERS (HELPER FUNCTION)
# ============================================================================

list_normal_users() {
    echo ""
    print_info "$(user_msg user_available_users)"
    echo ""
    awk -F: '$3 >= 1000 && $1 != "nobody" {printf "  * %s (%s)\n", $1, $5}' /etc/passwd
    echo ""
}

# ============================================================================
# CREATE USER FUNCTION
# ============================================================================

create_user() {
    show_header
    print_info "$(user_msg menu_option_1)"
    echo ""

    local username
    local password
    local password_confirm
    local shell="/bin/bash"
    local home_dir
    local comment
    local add_sudo
    local add_groups=""

    # Get username
    while true; do
        read_input_with_escape "$(user_msg enter_username)"
        username="$READ_INPUT"

        # Check if cancelled (ESC, BACK, or empty)
        if [ -z "$username" ] || [ "$username" = "ESC" ] || [ "$username" = "BACK" ]; then
            return
        fi

        if ! validate_username "$username"; then
            continue
        fi

        if id "$username" &>/dev/null; then
            print_error "$(user_msg user_exists)"
            continue
        fi

        break
    done

    # Get password
    while true; do
        read -s -p "$(user_msg enter_password): " password
        echo ""
        read -s -p "$(user_msg confirm_password): " password_confirm
        echo ""

        if [ "$password" != "$password_confirm" ]; then
            print_error "$(user_msg password_mismatch)"
            continue
        fi

        break
    done

    # Get comment (optional)
    read_input_with_escape "$(user_msg enter_comment) (opcional)"
    comment="$READ_INPUT"
    
    # Check if cancelled
    if [ "$comment" = "ESC" ] || [ "$comment" = "BACK" ]; then
        return
    fi

    # Get shell (optional)
    read_input_with_escape "$(user_msg enter_shell)"
    shell_input="$READ_INPUT"
    
    # Check if cancelled
    if [ "$shell_input" = "ESC" ] || [ "$shell_input" = "BACK" ]; then
        return
    fi
    
    if [ -z "$shell_input" ]; then
        shell="/bin/bash"
    else
        shell="$shell_input"
    fi

    # Get home directory (optional)
    read_input_with_escape "$(user_msg enter_home)"
    home_input="$READ_INPUT"
    
    # Check if cancelled
    if [ "$home_input" = "ESC" ] || [ "$home_input" = "BACK" ]; then
        return
    fi
    
    if [ -z "$home_input" ]; then
        home_dir="/home/$username"
    else
        # If not an absolute path, prepend /home/
        if [[ ! "$home_input" =~ ^/ ]]; then
            home_dir="/home/$home_input"
        else
            home_dir="$home_input"
        fi
    fi

    # Ask about sudo
    if ask_yes_no "$(user_msg add_to_sudo)"; then
        add_sudo="sudo"
    fi

    # Ask about additional groups
    if ask_yes_no "$(user_msg add_to_group)"; then
        read_input_with_escape "$(user_msg enter_groups)"
        add_groups="$READ_INPUT"
        
        # Check if cancelled
        if [ "$add_groups" = "ESC" ] || [ "$add_groups" = "BACK" ]; then
            return
        fi
    fi

    # Create the user
    if useradd -m -d "$home_dir" -s "$shell" -c "$comment" "$username" 2>/dev/null; then
        # Set password
        echo "$username:$password" | chpasswd

        # Add to sudo group if requested
        if [ -n "$add_sudo" ]; then
            usermod -aG sudo "$username" 2>/dev/null
        fi

        # Add to additional groups
        if [ -n "$add_groups" ]; then
            IFS=',' read -ra GROUPS <<< "$add_groups"
            for group in "${GROUPS[@]}"; do
                group=$(echo "$group" | xargs)  # trim whitespace
                if getent group "$group" &>/dev/null; then
                    usermod -aG "$group" "$username" 2>/dev/null
                else
                    print_warning "$(user_msg group_not_found): $group"
                fi
            done
        fi

        print_success "$(user_msg user_created)"
        log_message "INFO" "User created: $username"
    else
        print_error "Error creating user"
        log_message "ERROR" "Failed to create user: $username"
    fi

    pause_execution
}

# ============================================================================
# DELETE USER FUNCTION
# ============================================================================

delete_user() {
    show_header
    print_info "$(user_msg menu_option_2)"
    echo ""

    # Crear lista de usuarios normales (excluyendo sistema)
    local -a users=()
    while IFS= read -r user; do
        local uid=$(id -u "$user" 2>/dev/null || echo 0)
        # Solo usuarios normales (UID >= 1000 y != 65534)
        if [ "$uid" -ge 1000 ] && [ "$uid" -ne 65534 ]; then
            users+=("$user")
        fi
    done < <(getent passwd | cut -d: -f1)

    if [ ${#users[@]} -eq 0 ]; then
        print_warning "No hay usuarios regulares para eliminar"
        pause_execution
        return
    fi

    # Mostrar lista numerada
    print_info "Usuarios disponibles para eliminar:"
    echo ""
    for i in "${!users[@]}"; do
        local user="${users[$i]}"
        local comment=$(getent passwd "$user" | cut -d: -f5 | cut -d, -f1)
        local home=$(getent passwd "$user" | cut -d: -f6)
        if [ -n "$comment" ]; then
            echo -e "  ${GREEN}$((i+1)):${NC} $user ($comment) [$home]"
        else
            echo -e "  ${GREEN}$((i+1)):${NC} $user [$home]"
        fi
    done
    echo ""

    # Seleccionar usuario por número
    read_input_with_escape "$(user_msg select_option) (1-${#users[@]})"
    local choice="$READ_INPUT"

    # Check if cancelled
    if [ -z "$choice" ] || [ "$choice" = "ESC" ] || [ "$choice" = "BACK" ]; then
        return
    fi

    # Validar selección
    if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt ${#users[@]} ]; then
        print_error "$(user_msg invalid_option)"
        pause_execution
        return
    fi

    local username="${users[$((choice-1))]}"

    if ask_yes_no "$(user_msg confirm_delete)"; then
        if userdel -r "$username" 2>/dev/null; then
            print_success "$(user_msg user_deleted)"
            log_message "INFO" "User deleted: $username"
        else
            print_error "Error deleting user"
            log_message "ERROR" "Failed to delete user: $username"
        fi
    else
        print_info "$(user_msg operation_cancelled)"
    fi

    pause_execution
}

# ============================================================================
# MODIFY USER FUNCTION
# ============================================================================

modify_user() {
    show_header
    print_info "$(user_msg menu_option_3)"
    echo ""

    # Crear lista de usuarios normales (excluyendo sistema)
    local -a users=()
    while IFS= read -r user; do
        local uid=$(id -u "$user" 2>/dev/null || echo 0)
        # Solo usuarios normales (UID >= 1000 y != 65534)
        if [ "$uid" -ge 1000 ] && [ "$uid" -ne 65534 ]; then
            users+=("$user")
        fi
    done < <(getent passwd | cut -d: -f1)

    if [ ${#users[@]} -eq 0 ]; then
        print_warning "No hay usuarios regulares para modificar"
        pause_execution
        return
    fi

    # Mostrar lista numerada
    print_info "Usuarios disponibles para modificar:"
    echo ""
    for i in "${!users[@]}"; do
        local user="${users[$i]}"
        local comment=$(getent passwd "$user" | cut -d: -f5 | cut -d, -f1)
        local home=$(getent passwd "$user" | cut -d: -f6)
        if [ -n "$comment" ]; then
            echo -e "  ${GREEN}$((i+1)):${NC} $user ($comment) [$home]"
        else
            echo -e "  ${GREEN}$((i+1)):${NC} $user [$home]"
        fi
    done
    echo ""

    # Seleccionar usuario por número
    read_input_with_escape "$(user_msg select_option) (1-${#users[@]})"
    local choice="$READ_INPUT"

    # Check if cancelled
    if [ -z "$choice" ] || [ "$choice" = "ESC" ] || [ "$choice" = "BACK" ]; then
        return
    fi

    # Validar selección
    if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt ${#users[@]} ]; then
        print_error "$(user_msg invalid_option)"
        pause_execution
        return
    fi

    local username="${users[$((choice-1))]}"
    local new_shell
    local new_comment
    local new_home
    local change_pass

    echo ""
    print_info "Modificando usuario: $username"
    echo ""
    print_info "Dejar en blanco para no modificar"
    echo ""

    # Modify shell
    read_input_with_escape "$(user_msg enter_shell)"
    new_shell="$READ_INPUT"
    if [ "$new_shell" = "ESC" ] || [ "$new_shell" = "BACK" ]; then
        return
    elif [ -n "$new_shell" ]; then
        usermod -s "$new_shell" "$username"
    fi

    # Modify comment
    read_input_with_escape "$(user_msg enter_comment)"
    new_comment="$READ_INPUT"
    if [ "$new_comment" = "ESC" ] || [ "$new_comment" = "BACK" ]; then
        return
    elif [ -n "$new_comment" ]; then
        usermod -c "$new_comment" "$username"
    fi

    # Modify home
    read_input_with_escape "$(user_msg enter_home)"
    new_home="$READ_INPUT"
    if [ "$new_home" = "ESC" ] || [ "$new_home" = "BACK" ]; then
        return
    elif [ -n "$new_home" ]; then
        usermod -d "$new_home" -m "$username" 2>/dev/null || true
    fi

    # Cambio de contraseña
    echo ""
    read_input_with_escape "$(user_msg user_new_password_prompt)"
    change_pass="$READ_INPUT"
    
    if [ "$change_pass" = "ESC" ] || [ "$change_pass" = "BACK" ]; then
        return
    fi

    if [ "$change_pass" = "s" ] || [ "$change_pass" = "S" ] || [ "$change_pass" = "y" ] || [ "$change_pass" = "Y" ]; then
        if passwd "$username"; then
            print_success "$(user_msg user_password_changed)"
            log_message "INFO" "Password changed for user: $username"
        else
            print_error "$(user_msg user_password_change_failed)"
            log_message "ERROR" "Failed to change password for: $username"
        fi
    fi

    print_success "$(user_msg user_modified)"
    log_message "INFO" "User modified: $username"
    pause_execution
}

# ============================================================================
# LIST USERS FUNCTION
# ============================================================================

list_users() {
    local content=""
    local regular_users_list
    local system_users_list

    # Add to breadcrumb
    breadcrumb_push "$(msg bc_users_list)"

    # Get user lists
    regular_users_list=$(awk -F: '$3 >= 1000 && $1 != "nobody" {print "\t- " $1 " (" $5 ") [" $6 "]"}' /etc/passwd)
    system_users_list=$(awk -F: '$3 < 1000 && $1 != "root" {print "\t- " $1}' /etc/passwd)

    content+="${BLUE}[$(user_msg user_list)]${NC}\n\n"
    content+="${BLUE}$(user_msg regular_users)${NC}\n"
    content+="$regular_users_list\n"
    content+="\n${BLUE}$(user_msg system_users)${NC}\n"
    content+="$system_users_list"

    while true; do
        show_with_pager "$content"
        
        # Check if user selected something (PAGER_SELECTED_ITEM is set after selection)
        if [ -n "${PAGER_SELECTED_ITEM:-}" ]; then
            # Extract username from selected line (format: "  - username (comment) [home]" or "  - username")
            local selected_username
            selected_username=$(echo "$PAGER_SELECTED_ITEM" | sed 's/^[[:space:]]*-[[:space:]]*//; s/[[:space:]]*(.*//' | xargs)
            
            if [ -n "$selected_username" ]; then
                show_user_info "$selected_username"
                PAGER_SELECTED_ITEM=""
            fi
        else
            # User pressed 'b' to exit
            break
        fi
    done
    
    # Remove from breadcrumb when done
    breadcrumb_pop
}

# ============================================================================
# CREATE GROUP FUNCTION
# ============================================================================

create_group() {
    show_header
    print_info "$(user_msg create_group)"
    echo ""

    local groupname

    while true; do
        read_input_with_escape "$(user_msg enter_groupname)"
        groupname="$READ_INPUT"

        if [ -z "$groupname" ] || [ "$groupname" = "ESC" ] || [ "$groupname" = "BACK" ]; then
            return
        fi

        if ! [[ $groupname =~ ^[a-z_][a-z0-9_-]*$ ]]; then
            print_error "$(user_msg invalid_username)"
            continue
        fi

        if getent group "$groupname" &>/dev/null; then
            print_error "$(user_msg group_exists)"
            continue
        fi

        break
    done

    if groupadd "$groupname"; then
        print_success "$(user_msg group_created)"
        log_message "INFO" "Group created: $groupname"
    else
        print_error "Error creating group"
        log_message "ERROR" "Failed to create group: $groupname"
    fi

    pause_execution
}

# ============================================================================
# DELETE GROUP FUNCTION
# ============================================================================

delete_group() {
    show_header
    print_info "$(user_msg delete_group)"
    echo ""

    local groupname

    read_input_with_escape "$(user_msg enter_groupname)"
    groupname="$READ_INPUT"

    if [ -z "$groupname" ] || [ "$groupname" = "ESC" ] || [ "$groupname" = "BACK" ]; then
        return
    fi

    if ! getent group "$groupname" &>/dev/null; then
        print_error "$(user_msg group_not_found)"
        pause_execution
        return
    fi

    if ask_yes_no "$(user_msg confirm_group_delete)"; then
        if groupdel "$groupname" 2>/dev/null; then
            print_success "$(user_msg group_deleted)"
            log_message "INFO" "Group deleted: $groupname"
        else
            print_error "Error deleting group"
            log_message "ERROR" "Failed to delete group: $groupname"
        fi
    else
        print_info "$(user_msg operation_cancelled)"
    fi

    pause_execution
}

# ============================================================================
# LIST GROUPS FUNCTION
# ============================================================================

list_groups() {
    local content=""
    local groups_list

    # Add to breadcrumb
    breadcrumb_push "$(msg bc_groups_list)"

    groups_list=$(awk -F: '{print "\t- " $1}' /etc/group | sort)
    
    content+="${BLUE}[$(user_msg group_menu)]${NC}\n\n"
    content+="$groups_list"

    while true; do
        show_with_pager "$content"
        
        # Check if user selected something
        if [ -n "${PAGER_SELECTED_ITEM:-}" ]; then
            # Extract groupname from selected line (format: "  - groupname")
            local selected_groupname
            selected_groupname=$(echo "$PAGER_SELECTED_ITEM" | sed 's/^[[:space:]]*-[[:space:]]*//; s/[[:space:]]*$//' | xargs)
            
            if [ -n "$selected_groupname" ]; then
                show_group_info "$selected_groupname"
                PAGER_SELECTED_ITEM=""
            fi
        else
            # User pressed 'b' to exit
            break
        fi
    done
    
    # Remove from breadcrumb when done
    breadcrumb_pop
}

# ============================================================================
# GROUPS SUBMENU
# ============================================================================

groups_menu() {
    # Add Groups to breadcrumb
    breadcrumb_push "$(msg bc_groups)"

    while true; do
        show_header
        print_info "$(user_msg group_menu)"
        echo ""
        echo "  1) $(user_msg create_group)"
        echo "  2) $(user_msg delete_group)"
        echo "  3) $(user_msg list_groups)"
        echo ""
        echo -e "  ${YELLOW}$(user_msg menu_option_0)${NC}"
        echo ""

        read_menu_option "$(user_msg select_option): "
        local option="$MENU_INPUT"

        # ESC pressed - go back
        [[ "$option" == "ESC" ]] && {
            breadcrumb_pop
            return
        }

        case "$option" in
            1)
                create_group
                ;;
            2)
                delete_group
                ;;
            3)
                list_groups
                ;;
            0|"")
                breadcrumb_pop
                return
                ;;
            *)
                print_error "$(user_msg invalid_option)"
                pause_execution
                ;;
        esac
    done
}

# ============================================================================
# MAIN MENU
# ============================================================================

main_menu() {
    # Set breadcrumb for users module
    breadcrumb_set "Synex Control" "$(msg bc_users)"

    while true; do
        show_header
        print_info "$(user_msg menu_title)"
        echo ""
        echo "  $(user_msg menu_option_1)"
        echo "  $(user_msg menu_option_2)"
        echo "  $(user_msg menu_option_3)"
        echo "  $(user_msg menu_option_4)"
        echo "  $(user_msg menu_option_5)"
        echo ""
        echo -e "  ${YELLOW}$(user_msg menu_option_0)${NC}"
        echo ""

        read_menu_option "$(user_msg select_option): "
        local option="$MENU_INPUT"

        # ESC or 0 pressed - exit
        [[ "$option" == "ESC" || "$option" == "0" ]] && {
            print_success "$(user_msg operation_cancelled)"
            return
        }

        case "$option" in
            1)
                create_user
                ;;
            2)
                delete_user
                ;;
            3)
                modify_user
                ;;
            4)
                list_users
                ;;
            5)
                groups_menu
                ;;
            *)
                print_error "$(user_msg invalid_option)"
                pause_execution
                ;;
        esac
    done
}

# ============================================================================
# MAIN EXECUTION
# ============================================================================

main_menu
