import Command from '../command';
import { COMMAND_TYPE } from '../constants';

function cloneStyle(style = {}) {
  return JSON.parse(JSON.stringify(style || {}));
}

export default class SetOriginalModelStyleCommand extends Command {
  constructor(service, uuid, style = {}) {
    super(service);
    this.type = COMMAND_TYPE.SET_ORIGINAL_MODEL_STYLE;
    this.name = '修改原始模型样式';
    this.updatable = true;
    this.object = service.getObjectByUuid(uuid);
    this.uuid = uuid;
    // 首次修改前必须先固化原始样式基线，否则“还原”会回到已修改后的状态。
    service.ensureOriginalModelBaseline(uuid);
    this.oldStyle = service.getOriginalModelStyleValue(uuid);
    this.newStyle = service.mergeOriginalModelStyle(this.oldStyle, style);
  }

  execute() {
    if (!this.object) return;
    this.service.applyOriginalModelStyle(this.uuid, this.newStyle);
    this.service.syncOriginalModelStyleRecord(this.uuid);
  }

  undo() {
    if (!this.object) return;
    this.service.applyOriginalModelStyle(this.uuid, this.oldStyle);
    this.service.syncOriginalModelStyleRecord(this.uuid);
  }

  canUpdate(command, deltaTime, mergeWindow) {
    return (
      command &&
      command.type === this.type &&
      command.uuid === this.uuid &&
      deltaTime <= mergeWindow
    );
  }

  update(command) {
    this.newStyle = cloneStyle(command.newStyle);
  }

  getChangedKeys() {
    const changedKeys = [];
    ['color', 'opacity', 'visible'].forEach(key => {
      if (this.oldStyle[key] !== this.newStyle[key]) {
        changedKeys.push(key);
      }
    });
    return changedKeys;
  }
}
