"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var ManagedReference_exports = {};
__export(ManagedReference_exports, {
  ManagedReference: () => ManagedReference
});
module.exports = __toCommonJS(ManagedReference_exports);
var import_protocol = require("#protocol");
/**
 * @license
 * Copyright 2022-2025 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
function ManagedReference(parent, primaryKey, name, id, assertWriteOk, clone, session) {
  let expired = false;
  let location = {
    ...parent.location,
    path: parent.location.path.at(name)
  };
  const key = primaryKey === "id" ? id ?? name : name;
  const altKey = primaryKey === "id" ? key === name ? void 0 : name : id;
  let value;
  let dynamicContainer;
  if (parent.value[import_protocol.Val.properties]) {
    dynamicContainer = parent.value[import_protocol.Val.properties](parent.rootOwner, session);
    if (key in dynamicContainer) {
      value = dynamicContainer[key];
    } else if (altKey !== void 0 && altKey in dynamicContainer) {
      value = dynamicContainer[altKey];
    } else {
      dynamicContainer = void 0;
    }
  }
  if (dynamicContainer === void 0) {
    if (key in parent.value) {
      value = parent.value[key];
    } else if (altKey !== void 0) {
      value = parent.value[altKey];
    }
  }
  const reference = {
    primaryKey,
    parent,
    get rootOwner() {
      return parent.rootOwner;
    },
    get value() {
      return value;
    },
    get expired() {
      return expired;
    },
    get location() {
      return location;
    },
    set location(loc) {
      location = loc;
    },
    set value(newValue) {
      if (value === newValue) {
        return;
      }
      assertWriteOk(newValue);
      replaceValue(newValue);
      this.change(() => {
        if (dynamicContainer) {
          dynamicContainer[key] = newValue;
          if (altKey !== void 0 && altKey in dynamicContainer) {
            delete dynamicContainer[altKey];
          }
        } else {
          parent.value[key] = newValue;
          if (altKey !== void 0 && altKey in parent.value) {
            delete parent.value[altKey];
          }
        }
      });
    },
    get original() {
      if (!parent.original) {
        return void 0;
      }
      if (dynamicContainer !== void 0) {
        const origProperties = parent.original[import_protocol.Val.properties](parent.rootOwner, session);
        if (key in origProperties) {
          return origProperties[key];
        }
        if (altKey !== void 0) {
          return origProperties[altKey];
        }
      } else {
        if (key in parent.original) {
          return parent.original[key];
        }
        if (altKey !== void 0) {
          return parent.original[altKey];
        }
      }
    },
    change(mutator) {
      if (expired) {
        throw new import_protocol.ExpiredReferenceError(this.location);
      }
      parent.change(() => {
        if (clone && value === this.original) {
          const newValue = clone(value);
          if (dynamicContainer !== void 0) {
            dynamicContainer[key] = newValue;
            if (altKey !== void 0 && altKey in dynamicContainer) {
              delete dynamicContainer[altKey];
            }
          } else {
            parent.value[key] = newValue;
            if (altKey !== void 0 && altKey in parent.value) {
              delete parent.value[altKey];
            }
          }
          replaceValue(newValue);
        }
        mutator();
      });
    },
    refresh() {
      if (parent.expired) {
        expired = true;
        return;
      }
      if (parent.value === void 0 || parent.value === null) {
        expired = true;
        replaceValue(void 0);
        return;
      }
      let value2;
      if (dynamicContainer !== void 0) {
        if (key in dynamicContainer) {
          value2 = dynamicContainer[key];
        } else if (altKey !== void 0 && altKey in dynamicContainer) {
          value2 = dynamicContainer[altKey];
        }
      } else {
        if (key in parent.value) {
          value2 = parent.value[key];
        } else if (altKey !== void 0 && altKey in parent.value) {
          value2 = parent.value[altKey];
        }
      }
      replaceValue(value2);
    }
  };
  if (!parent.subrefs) {
    parent.subrefs = {};
  }
  parent.subrefs[key] = reference;
  return reference;
  function replaceValue(newValue) {
    value = newValue;
    const subrefs = reference.subrefs;
    if (subrefs) {
      for (const key2 in subrefs) {
        subrefs[key2].refresh();
      }
    }
  }
}
//# sourceMappingURL=ManagedReference.js.map
