import { shuffle } from "@thi.ng/arrays/shuffle";
import { isPlainObject } from "@thi.ng/checks";
import { SYSTEM } from "@thi.ng/random/system";
import { __iter, iterator } from "./iterator.js";
import { isReduced } from "./reduced.js";
function streamShuffle(...args) {
  return __iter(streamShuffle, args, iterator) || (([init, complete, reduce]) => {
    let n;
    let maxSwaps;
    let rnd = SYSTEM;
    const opts = args[0];
    if (isPlainObject(opts)) {
      n = opts.n;
      maxSwaps = opts.max || n;
      opts.rnd && (rnd = opts.rnd);
    } else {
      n = args[0];
      maxSwaps = args[1] || n;
    }
    const buf = [];
    return [
      init,
      (acc) => {
        if (buf.length) {
          shuffle(buf, Math.min(maxSwaps, buf.length), rnd);
          for (let i = 0, n2 = buf.length; i < n2 && !isReduced(acc); i++) {
            acc = reduce(acc, buf[i]);
          }
        }
        buf.length = 0;
        acc = complete(acc);
        return acc;
      },
      (acc, x) => {
        buf.push(x);
        if (buf.length === n) {
          shuffle(buf, Math.min(maxSwaps, n), rnd);
          acc = reduce(acc, buf.shift());
        }
        return acc;
      }
    ];
  });
}
export {
  streamShuffle
};
