"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useUpdateField = void 0;
var _react = require("react");
var _i18n = require("@kbn/i18n");
var _mappings_state_context = require("../../../../mappings_state_context");
var _lib = require("../../../../lib");
var _constants = require("../../../../constants");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

const useUpdateField = () => {
  const [state, setState] = (0, _react.useState)({
    isModalOpen: false
  });
  const dispatch = (0, _mappings_state_context.useDispatch)();
  const {
    fields
  } = (0, _mappings_state_context.useMappingsState)();
  const {
    byId,
    aliases
  } = fields;
  const confirmButtonText = _i18n.i18n.translate('xpack.idxMgmt.mappingsEditor.updateField.confirmationModal.confirmDescription', {
    defaultMessage: 'Confirm type change'
  });
  let modalTitle = '';
  if (state.field) {
    const {
      source
    } = state.field;
    modalTitle = _i18n.i18n.translate('xpack.idxMgmt.mappingsEditor.updateField.confirmationModal.title', {
      defaultMessage: "Confirm change '{fieldName}' type to '{fieldType}'.",
      values: {
        fieldName: source.name,
        fieldType: source.type
      }
    });
  }
  const closeModal = () => {
    setState({
      isModalOpen: false
    });
  };
  const updateField = (0, _react.useCallback)(field => {
    const previousField = byId[field.id];
    const willDeleteChildFields = (oldType, newType) => {
      const {
        hasChildFields,
        hasMultiFields
      } = field;
      if (!hasChildFields && !hasMultiFields) {
        // No child or multi-fields will be deleted, no confirmation needed.
        return false;
      }
      return (0, _lib.shouldDeleteChildFieldsAfterTypeChange)(oldType, newType);
    };
    if (field.source.type !== previousField.source.type) {
      // Array of all the aliases pointing to the current field beeing updated
      const aliasesOnField = aliases[field.id] || [];

      // Array of all the aliases pointing to the current field + all its possible children
      const aliasesOnFieldAndDescendants = (0, _lib.getAllDescendantAliases)(field, fields);
      const isReferencedByAlias = aliasesOnField && Boolean(aliasesOnField.length);
      const nextTypeCanHaveAlias = !_constants.PARAMETERS_DEFINITION.path.targetTypesNotAllowed.includes(field.source.type);

      // We need to check if, by changing the type, we will also
      // delete possible child properties ("fields" or "properties").
      // If we will, we need to warn the user about it.
      let requiresConfirmation;
      let aliasesToDelete = [];
      if (isReferencedByAlias && !nextTypeCanHaveAlias) {
        aliasesToDelete = aliasesOnFieldAndDescendants;
        requiresConfirmation = true;
      } else {
        requiresConfirmation = willDeleteChildFields(previousField.source.type, field.source.type);
        if (requiresConfirmation) {
          aliasesToDelete = aliasesOnFieldAndDescendants.filter(
          // We will only delete aliases that points to possible children, *NOT* the field itself
          id => aliasesOnField.includes(id) === false);
        }
      }
      if (requiresConfirmation) {
        setState({
          isModalOpen: true,
          field,
          aliases: Boolean(aliasesToDelete.length) ? aliasesToDelete.map(id => byId[id].path.join(' > ')).sort() : undefined
        });
        return;
      }
    }
    dispatch({
      type: 'field.edit',
      value: field.source
    });
  }, [dispatch, aliases, fields, byId]);
  const confirmTypeUpdate = () => {
    dispatch({
      type: 'field.edit',
      value: state.field.source
    });
    closeModal();
  };
  return {
    updateField,
    modal: {
      isOpen: state.isModalOpen,
      props: {
        childFields: state.field && state.field.childFields,
        title: modalTitle,
        aliases: state.aliases,
        byId,
        confirmButtonText,
        onConfirm: confirmTypeUpdate,
        onCancel: closeModal
      }
    }
  };
};
exports.useUpdateField = useUpdateField;