import { stringifyCollection } from '../stringify/stringifyCollection.mjs';
import { Collection } from './Collection.mjs';
import { SEQ, isScalar } from './Node.mjs';
import { isScalarValue } from './Scalar.mjs';
import { toJS } from './toJS.mjs';

class YAMLSeq extends Collection {
  constructor(schema) {
    super(SEQ, schema);
    this.items = [];
  }
  static get tagName() {
    return 'tag:yaml.org,2002:seq';
  }
  add(value) {
    this.items.push(value);
  }
  /**
   * Removes a value from the collection.
   *
   * `key` must contain a representation of an integer for this to succeed.
   * It may be wrapped in a `Scalar`.
   *
   * @returns `true` if the item was found and removed.
   */
  delete(key) {
    const idx = asItemIndex(key);
    if (typeof idx !== 'number') return false;
    const del = this.items.splice(idx, 1);
    return del.length > 0;
  }
  get(key, keepScalar) {
    const idx = asItemIndex(key);
    if (typeof idx !== 'number') return undefined;
    const it = this.items[idx];
    return !keepScalar && isScalar(it) ? it.value : it;
  }
  /**
   * Checks if the collection includes a value with the key `key`.
   *
   * `key` must contain a representation of an integer for this to succeed.
   * It may be wrapped in a `Scalar`.
   */
  has(key) {
    const idx = asItemIndex(key);
    return typeof idx === 'number' && idx < this.items.length;
  }
  /**
   * Sets a value in this collection. For `!!set`, `value` needs to be a
   * boolean to add/remove the item from the set.
   *
   * If `key` does not contain a representation of an integer, this will throw.
   * It may be wrapped in a `Scalar`.
   */
  set(key, value) {
    const idx = asItemIndex(key);
    if (typeof idx !== 'number') throw new Error(`Expected a valid index, not ${key}.`);
    const prev = this.items[idx];
    if (isScalar(prev) && isScalarValue(value)) prev.value = value;else this.items[idx] = value;
  }
  toJSON(_, ctx) {
    const seq = [];
    if (ctx?.onCreate) ctx.onCreate(seq);
    let i = 0;
    for (const item of this.items) seq.push(toJS(item, String(i++), ctx));
    return seq;
  }
  toString(ctx, onComment, onChompKeep) {
    if (!ctx) return JSON.stringify(this);
    return stringifyCollection(this, ctx, {
      blockItemPrefix: '- ',
      flowChars: {
        start: '[',
        end: ']'
      },
      itemIndent: (ctx.indent || '') + '  ',
      onChompKeep,
      onComment
    });
  }
}
function asItemIndex(key) {
  let idx = isScalar(key) ? key.value : key;
  if (idx && typeof idx === 'string') idx = Number(idx);
  return typeof idx === 'number' && Number.isInteger(idx) && idx >= 0 ? idx : null;
}

export { YAMLSeq };
