// Ignored via go/ees005
// eslint-disable-next-line import/no-namespace
import * as clipboard from 'clipboard-polyfill';
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../analytics';
import { getAllSelectionAnalyticsPayload, getCellSelectionAnalyticsPayload, getNodeSelectionAnalyticsPayload, getRangeSelectionAnalyticsPayload } from '../selection';
const isClipboardApiSupported = () => !!navigator.clipboard && typeof navigator.clipboard.writeText === 'function';
const isIEClipboardApiSupported = () =>
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
window.clipboardData && typeof window.clipboardData.setData === 'function';
const isExtensionNode = node => {
  if (node === 'extension' || node === 'bodiedExtension' || node === 'inlineExtension' || node === 'multiBodiedExtension') {
    return true;
  }
  return false;
};
export const copyToClipboard = async textToCopy => {
  if (isClipboardApiSupported()) {
    try {
      await navigator.clipboard.writeText(textToCopy);
    } catch (error) {
      throw new Error('Clipboard api is not supported');
    }
  } else if (isIEClipboardApiSupported()) {
    try {
      // Ignored via go/ees005
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      await window.clipboardData.setData('text', textToCopy);
    } catch (error) {
      throw new Error('IE clipboard api is not supported');
    }
  } else {
    throw new Error('Clipboard api is not supported');
  }
};

// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
export const copyHTMLToClipboard = async (elementToCopy, plainTextToCopy) => {
  // @ts-ignore
  if (isClipboardApiSupported() && typeof ClipboardItem !== 'undefined') {
    try {
      const data = new ClipboardItem({
        'text/plain': new Blob([plainTextToCopy || elementToCopy.innerText], {
          type: 'text/plain'
        }),
        'text/html': new Blob([elementToCopy.innerHTML], {
          type: 'text/html'
        })
      });
      // @ts-ignore
      await navigator.clipboard.write([data]);
    } catch (error) {
      throw new Error('Clipboard api is not supported');
    }
  } else if (!!document && typeof document === 'object') {
    try {
      // ED-17083 extension copy seems have issue with ClipboardItem API
      // Hence of use of this polyfill
      copyHTMLToClipboardPolyfill(elementToCopy, plainTextToCopy);
    } catch (error) {
      // eslint-disable-next-line no-console
      console.log(error);
    }
  }
};

// At the time of development, Firefox doesn't support ClipboardItem API
// Hence of use of this polyfill
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
export const copyHTMLToClipboardPolyfill = async (elementToCopy, plainTextToCopy) => {
  const dt = new clipboard.ClipboardItem({
    'text/html': new Blob([elementToCopy.innerHTML], {
      type: 'text/html'
    }),
    'text/plain': new Blob([plainTextToCopy || elementToCopy.innerText], {
      type: 'text/plain'
    })
  });
  await clipboard.write([dt]);
};

// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
export const getAnalyticsPayload = (state, action) => {
  const {
    selection,
    doc
  } = state;
  const selectionAnalyticsPayload = getNodeSelectionAnalyticsPayload(selection) || getRangeSelectionAnalyticsPayload(selection, doc) || getAllSelectionAnalyticsPayload(selection) || getCellSelectionAnalyticsPayload(state);
  if (selectionAnalyticsPayload) {
    var _attributes;
    const {
      actionSubjectId: selectionActionSubjectId
    } = selectionAnalyticsPayload;
    const node = (_attributes = selectionAnalyticsPayload.attributes) === null || _attributes === void 0 ? void 0 : _attributes.node;
    const content = [];
    let extensionType;
    let extensionKey;
    switch (selectionActionSubjectId) {
      case ACTION_SUBJECT_ID.NODE:
        if (node) {
          content.push(node);
          if (isExtensionNode(node)) {
            extensionType = selection.node.attrs.extensionType;
            extensionKey = selection.node.attrs.extensionKey;
          }
        }
        break;
      case ACTION_SUBJECT_ID.RANGE:
        // Ignored via go/ees005
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        content.push(...selectionAnalyticsPayload.attributes.nodes);
        break;
      case ACTION_SUBJECT_ID.ALL:
        content.push('all');
        break;
      case ACTION_SUBJECT_ID.CELL:
        {
          // Ignored via go/ees005
          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
          const {
            selectedCells
          } = selectionAnalyticsPayload.attributes;
          content.push(...Array(selectedCells).fill('tableCell'));
          break;
        }
    }
    if (isExtensionNode(node)) {
      return {
        eventType: EVENT_TYPE.TRACK,
        action,
        actionSubject: ACTION_SUBJECT.DOCUMENT,
        attributes: {
          content,
          extensionKey,
          extensionType
        }
      };
    }
    return {
      eventType: EVENT_TYPE.TRACK,
      action,
      actionSubject: ACTION_SUBJECT.DOCUMENT,
      attributes: {
        content
      }
    };
  }
  if (selection instanceof TextSelection && selection.$cursor) {
    return {
      eventType: EVENT_TYPE.TRACK,
      action,
      actionSubject: ACTION_SUBJECT.DOCUMENT,
      attributes: {
        content: ['caret']
      }
    };
  }
};

// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
export const getNodeCopiedAnalyticsPayload = (node, inputMethod) => {
  const nodeType = node.type.name;
  let extensionType;
  let extensionKey;
  if (isExtensionNode(nodeType)) {
    extensionType = node.attrs.extensionType;
    extensionKey = node.attrs.extensionKey;
  }
  const payload = {
    eventType: EVENT_TYPE.TRACK,
    action: ACTION.COPIED,
    actionSubject: ACTION_SUBJECT.DOCUMENT,
    attributes: {
      content: [nodeType],
      inputMethod,
      nodeType,
      ...(extensionType ? {
        extensionType
      } : {}),
      ...(extensionKey ? {
        extensionKey
      } : {})
    }
  };
  return payload;
};