import { __require as requireKleur } from '../../../../../kleur@3.0.3/node_modules/kleur/index.mjs';
import { __require as requirePrompt } from './prompt.mjs';
import { __require as requireSrc } from '../../../../../sisteransi@1.0.5/node_modules/sisteransi/src/index.mjs';
import { __require as requireUtil } from '../util/index.mjs';

var number;
var hasRequiredNumber;
function requireNumber() {
  if (hasRequiredNumber) return number;
  hasRequiredNumber = 1;
  const color = requireKleur();
  const Prompt = requirePrompt();
  const {
    cursor,
    erase
  } = requireSrc();
  const {
    style,
    figures,
    clear,
    lines
  } = requireUtil();
  const isNumber = /[0-9]/;
  const isDef = any => any !== undefined;
  const round = (number, precision) => {
    let factor = Math.pow(10, precision);
    return Math.round(number * factor) / factor;
  };

  /**
   * NumberPrompt Base Element
   * @param {Object} opts Options
   * @param {String} opts.message Message
   * @param {String} [opts.style='default'] Render style
   * @param {Number} [opts.initial] Default value
   * @param {Number} [opts.max=+Infinity] Max value
   * @param {Number} [opts.min=-Infinity] Min value
   * @param {Boolean} [opts.float=false] Parse input as floats
   * @param {Number} [opts.round=2] Round floats to x decimals
   * @param {Number} [opts.increment=1] Number to increment by when using arrow-keys
   * @param {Function} [opts.validate] Validate function
   * @param {Stream} [opts.stdin] The Readable stream to listen to
   * @param {Stream} [opts.stdout] The Writable stream to write readline data to
   * @param {String} [opts.error] The invalid error label
   */
  class NumberPrompt extends Prompt {
    constructor(opts = {}) {
      super(opts);
      this.transform = style.render(opts.style);
      this.msg = opts.message;
      this.initial = isDef(opts.initial) ? opts.initial : '';
      this.float = !!opts.float;
      this.round = opts.round || 2;
      this.inc = opts.increment || 1;
      this.min = isDef(opts.min) ? opts.min : -Infinity;
      this.max = isDef(opts.max) ? opts.max : Infinity;
      this.errorMsg = opts.error || `Please Enter A Valid Value`;
      this.validator = opts.validate || (() => true);
      this.color = `cyan`;
      this.value = ``;
      this.typed = ``;
      this.lastHit = 0;
      this.render();
    }
    set value(v) {
      if (!v && v !== 0) {
        this.placeholder = true;
        this.rendered = color.gray(this.transform.render(`${this.initial}`));
        this._value = ``;
      } else {
        this.placeholder = false;
        this.rendered = this.transform.render(`${round(v, this.round)}`);
        this._value = round(v, this.round);
      }
      this.fire();
    }
    get value() {
      return this._value;
    }
    parse(x) {
      return this.float ? parseFloat(x) : parseInt(x);
    }
    valid(c) {
      return c === `-` || c === `.` && this.float || isNumber.test(c);
    }
    reset() {
      this.typed = ``;
      this.value = ``;
      this.fire();
      this.render();
    }
    exit() {
      this.abort();
    }
    abort() {
      let x = this.value;
      this.value = x !== `` ? x : this.initial;
      this.done = this.aborted = true;
      this.error = false;
      this.fire();
      this.render();
      this.out.write(`\n`);
      this.close();
    }
    async validate() {
      let valid = await this.validator(this.value);
      if (typeof valid === `string`) {
        this.errorMsg = valid;
        valid = false;
      }
      this.error = !valid;
    }
    async submit() {
      await this.validate();
      if (this.error) {
        this.color = `red`;
        this.fire();
        this.render();
        return;
      }
      let x = this.value;
      this.value = x !== `` ? x : this.initial;
      this.done = true;
      this.aborted = false;
      this.error = false;
      this.fire();
      this.render();
      this.out.write(`\n`);
      this.close();
    }
    up() {
      this.typed = ``;
      if (this.value === '') {
        this.value = this.min - this.inc;
      }
      if (this.value >= this.max) return this.bell();
      this.value += this.inc;
      this.color = `cyan`;
      this.fire();
      this.render();
    }
    down() {
      this.typed = ``;
      if (this.value === '') {
        this.value = this.min + this.inc;
      }
      if (this.value <= this.min) return this.bell();
      this.value -= this.inc;
      this.color = `cyan`;
      this.fire();
      this.render();
    }
    delete() {
      let val = this.value.toString();
      if (val.length === 0) return this.bell();
      this.value = this.parse(val = val.slice(0, -1)) || ``;
      if (this.value !== '' && this.value < this.min) {
        this.value = this.min;
      }
      this.color = `cyan`;
      this.fire();
      this.render();
    }
    next() {
      this.value = this.initial;
      this.fire();
      this.render();
    }
    _(c, key) {
      if (!this.valid(c)) return this.bell();
      const now = Date.now();
      if (now - this.lastHit > 1000) this.typed = ``; // 1s elapsed
      this.typed += c;
      this.lastHit = now;
      this.color = `cyan`;
      if (c === `.`) return this.fire();
      this.value = Math.min(this.parse(this.typed), this.max);
      if (this.value > this.max) this.value = this.max;
      if (this.value < this.min) this.value = this.min;
      this.fire();
      this.render();
    }
    render() {
      if (this.closed) return;
      if (!this.firstRender) {
        if (this.outputError) this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns));
        this.out.write(clear(this.outputText, this.out.columns));
      }
      super.render();
      this.outputError = '';

      // Print prompt
      this.outputText = [style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(this.done), !this.done || !this.done && !this.placeholder ? color[this.color]().underline(this.rendered) : this.rendered].join(` `);

      // Print error
      if (this.error) {
        this.outputError += this.errorMsg.split(`\n`).reduce((a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
      }
      this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore);
    }
  }
  number = NumberPrompt;
  return number;
}

export { requireNumber as __require };
