JavaScript (ES6), 163 120120 110 bytes
g=([j,...a],n,l)=>l?g(a,a.reduce((r,i)=>r+=i>j,n*l),l-1):n
f=(n,a=[],i=0,r=0,[j,...b]=a)=>n?a.splice(n%-~i,0,i)&&f|f(n/++i|0,a,i):gi?f(an,0b,i-1,b.reduce((r,k)=>r+=k>j,r*i)):r
<input type=number min=0 oninput=o.textContent=f(+this.value)><pre id=o>
0-indexed. Works by converting the index to a permutation, inverting it, then converting back to an index. Edit: Saved about 25% by making f
invert and reverse the permutation, then making g
convert the reversed permutation back to an index. Saved a further 10 bytes by combining the two recursive calls into a single function. Ungolfed:
function index(n) {
var a = [0];
for (var i = 1; n = Math.floor(n / i); i++) {
var j = i - n % (i + 1);
for (var k = 0; k < i; k++) {
if (a[k] > j) a[k]++;
}
a.push(j);
}
a = [...a.keys()].map(k => a.indexOf(k));
while (i) {
n *= i--;
j = a.pop();
for (k = 0; k < i; k++) {
if (a[k] > j) n++;
}
}
return n;
}