import { LowCodeModuleParser, IEvaledModule, LowcodeContext } from './base';

export class ComputedParser implements LowCodeModuleParser {
  computed: LowcodeContext['computed'];

  funcs: any;

  onStart(context: LowcodeContext) {
    this.computed = {};
    this.funcs = {};
  }

  parseModule(pageId: string, mod: IEvaledModule) {
    const computedFuncs = mod.exports.default || mod.exports;
    if (typeof computedFuncs !== 'object') {
      throw new Error('computed must export an object');
    }

    this.computed[pageId] = createComputed(computedFuncs);
    this.funcs[pageId] = computedFuncs;
  }

  onEnd(context: LowcodeContext) {
    context.computed = this.computed;
    context.computedFuncs = this.funcs;
  }
}

export function createComputed(computedFuncs, thisArg?) {
  const computedObj = {};
  Object.keys(computedFuncs).forEach((name) => {
    const getter = computedFuncs[name];
    Object.defineProperty(computedObj, name, {
      get: thisArg ? getter.bind(thisArg) : getter,
      enumerable: true,
    });
  });
  return computedObj;
}
