import { deserializeValue } from '@cloudbase/cals';
import { generateDataBinds } from '../../utils/adapter/generate';

function getDatabinds(expressions = [], ctx, options) {
  const databindMetas = [];
  for (let i = 0; i < expressions.length; i++) {
    const { value: dynamicValue } = deserializeValue({ page: { id: 'index', type: 'PAGE' } }, `:a${i}`, expressions[i]);
    databindMetas.push({
      type: dynamicValue.type,
      bindDataPath: dynamicValue.value,
      propertyPath: `a${i}`,
    });
  }
  const databinds = generateDataBinds(ctx, databindMetas, options);

  return databinds;
}

function expectDatabinds(databinds, toBe, ...args) {
  for (const key in databinds) {
    try {
      expect(databinds[key](...args)).toBe(toBe);
    } catch (e) {
      console.log(key, databinds, databinds[key]);
      throw e;
    }
  }
}

describe('adapter', () => {
  it(`generateDataBinds`, () => {
    const commonExpressions = [
      '$for.id3._id',
      '$for.id3["_id"]',
      // '$for["id3"]["_id"]',
      '$context.id23.data.test',
      "$context['id23']['data']['test']",
    ];

    const appExpressions = [
      'event.detail', // 组件也会用到，listener 的 isComposite 是false 约等于通用的
      '$app.dataset.state.aaa',
      '$app.dataset.state["aaa"]',
      '$page.dataset.state.aaa',
      '$page.dataset.state["aaa"]',
      '$page.dataset.params.aaa',
      '$page.dataset.params["aaa"]',
    ];

    const componentExpression = [
      '$comp.state.aaa',
      '$comp.state["aaa"]',
      '$comp.props.data.id',
      '$comp.props.data["id"]',
      '$comp.props["data"].id',
    ];

    const ctx = {
      $app: {
        dataset: { state: { aaa: '123' } },
      },
      $page: {
        dataset: { state: { aaa: '123' }, params: { aaa: '123' } },
      },
      $comp: new Proxy(
        { props: { data: { id: '123' } }, state: { aaa: '123' } },
        {
          get(target, prop) {
            if (prop === '$comp' || prop === '$WEAPPS_COMP') {
              return this;
            }
            return target[prop];
          },
        },
      ),
    };

    const forContext = {
      id3: { _id: '123' },
    };
    const $context = {
      id23: { data: { test: '123' } },
    };
    const event = {
      detail: '123',
    };

    const appDatabinds = getDatabinds([...commonExpressions, ...appExpressions], ctx, { isComposite: false });
    const compDataBinds = getDatabinds([...commonExpressions, ...componentExpression], ctx, { isComposite: true });

    expectDatabinds(appDatabinds, '123', forContext, event, $context);
    expectDatabinds(compDataBinds, '123', forContext, $context);
  });
});
