import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../analytics';
const whitelistedAttributes = ['align', 'annotationType', 'extensionKey', 'extensionType', 'layout', 'type', 'localId', 'mode', 'language', 'timestamp', 'state', 'originalWidth', 'originalHeight', 'height', 'width', 'shortName', 'level', 'userType', 'order', 'panelType', 'color', 'style', 'isNumberColumnEnabled', 'colspan', 'rowspan', 'colwidth', 'background'];
function concatAncestorHierarchy(node, ancestoryHierarchy) {
  const {
    name
  } = node.type;
  // Space concatenator used to reduce analytics payload size
  return ancestoryHierarchy ? `${ancestoryHierarchy} ${name}` : name;
}
const sanitizeMarks = (marks = []) => {
  let sanitizedMarks = [];
  marks.forEach(mark => {
    if (mark.attrs) {
      const attrs = sanitizeAttributes(mark.attrs);
      sanitizedMarks.push({
        ...mark,
        attrs
      });
    } else {
      sanitizedMarks.push({
        ...mark
      });
    }
  });
  return sanitizedMarks;
};
const sanitizeAttributes = (attrs = {}) => {
  let sanitizedAttrs = Object.assign({}, attrs);
  Object.keys(attrs).filter(key => !whitelistedAttributes.includes(key)).forEach(key => {
    sanitizedAttrs[key] !== null ? sanitizedAttrs[key] = '' : sanitizedAttrs[key] = 'null';
  });
  return sanitizedAttrs;
};
const trackUnsupportedContentTooltipActionFor = (action, dispatchAnalyticsEvent, unsupportedContentType, originalNodeType) => {
  dispatchAnalyticsEvent({
    action: action,
    actionSubjectId: unsupportedContentType,
    actionSubject: ACTION_SUBJECT.TOOLTIP,
    eventType: EVENT_TYPE.UI,
    attributes: {
      unsupportedNodeType: originalNodeType
    }
  });
};
export const findAndTrackUnsupportedContentNodes = (node, schema, dispatchAnalyticsEvent, ancestorHierarchy = '') => {
  const {
    type: nodeType,
    marks: nodeMarks
  } = node;
  const {
    unsupportedMark,
    unsupportedNodeAttribute
  } = schema.marks;
  const {
    unsupportedInline,
    unsupportedBlock
  } = schema.nodes;
  const parentType = ancestorHierarchy.split(' ').pop() || '';
  if (nodeMarks.length) {
    nodeMarks.forEach(mark => {
      if (mark.type === unsupportedMark) {
        const {
          originalValue
        } = mark.attrs || {};
        const {
          type
        } = originalValue || {};
        const unsupportedNode = {
          type: type || '',
          ancestry: ancestorHierarchy,
          parentType: parentType,
          marks: [],
          attrs: originalValue.attrs || {}
        };
        fireUnsupportedEvent(dispatchAnalyticsEvent, ACTION_SUBJECT_ID.UNSUPPORTED_MARK, unsupportedNode);
      } else if (mark.type === unsupportedNodeAttribute) {
        const {
          unsupported
        } = mark.attrs || {};
        const unsupportedNodeAttribute = {
          type: nodeType.name || '',
          ancestry: ancestorHierarchy,
          parentType: parentType,
          marks: [],
          attrs: unsupported || {}
        };
        fireUnsupportedEvent(dispatchAnalyticsEvent, ACTION_SUBJECT_ID.UNSUPPORTED_NODE_ATTRIBUTE, unsupportedNodeAttribute);
      }
    });
  }
  if (nodeType === unsupportedInline || nodeType === unsupportedBlock) {
    const {
      originalValue
    } = node.attrs || {};
    const {
      marks
    } = originalValue || [];
    const {
      attrs
    } = originalValue || {};
    const {
      type
    } = originalValue || {};
    const unsupportedNode = {
      type: type || '',
      ancestry: ancestorHierarchy,
      parentType: parentType,
      marks: marks || [],
      attrs: attrs || {}
    };
    const actionSubjectId = nodeType === unsupportedInline ? ACTION_SUBJECT_ID.UNSUPPORTED_INLINE : ACTION_SUBJECT_ID.UNSUPPORTED_BLOCK;
    fireUnsupportedEvent(dispatchAnalyticsEvent, actionSubjectId, unsupportedNode);
  } else {
    // Recursive check for nested content
    node.content.forEach(childNode => findAndTrackUnsupportedContentNodes(childNode, schema, dispatchAnalyticsEvent, concatAncestorHierarchy(node, ancestorHierarchy)));
  }
};
export const fireUnsupportedEvent = (dispatchAnalyticsEvent, actionSubjectId, unsupportedNode, errorCode) => {
  const sanitizedAttrs = sanitizeAttributes(unsupportedNode.attrs);
  const sanitizedMarks = sanitizeMarks(unsupportedNode.marks);
  const sanitizedUnsupportedNode = {
    type: unsupportedNode.type,
    ancestry: unsupportedNode.ancestry,
    parentType: unsupportedNode.parentType,
    attrs: sanitizedAttrs,
    marks: sanitizedMarks
  };
  const payload = {
    action: ACTION.UNSUPPORTED_CONTENT_ENCOUNTERED,
    actionSubject: ACTION_SUBJECT.DOCUMENT,
    actionSubjectId,
    attributes: {
      unsupportedNode: sanitizedUnsupportedNode,
      ...(!!errorCode && {
        errorCode
      })
    },
    eventType: EVENT_TYPE.TRACK
  };
  dispatchAnalyticsEvent(payload);
};
export const trackUnsupportedContentTooltipDisplayedFor = (dispatchAnalyticsEvent, unsupportedContentType, originalNodeType) => {
  trackUnsupportedContentTooltipActionFor(ACTION.UNSUPPORTED_TOOLTIP_VIEWED, dispatchAnalyticsEvent, unsupportedContentType, originalNodeType);
};