text: 'use strict';
  
  const _ = require('lodash');
  const { getService } = require('../../../utils');
  const {
    isSortable,
    isSearchable,
    isVisible,
    isRelation,
    getDefaultMainField,
  } = require('./attributes');
  
  function createDefaultMetadatas(schema) {
    return {
      ...Object.keys(schema.attributes).reduce((acc, name) => {
        acc[name] = createDefaultMetadata(schema, name);
        return acc;
      }, {}),
      id: {
        edit: {},
        list: {
          label: 'id',
          searchable: true,
          sortable: true,
        },
      },
    };
  }
  
  function createDefaultMetadata(schema, name) {
    const edit = {
      label: name,
      description: '',
      placeholder: '',
      visible: isVisible(schema, name),
      editable: true,
    };
  
    if (isRelation(schema.attributes[name])) {
      const { targetModel } = schema.attributes[name];
  
      const targetSchema = getTargetSchema(targetModel);
  
      if (targetSchema) {
        edit.mainField = getDefaultMainField(targetSchema);
      }
    }
  
    _.assign(
      edit,
      _.pick(_.get(schema, ['config', 'metadatas', name, 'edit'], {}), [
        'label',
        'description',
        'placeholder',
        'visible',
        'editable',
        'mainField',
      ])
    );
  
    const list = {
      label: name,
      searchable: isSearchable(schema, name),
      sortable: isSortable(schema, name),
      ..._.pick(_.get(schema, ['config', 'metadatas', name, 'list'], {}), [
        'label',
        'searchable',
        'sortable',
      ]),
    };
  
    return { edit, list };
  }
  
  /** Synchronisation functions */
  
  async function syncMetadatas(configuration, schema) {
    // clear all keys that do not exist anymore
    if (_.isEmpty(configuration.metadatas)) {
      return createDefaultMetadatas(schema);
    }
  
    // remove old keys
    const metasWithValidKeys = _.pick(configuration.metadatas, Object.keys(schema.attributes));
  
    // add new keys and missing fields
    const metasWithDefaults = _.merge({}, createDefaultMetadatas(schema), metasWithValidKeys);
  
    // clear the invalid mainFields
    const updatedMetas = Object.keys(metasWithDefaults).reduce((acc, key) => {
      const { edit, list } = metasWithDefaults[key];
      const attr = schema.attributes[key];
  
      let updatedMeta = { edit, list };
      // update sortable attr
      if (list.sortable && !isSortable(schema, key)) {
        _.set(updatedMeta, ['list', 'sortable'], false);
        _.set(acc, [key], updatedMeta);
      }
  
      if (list.searchable && !isSearchable(schema, key)) {
        _.set(updatedMeta, ['list', 'searchable'], false);
        _.set(acc, [key], updatedMeta);
      }
  
      if (!_.has(edit, 'mainField')) return acc;
  
      // remove mainField if the attribute is not a relation anymore
      if (!isRelation(attr)) {
        _.set(updatedMeta, 'edit', _.omit(edit, ['mainField']));
        _.set(acc, [key], updatedMeta);
        return acc;
      }
  
      // if the mainField is id you can keep it
      if (edit.mainField === 'id') return acc;
  
      // check the mainField in the targetModel
      const targetSchema = getTargetSchema(attr.targetModel);
  
      if (!targetSchema) return acc;
  
      if (!isSortable(targetSchema, edit.mainField)) {
        _.set(updatedMeta, ['edit', 'mainField'], getDefaultMainField(targetSchema));
        _.set(acc, [key], updatedMeta);
        return acc;
      }
  
      return acc;
    }, {});
  
    return _.assign(metasWithDefaults, updatedMetas);
  }
  
  const getTargetSchema = targetModel => {
    return getService('content-types').findContentType(targetModel);
  };
  
  module.exports = {
    createDefaultMetadatas,
    syncMetadatas,
  };
  