text: 'use strict';
  
  const { has, isNil, mapValues } = require('lodash/fp');
  
  const { getService } = require('../utils');
  const storeUtils = require('./utils/store');
  const createConfigurationService = require('./configuration');
  
  const STORE_KEY_PREFIX = 'components';
  
  const configurationService = createConfigurationService({
    storeUtils,
    isComponent: true,
    prefix: STORE_KEY_PREFIX,
    getModels() {
      const { toContentManagerModel } = getService('data-mapper');
  
      return mapValues(toContentManagerModel, strapi.components);
    },
  });
  
  module.exports = {
    findAllComponents() {
      const { toContentManagerModel } = getService('data-mapper');
  
      return Object.values(strapi.components).map(toContentManagerModel);
    },
  
    findComponent(uid) {
      const { toContentManagerModel } = getService('data-mapper');
  
      const component = strapi.components[uid];
  
      return isNil(component) ? component : toContentManagerModel(component);
    },
  
    // configuration
  
    async findConfiguration(component) {
      const configuration = await configurationService.getConfiguration(component.uid);
  
      return {
        uid: component.uid,
        category: component.categoru,
        ...configuration,
      };
    },
  
    async updateConfiguration(component, newConfiguration) {
      await configurationService.setConfiguration(component.uid, newConfiguration);
  
      return this.findConfiguration(component);
    },
  
    async findComponentsConfigurations(model) {
      const componentsMap = {};
  
      const getComponentConfigurations = async uid => {
        const component = this.findComponent(uid);
  
        if (has(uid, componentsMap)) return;
  
        const componentConfiguration = await this.findConfiguration(component);
        const componentsConfigurations = await this.findComponentsConfigurations(component);
  
        Object.assign(componentsMap, {
          [uid]: componentConfiguration,
          ...componentsConfigurations,
        });
      };
  
      for (const key in model.attributes) {
        const attribute = model.attributes[key];
  
        if (attribute.type === 'component') {
          await getComponentConfigurations(attribute.component);
        }
  
        if (attribute.type === 'dynamiczone') {
          for (const componentUid of attribute.components) {
            await getComponentConfigurations(componentUid);
          }
        }
      }
  
      return componentsMap;
    },
  
    syncConfigurations() {
      return configurationService.syncConfigurations();
    },
  };
  