const pc = window.pc;
import { Debugger as g, sortMapByOrder as E, setsEqual as Q, BaseSystem as S } from "./core.mjs";
import { CompletionType as q, SystemName as b } from "./types.mjs";
function w(m) {
  return m && m.__esModule && Object.prototype.hasOwnProperty.call(m, "default") ? m.default : m;
}
var O = { exports: {} }, P;
function L() {
  return P || (P = 1, (function(m) {
    var t = Object.prototype.hasOwnProperty, e = "~";
    function r() {
    }
    Object.create && (r.prototype = /* @__PURE__ */ Object.create(null), new r().__proto__ || (e = !1));
    function d(a, i, n) {
      this.fn = a, this.context = i, this.once = n || !1;
    }
    function y(a, i, n, o, _) {
      if (typeof n != "function")
        throw new TypeError("The listener must be a function");
      var p = new d(n, o || a, _), l = e ? e + i : i;
      return a._events[l] ? a._events[l].fn ? a._events[l] = [a._events[l], p] : a._events[l].push(p) : (a._events[l] = p, a._eventsCount++), a;
    }
    function k(a, i) {
      --a._eventsCount === 0 ? a._events = new r() : delete a._events[i];
    }
    function h() {
      this._events = new r(), this._eventsCount = 0;
    }
    h.prototype.eventNames = function() {
      var i = [], n, o;
      if (this._eventsCount === 0) return i;
      for (o in n = this._events)
        t.call(n, o) && i.push(e ? o.slice(1) : o);
      return Object.getOwnPropertySymbols ? i.concat(Object.getOwnPropertySymbols(n)) : i;
    }, h.prototype.listeners = function(i) {
      var n = e ? e + i : i, o = this._events[n];
      if (!o) return [];
      if (o.fn) return [o.fn];
      for (var _ = 0, p = o.length, l = new Array(p); _ < p; _++)
        l[_] = o[_].fn;
      return l;
    }, h.prototype.listenerCount = function(i) {
      var n = e ? e + i : i, o = this._events[n];
      return o ? o.fn ? 1 : o.length : 0;
    }, h.prototype.emit = function(i, n, o, _, p, l) {
      var c = e ? e + i : i;
      if (!this._events[c]) return !1;
      var s = this._events[c], f = arguments.length, v, u;
      if (s.fn) {
        switch (s.once && this.removeListener(i, s.fn, void 0, !0), f) {
          case 1:
            return s.fn.call(s.context), !0;
          case 2:
            return s.fn.call(s.context, n), !0;
          case 3:
            return s.fn.call(s.context, n, o), !0;
          case 4:
            return s.fn.call(s.context, n, o, _), !0;
          case 5:
            return s.fn.call(s.context, n, o, _, p), !0;
          case 6:
            return s.fn.call(s.context, n, o, _, p, l), !0;
        }
        for (u = 1, v = new Array(f - 1); u < f; u++)
          v[u - 1] = arguments[u];
        s.fn.apply(s.context, v);
      } else {
        var A = s.length, C;
        for (u = 0; u < A; u++)
          switch (s[u].once && this.removeListener(i, s[u].fn, void 0, !0), f) {
            case 1:
              s[u].fn.call(s[u].context);
              break;
            case 2:
              s[u].fn.call(s[u].context, n);
              break;
            case 3:
              s[u].fn.call(s[u].context, n, o);
              break;
            case 4:
              s[u].fn.call(s[u].context, n, o, _);
              break;
            default:
              if (!v) for (C = 1, v = new Array(f - 1); C < f; C++)
                v[C - 1] = arguments[C];
              s[u].fn.apply(s[u].context, v);
          }
      }
      return !0;
    }, h.prototype.on = function(i, n, o) {
      return y(this, i, n, o, !1);
    }, h.prototype.once = function(i, n, o) {
      return y(this, i, n, o, !0);
    }, h.prototype.removeListener = function(i, n, o, _) {
      var p = e ? e + i : i;
      if (!this._events[p]) return this;
      if (!n)
        return k(this, p), this;
      var l = this._events[p];
      if (l.fn)
        l.fn === n && (!_ || l.once) && (!o || l.context === o) && k(this, p);
      else {
        for (var c = 0, s = [], f = l.length; c < f; c++)
          (l[c].fn !== n || _ && !l[c].once || o && l[c].context !== o) && s.push(l[c]);
        s.length ? this._events[p] = s.length === 1 ? s[0] : s : k(this, p);
      }
      return this;
    }, h.prototype.removeAllListeners = function(i) {
      var n;
      return i ? (n = e ? e + i : i, this._events[n] && k(this, n)) : (this._events = new r(), this._eventsCount = 0), this;
    }, h.prototype.off = h.prototype.removeListener, h.prototype.addListener = h.prototype.on, h.prefixed = e, h.EventEmitter = h, m.exports = h;
  })(O)), O.exports;
}
var N = L();
const x = /* @__PURE__ */ w(N);
class T extends x {
  quest;
  name;
  type;
  _description;
  _isCompleted = !1;
  _onComplete;
  constructor(t, e, r, d) {
    super(), this.quest = t, this.name = e, this._description = d?.description ?? "", this.type = r, this._onComplete = d?.onComplete ?? null;
  }
  get description() {
    return this._description;
  }
  set description(t) {
    this._description = t, this.emit("content-update", { description: t }), this.quest.emit("task:content-update", this, { description: t });
  }
  get isCompleted() {
    return this._isCompleted;
  }
  get onComplete() {
    return this._onComplete ?? null;
  }
  set onComplete(t) {
    this._onComplete = t;
  }
  reset() {
    this._isCompleted = !1, this.emit("reset"), this.quest.emit("task:reset", this), this._onStateUpdate();
  }
  destroy() {
    this._onComplete = null;
  }
  _onStateUpdate() {
    this.emit("state-update"), this.quest.emit("task:state-update", this);
  }
  _complete() {
    if (!this._isCompleted) {
      if (!this.quest.isActive) {
        g.error(`Task ${this.name} is not in an active quest.`);
        return;
      }
      this._isCompleted = !0, this.emit("complete"), this.quest.emit("task:complete", this), this._onStateUpdate(), this._onComplete?.();
    }
  }
}
class U extends T {
  constructor(t, e, r) {
    super(t, e, q.Simple, r);
  }
  complete() {
    this._complete();
  }
}
class M extends T {
  _currentProgress = 0;
  _totalProgress;
  constructor(t, e, r, d) {
    super(t, e, q.Progress, d), this._totalProgress = r;
  }
  get currentProgress() {
    return this._currentProgress;
  }
  get totalProgress() {
    return this._totalProgress;
  }
  reset() {
    super.reset(), this._currentProgress = 0, this.emit("progress-update", this._currentProgress, this._totalProgress);
  }
  addProgress(t = 1) {
    if (!this._isCompleted) {
      if (!this.quest.isActive) {
        g.error(`Task ${this.name} is not in an active quest.`);
        return;
      }
      this._currentProgress = Math.min(this._currentProgress + t, this._totalProgress), this.emit("progress-update", this._currentProgress, this._totalProgress), this.quest?.emit("task:progress-update", this), this._currentProgress >= this._totalProgress ? this._complete() : this._onStateUpdate();
    }
  }
}
class B extends x {
  system;
  name;
  _title;
  _description;
  autoStart;
  _tasks = /* @__PURE__ */ new Map();
  _tasksOrder = [];
  _isCompleted = !1;
  _isActive = !1;
  _onComplete = null;
  constructor(t, e, r) {
    super(), this.system = t, this.name = e, this._title = r?.title || "", this._description = r?.description || "", this.autoStart = r?.autoStart || !1, this._onComplete = r?.onComplete ?? null, r?.tasks && this._setupTasks(r.tasks);
  }
  get title() {
    return this._title;
  }
  set title(t) {
    this._title = t, this.emit("content-update", { title: t, description: this._description });
  }
  get description() {
    return this._description;
  }
  set description(t) {
    this._description = t, this.emit("content-update", { title: this._title, description: t });
  }
  get tasks() {
    return E(this._tasksOrder, this._tasks);
  }
  get tasksOrder() {
    return this._tasksOrder;
  }
  set tasksOrder(t) {
    Q(t, this._tasksOrder) ? (this._tasksOrder = t, this.emit("task-list-update", "reorder")) : g.error("Order array does not match the original order.");
  }
  get isCompleted() {
    return this._isCompleted;
  }
  get isActive() {
    return this._isActive;
  }
  get onComplete() {
    return this._onComplete;
  }
  set onComplete(t) {
    this._onComplete = t;
  }
  start() {
    this._isActive = !0, this.emit("start"), this.system.emit("quest:start", this), this._addEventListeners(), this._validateQuestCompletion();
  }
  reset() {
    this._isCompleted = !1, this._isActive = !1, this._tasks.forEach((t) => {
      t.reset();
    }), this.emit("reset"), this.system.emit("quest:reset", this);
  }
  addTask(t) {
    return this._tasks.has(t.name) ? (g.error(`Task ${t.name} already exists.`), !1) : (this._tasks.set(t.name, t), this._tasksOrder.push(t.name), this.emit("task-list-update", "add"), !0);
  }
  removeTask(t) {
    this._tasks.delete(t.name), this._tasksOrder = this._tasksOrder.filter((e) => e !== t.name), t.destroy(), this.emit("task-list-update", "remove"), this._validateQuestCompletion();
  }
  addSimpleTask(t, e) {
    const r = new U(this, t, e);
    return this.addTask(r), r;
  }
  addProgressTask(t, e, r) {
    const d = new M(this, t, e, r);
    return this.addTask(d), d;
  }
  getTaskByName(t) {
    return this._tasks.get(t) || null;
  }
  destroy() {
    this._removeEventListeners(), this._tasks.forEach((t) => {
      t.destroy();
    }), this._tasks.clear(), this._tasksOrder = [];
  }
  _setupTasks(t) {
    t.forEach((e) => {
      const { description: r, onComplete: d } = e.options;
      if (e.options.type === q.Simple)
        this.addSimpleTask(e.name, {
          description: r,
          onComplete: d
        });
      else if (e.options.type === q.Progress) {
        e.options.totalProgress || g.warn("Total progress must be a valid positive number. Setting to 1.");
        const y = e.options.totalProgress || 1;
        this.addProgressTask(e.name, y, {
          description: r,
          onComplete: d
        });
      }
    });
  }
  _onStateUpdate(t) {
    this.system.emit("quest:task-state-update", this, t);
  }
  _onTaskComplete(t) {
    this._validateQuestCompletion();
  }
  _validateQuestCompletion() {
    if (this._isCompleted) return;
    this.tasks.every((e) => e.isCompleted) && this._tasks.size > 0 && this._complete();
  }
  _complete() {
    this._isCompleted = !0, this.emit("complete"), this.system.emit("quest:complete", this), this._onComplete?.(), this._removeEventListeners();
  }
  _addEventListeners() {
    this.on("task:state-update", this._onStateUpdate.bind(this)), this.on("task:complete", this._onTaskComplete.bind(this));
  }
  _removeEventListeners() {
    this.off("task:state-update"), this.off("task:complete");
  }
}
class z extends S {
  static systemName = b.Quest;
  _quests = /* @__PURE__ */ new Map();
  _questsOrder = [];
  _onAllQuestsComplete = null;
  _options;
  constructor(t, e) {
    if (super(t), this._options = e || {}, this._options) {
      const { quests: r, onAllQuestsComplete: d } = this._options;
      r && this._setupQuests(r), d && (this._onAllQuestsComplete = d);
    }
    this._addEventListeners();
  }
  get quests() {
    return E(this._questsOrder, this._quests);
  }
  get questsOrder() {
    return this._questsOrder;
  }
  set questsOrder(t) {
    Q(t, this._questsOrder) ? (this._questsOrder = t, this.emit("quest-list-update", "reorder")) : g.error("Order array does not match the original order.");
  }
  get onAllQuestsComplete() {
    return this._onAllQuestsComplete;
  }
  set onAllQuestsComplete(t) {
    this._onAllQuestsComplete = t;
  }
  start() {
  }
  addQuest(t, e) {
    const r = new B(this, t, e);
    return this._quests.has(t) ? (g.error(`Quest ${t} already exists.`), this._quests.get(t)) : (this._quests.set(t, r), this._questsOrder.push(t), r.autoStart && r.start(), this.emit("quest-list-update", "add"), r);
  }
  removeQuest(t) {
    this._quests.delete(t.name), this._questsOrder = this._questsOrder.filter((e) => e !== t.name), t.destroy(), this.emit("quest-list-update", "remove");
  }
  resetAllQuests() {
    for (const t of this.quests.values())
      t.reset();
  }
  getQuestByName(t) {
    return this._quests.get(t) || null;
  }
  _setupQuests(t) {
    t.forEach((e) => {
      this.addQuest(e.name, e.options);
    });
  }
  _onQuestComplete(t) {
    this._validateAllQuestsCompletion();
  }
  _validateAllQuestsCompletion() {
    this.quests.every((e) => e.isCompleted) && (this.emit("all-quests-complete"), this._onAllQuestsComplete?.());
  }
  _addEventListeners() {
    this.on("quest:complete", this._onQuestComplete.bind(this));
  }
}
export {
  M as ProgressTask,
  B as Quest,
  z as QuestSystem,
  U as SimpleTask,
  T as Task
};
