// Минимальный плагин трансформаций: хранит выбранный объект, даёт доступ к pos/rot/scale,
// реагирует на клики по дереву. Трансформации применяются на уровне SceneModel.

export class TransformGizmo {
  constructor({ viewer, sdk, treeView, transformStore, onTargetChange, onTransformChange, sceneModels }) {
    this.viewer = viewer;
    this.scene = viewer.scene;
    this.sdk = sdk;
    this.treeView = treeView;
    this.transformStore = transformStore || {};
    this.sceneModels = sceneModels || {};
    this.onTargetChange = onTargetChange;
    this.onTransformChange = onTransformChange;

    this.mode = "translate"; // translate | rotate | scale
    this.target = null; // { modelId, objectId }

    this._bindTree();
  }

  setMode(next) {
    if (!["translate", "rotate", "scale"].includes(next)) return;
    this.mode = next;
    this._log(`Режим гизмы: ${next}`);
  }

  clearTarget() {
    if (this.target?.objectId) {
      this.scene.setObjectsHighlighted([this.target.objectId], false);
    }
    this.scene.setObjectsHighlighted(this.scene.highlightedObjectIds || [], false);
    this.target = null;
    this.onTargetChange?.(null);
    this._log("Выбор очищен");
  }

  setTarget({ modelId, objectId }) {
    if (!modelId) return;

    this.scene.setObjectsHighlighted(this.scene.highlightedObjectIds || [], false);

    const model = this.sceneModels ? this.sceneModels[modelId] || this.scene.models[modelId] : this.scene.models[modelId];
    if (!model) {
      this._log(`Модель ${modelId} не найдена`, true);
      return;
    }

    // Если указан объект
    if (objectId) {
      const entity = this.scene.objects[objectId];
      if (!entity) {
        this._log(`Объект ${objectId} не найден`, true);
      } else {
        const saved = this.transformStore?.[modelId]?.[objectId];
        if (saved) {
          if (saved.position) model.position = saved.position;
          if (saved.rotation) model.rotation = saved.rotation;
          if (saved.scale) model.scale = saved.scale;
        }
        this.onTargetChange?.({
          modelId,
          objectId,
          transform: {
            position: [...model.position],
            rotation: [...model.rotation],
            scale: model.scale ? [...model.scale] : [1, 1, 1],
          },
        });
        this.scene.setObjectsHighlighted([objectId], true);
        this.target = { modelId, objectId };
        return;
      }
    }

    // Если objectId нет, работаем всей моделью
    const ids = Object.keys(model.objects || {});
    if (ids.length) {
      this.scene.setObjectsHighlighted(ids, true);
    }
    this.onTargetChange?.({
      modelId,
      objectId: null,
      transform: {
        position: [...model.position],
        rotation: [...model.rotation],
        scale: model.scale ? [...model.scale] : [1, 1, 1],
      },
    });
    this.target = { modelId, objectId: null };
  }

  handleTreeNodeClick(evt) {
    const node = evt?.treeViewNode || evt?.node || evt;
    const objectId = node?.objectId || node?.id || node?.object?.id || node?.entityId || node?.objectIdGiven;
    const modelId = node?.modelId || node?.model?.id || node?.modelID || node?.model?.modelId || node?.modelIdGiven;
    if (objectId && modelId) {
      this.setTarget({ modelId, objectId });
    } else if (modelId) {
      // нет objectId - подсветим всю модель
      const model = this.scene.models[modelId];
      if (model) {
        const ids = Object.keys(model.objects || {});
        this.scene.setObjectsHighlighted(this.scene.highlightedObjectIds || [], false);
        this.scene.setObjectsHighlighted(ids, true);
        this.target = { modelId, objectId: null };
      }
    }
  }

  updateTransform({ position, rotation, scale }) {
    if (!this.target?.modelId) return;
    const model = this.sceneModels ? this.sceneModels[this.target.modelId] || this.scene.models[this.target.modelId] : this.scene.models[this.target.modelId];
    if (!model) return;
    if (position) model.position = position;
    if (rotation) model.rotation = rotation;
    if (scale) model.scale = scale;
    // сохраняем в store
    if (!this.transformStore[this.target.modelId]) {
      this.transformStore[this.target.modelId] = {};
    }
    const key = this.target.objectId || "__model__";
    this.transformStore[this.target.modelId][key] = {
      position: [...model.position],
      rotation: [...model.rotation],
      scale: model.scale ? [...model.scale] : [1, 1, 1],
    };
    this.onTransformChange?.({
      modelId: this.target.modelId,
      objectId: this.target.objectId,
      transform: {
        position: [...model.position],
        rotation: [...model.rotation],
        scale: model.scale ? [...model.scale] : [1, 1, 1],
      },
    });
  }

  _bindTree() {
    if (this.treeView?.on) {
      this.treeView.on("nodeTitleClicked", (e) => this.handleTreeNodeClick(e));
      // подстрахуемся: некоторые деревья бросают другой эвент
      this.treeView.on("nodeClicked", (e) => this.handleTreeNodeClick(e));
    }
  }

  _log(msg, isError = false) {
    if (isError) {
      console.error("[TransformGizmo]", msg);
    } else {
      console.log("[TransformGizmo]", msg);
    }
  }
}
