const compose = (...fn) => (...x) => fn.reduce((a, b) => c => a(b(c)))(...x);
const toString = x => x + '';
const reverse = x => Array.from(x).reduce((p, c) => [c, ...p], []);
const minBiggerThanN = (arr, n) => arr.filter(e => e > n).sort()[0];
const remEl = (arr, e) => {
  const r = arr.indexOf(e);
  return arr.filter((e,i) => i !== r);
}

const nextHighest = itr => {
  const seen = [];
  let result = 0;
  for (const [i,v] of itr.entries()) {
    const n = +v;
    if (Math.max(n, ...seen) !== n) {
      const right = itr.slice(i + 1);
      const swap = minBiggerThanN(seen, n);
      const rem = remEl(seen, swap);
      const rest = [n, ...rem].sort();
      result = [...reverse(right), swap, ...rest].join('');
      break;
    } else {
      seen.push(n);
    }
  }
  return result;
};

const check = compose(nextHighest, reverse, toString);

const test = v => {
  console.log(v, '=>', check(v));
}

test(0);
test(9);
test(12);
test(21);
test(12453);
test(738440);
test(45072010);
test(95322020);
test('9589776899767587796600');