import { forceInteractive as u } from "@geoscene/core/applications/Components/analysisUtils.js";
import d from "@geoscene/core/core/Accessor.js";
import { property as a, subclass as v } from "@geoscene/core/core/accessorSupport/decorators.js";
import { ignoreAbortErrors as f } from "@geoscene/core/core/promiseUtils.js";
import { when as V, watch as y, on as m, whenOnce as A } from "@geoscene/core/core/reactiveUtils.js";
import { c as p, i as b, t as g, a as O } from "./async-utils.js";
import { a as l, r as w } from "./maybe.js";
/*! All material copyright GeoScene, All Rights Reserved, unless otherwise specified.
See https://js.geoscene.cn/4.33/geoscene/copyright.txt for details.
v4.33.18 */
var U = Object.defineProperty, F = Object.getOwnPropertyDescriptor, i = (s, t, n, r) => {
  for (var o = r > 1 ? void 0 : r ? F(t, n) : t, c = s.length - 1, h; c >= 0; c--)
    (h = s[c]) && (o = (r ? h(t, n, o) : h(o)) || o);
  return r && o && U(t, n, o), o;
};
let e = class extends d {
  // No properties are set in the constructor. The component should support assignments at any time and component
  // properties are only assigned after the view models is constructed.
  constructor() {
    super({}), this._ownsAnalysis = !1, this._operationState = "inactive", this._loggedUnsupportedErrorMessage = !1, this._changeFromReconnect = !1, this._startUserOperation = null;
  }
  initialize() {
    this._set("analysis", this.constructAnalysis()), this._ownsAnalysis = !0;
    const s = () => {
      !this._changeFromReconnect && !this._viewHasAnalysis && (this._ownsAnalysis = !1);
      const t = !this._changeFromReconnect;
      this._changeFromReconnect = !1, t && this._scheduleViewReconnect();
    };
    this.addHandles([
      V(
        () => this.view != null && this.view.ready && !this.supported,
        () => {
          this._loggedUnsupportedErrorMessage || console.error(this.unsupportedErrorMessage);
        },
        { sync: !0, initial: !0 }
      ),
      y(() => [this.analysis, this._viewHasAnalysis], s, { sync: !0 }),
      m(
        () => this.view,
        "analysis-view-destroy",
        (t) => {
          t.analysis === this.analysis && s();
        }
      ),
      y(
        () => ({
          view: this.view,
          ready: !!this.view?.ready,
          supported: this.supported
        }),
        ({ view: t }, n) => {
          const r = n?.view;
          t !== r && (this._startUserOperation = l(this._startUserOperation), this._disconnectFromView(r)), this._scheduleViewReconnect();
        },
        { sync: !0, initial: !0 }
      )
    ]);
  }
  destroy() {
    this._reconnectViewTask = l(this._reconnectViewTask), this._startUserOperation = l(this._startUserOperation), this._analysisView != null && (this._analysisView.visible = void 0), this._disconnectFromView(this.view), this._set("view", null), this._ownsAnalysis && this.analysis?.destroy();
  }
  get supported() {
    return this.view == null || this.view.type === this.supportedViewType;
  }
  set visible(s) {
    this._set("visible", s), this._analysisView != null && (this._analysisView.visible = s);
  }
  get active() {
    return this._startUserOperation?.state === 2;
  }
  get disabled() {
    return this.view == null || !this.view.ready || !this.supported;
  }
  set analysis(s) {
    s !== this._get("analysis") && (this._startUserOperation = l(this._startUserOperation), this._disconnectFromView(this.view), this._setExternalAnalysis(s), this._scheduleViewReconnect());
  }
  get analysisView() {
    return this._analysisView;
  }
  get ready() {
    return this._analysisView != null && !this.connectingToView;
  }
  get connectingToView() {
    return this._reconnectViewTask != null;
  }
  get _viewHasAnalysis() {
    const { view: s } = this;
    return s?.analyses.includes(this.analysis) === !0;
  }
  get operationState() {
    return this._operationState;
  }
  /**
   * Removes the tool and clears the analysis by resetting its inputs.
   */
  clear() {
    this.clearAnalysis(), this._startUserOperation = l(this._startUserOperation);
  }
  /**
   * If analysis has unset inputs, start() will kick off the user operation to specify those inputs.
   */
  async start(s) {
    if (!this.visible) {
      console.warn("Cannot start analysis when not visible");
      return;
    }
    const t = {
      task: null,
      abort: null,
      state: 0
      /* PENDING */
    }, n = p(async (r) => {
      if (t.state = 1, await A(() => this.ready, r), t.state = 2, this._analysisView == null || this.view == null)
        return;
      this._operationState = "active";
      const o = s?.({ signal: r }) ?? this.place({ signal: r });
      await f(o);
    });
    return n.promise.finally(() => {
      (this._startUserOperation === t || this._startUserOperation == null) && (this._operationState = "inactive");
    }), t.task = n, t.abort = () => n.abort(), this._startUserOperation = t, await n.promise;
  }
  async startNewAnalysis() {
    this.clear(), await this.start();
  }
  async continue() {
    await this.start();
  }
  stop() {
    this._startUserOperation = l(this._startUserOperation);
  }
  /**
   * A callback used by view models that manage an analysis belonging to an Layer.
   *
   * The function will be called each time the view becomes ready, the internal Layer of
   * the view model has been added to the map and the analysis view of the analysis has been created.
   */
  onConnectToAnalysisView(s) {
  }
  /**
   * A callback used by view models that manage an analysis.
   *
   * The function will be called each time the view becomes unready and the internal analysis
   * has been removed the map or analyses.
   */
  onDisconnectFromAnalysisView() {
  }
  _scheduleViewReconnect() {
    this._reconnectViewTask = l(this._reconnectViewTask);
    const s = p(async (t) => {
      try {
        await this._reconnectView(t);
      } catch (n) {
        if (g(t), !O(n)) {
          console.warn("Failed to use analysis in view model", n);
          return;
        }
        throw n;
      } finally {
        s === this._reconnectViewTask && (this._reconnectViewTask = void 0);
      }
    });
    this._reconnectViewTask = s;
  }
  async _reconnectView(s) {
    const { view: t } = this, n = t != null && t.ready && this.supported, r = this.analysis;
    if (this._startUserOperation = _(this._startUserOperation), this._disconnectFromView(t), !n || t == null || r == null)
      return;
    this._ownsAnalysis && (this._changeFromReconnect = !0, t.analyses.add(r));
    const o = await t.whenAnalysisView(r);
    if (this._analysisView = o, b(s)) {
      this._startUserOperation = _(this._startUserOperation);
      return;
    }
    o.visible = this.visible, this._forceInteractiveHandle = u(o), this.addHandles(this._forceInteractiveHandle), this.onConnectToAnalysisView(o);
  }
  _disconnectFromView(s) {
    s != null && this._ownsAnalysis && s.analyses.includes(this.analysis) && (this._changeFromReconnect = !0, this.analysis.clear(), s.analyses.remove(this.analysis)), this.onDisconnectFromAnalysisView(), this._forceInteractiveHandle = w(this._forceInteractiveHandle), this._analysisView = void 0;
  }
  _setExternalAnalysis(s) {
    this._analysisView != null && !this._ownsAnalysis && (this._analysisView.visible = void 0, this._forceInteractiveHandle = w(this._forceInteractiveHandle)), this._analysisView = void 0, this._ownsAnalysis = !1, this._set("analysis", s), this._changeFromReconnect = !1;
  }
};
i([
  a()
], e.prototype, "supported", 1);
i([
  a()
], e.prototype, "view", 2);
i([
  a({ type: Boolean, value: !0 })
], e.prototype, "visible", 1);
i([
  a()
], e.prototype, "active", 1);
i([
  a()
], e.prototype, "disabled", 1);
i([
  a()
], e.prototype, "analysis", 1);
i([
  a()
], e.prototype, "_analysisView", 2);
i([
  a()
], e.prototype, "analysisView", 1);
i([
  a()
], e.prototype, "ready", 1);
i([
  a()
], e.prototype, "connectingToView", 1);
i([
  a()
], e.prototype, "_ownsAnalysis", 2);
i([
  a()
], e.prototype, "_viewHasAnalysis", 1);
i([
  a()
], e.prototype, "_reconnectViewTask", 2);
i([
  a()
], e.prototype, "_forceInteractiveHandle", 2);
i([
  a()
], e.prototype, "_operationState", 2);
i([
  a()
], e.prototype, "operationState", 1);
e = i([
  v("geoscene.components.support.AnalysisViewModel")
], e);
function _(s) {
  return s != null && s.state >= 2 ? (s.abort(), null) : s;
}
export {
  e as A
};