import {
  isComponent,
  isGroup,
  toNumber,
  deepMap,
  isScreen,
  isGeneralPanel,
  isPanel,
} from './utils';
import defaultTriggers from 'constants/default-triggers';
import defaultActions from 'constants/default-actions';
import { Utils } from '@easyv/react-gui';
import qs from 'qs';
import { isJsonString } from 'utils/utils';

const { reduceConfig, transfromConfig, getValueFromConfig } = Utils;

export const getInteractions = (components, layers) => {
  if (!components) {
    return [];
  }

  const _getInitState = (layers) => {
    return layers.reduce((all, item) => {
      if (isGeneralPanel(item.id)) {
        // 动态面板特殊处理，将所有的动态面板都存进interactions中
        all.push({
          id: item.id,
          state: {
            show: !item.hideDefault,
            unmount: true,
          },
          activeState: {},
          controllers: [],
        });
      } else if (item.hideDefault) {
        all.push({
          id: item.id,
          state: {
            show: false,
            unmount: true,
          },
          activeState: {},
          controllers: [],
        });
      }

      if (isGroup(item.id)) {
        all = all.concat(_getInitState(item.components));
      } else if (isComponent(item.id)) {
        const children = components.filter((d) => d.parent === item.id);

        if (children && children.length > 0) {
          const defaultHideChildren = children.filter((d) => {
            return getValueFromConfig(d.config, [0], 'show') === false;
          });
          if (defaultHideChildren.length > 0) {
            all.push(
              ...defaultHideChildren.map((d) => ({
                id: d.id,
                state: {
                  show: false,
                  unmount: true,
                },
                activeState: {},
                controllers: [],
              })),
            );
          }
        }
      }

      return all;
    }, []);
  };

  const initState = _getInitState(layers);

  return components.reduce((result, current) => {
    if (current.config) {
      const configs = reduceConfig(current.config);
      const interaction = configs.interaction;
      const controller = current.id;
      if (interaction && controller) {
        const events = interaction.events;
        if (events) {
          Object.keys(events).map((key) => {
            const event = events[key];
            const id = getId(event.component);
            if (id) {
              const index = result.findIndex((o) => o.id == id);
              const animation = getAnimation({
                type: event.animationName,
                duration: event.duration,
              });
              if (index < 0) {
                result = result.concat([
                  {
                    id,
                    state: {
                      show: true,
                    },
                    activeState: {
                      animation: {
                        key: 'show',
                        ...animation,
                      },
                    },
                    controllers: [controller],
                  },
                ]);
              } else {
                result[index] = {
                  ...result[index],
                  activeState: {
                    animation: {
                      key: 'show',
                      ...animation,
                    },
                  },
                  controllers: result[index].controllers.includes(controller)
                    ? result[index].controllers
                    : result[index].controllers.concat([controller]),
                };
              }
            }
          });
        }
      }
    }

    result.map((o) => {
      if (!window.interactionControllers) window.interactionControllers = {};
      window.interactionControllers[o.id] = o.controllers;
    });

    return result;
  }, initState);
};

const _reduceConfig = (config) => {
  if (!Array.isArray(config)) {
    return config;
  } else {
    return config.reduce((result, current) => {
      result[current.name] =
        current.type !== 'componentOptions' && current.config && current.config.options
          ? _reduceConfig(
              (current.config.options.find((o) => o.value === current.value) || {}).name,
            )
          : _reduceConfig(current.value);
      return result;
    }, {});
  }
};

const _findComponentInLayers = (layers, fakeId) => {
  const id = getId(fakeId);

  return layers.reduce((result, current) => {
    if (result) return result;

    if (current.components) {
      if (!result && current.id === id) {
        result = current;
      } else {
        result = _findComponentInLayers(current.components, fakeId);
      }
    } else {
      if (!result && current.id === id) {
        result = current;
      }
    }

    return result;
  }, null);
};

// remote control get all interactions in selected component
export const getEvents = (component, layers, panels: any = [], components) => {
  let { id, config = [], events = [] } = component;
  config = transfromConfig(config);

  const result: any = [];
  const originConfigs = reduceConfig(config);
  const configs = _reduceConfig(config);

  const originInteraction = originConfigs.interaction;
  const interaction = configs.interaction;

  if (interaction) {
    const events = interaction.events;
    const originEvents = originInteraction.events;
    if (events) {
      Object.keys(events).map((eventKey) => {
        const event = events[eventKey];
        const value = originEvents[eventKey];
        let type = null;
        let action = null;
        let component: any = null;
        let panel: any = null;
        Object.keys(event).map((objKey) => {
          objKey === 'type' && (type = event.type);
          objKey === 'action' && (action = event.action);
          value.action === 'switchState'
            ? objKey === 'panel' && (panel = JSON.parse(value.panel || '{}'))
            : objKey === 'component' &&
              (component = _findComponentInLayers(layers, event.component));
        });

        if (type && value.action !== 'switchState') {
          result.push({
            [`${type} ${action} ${component && component.name ? component.name : '组件'}`]: value,
          });
        }

        if (type && value.action === 'switchState' && panel && panel.panelId && panel.stateId) {
          const panelId = ((getId(panel.panelId) as any) || '').split('_')[1];
          const stateId = getId(panel.stateId);

          if (panelId && stateId) {
            const thePanel: any = panels.find((o) => +o.id === +panelId);
            if (thePanel && thePanel.states) {
              const theState = thePanel.states.find((o) => +o.id === +stateId);
              if (theState) {
                result.push({
                  [`${type} 切换 ${thePanel.name} ${theState.name}`]: value,
                });
              }
            }
          }
        }
      });
    }
  }

  const originComponent = components.find((d) => d.id == id) || {};
  const { triggers = [] } = originComponent;
  const allTriggers = defaultTriggers.concat(triggers);

  const customEvents = events.map((item) => {
    const { trigger, component, action, stateId } = item;
    const currentTrigger: any = allTriggers.find((d) => d.value === trigger) || {};
    const triggerName = currentTrigger.name;
    const targetComponentsInfo = component.map((d) => {
      if (isComponent(d)) {
        return components.find((o) => o.id === getId(d));
      } else if (isPanel(d)) {
        return panels.find((o) => o.id == (getId(d) as any).replace('panel_', ''));
      } else if (isGroup(d)) {
        return _findComponentInLayers(layers, d);
      }
    });

    const componentInfo = targetComponentsInfo[0] || {};
    const { actions = [] } = componentInfo;
    const allActions = defaultActions.concat(actions);
    const currentAction: any = allActions.find((d) => d.value === action) || {};
    const actionName = currentAction.name;
    const targetComponentName = targetComponentsInfo.map((d) => d.name || '组件');

    return {
      [`${triggerName} ${action === 'switchState' ? '切换' : actionName} ${targetComponentName.join(
        '、',
      )}`]: {
        type: trigger,
        action: action,
        component: action === 'switchState' ? '' : component,
        panel:
          action === 'switchState'
            ? `{"panelId": "${component[0]}","stateId": "${stateId}" }`
            : '{}',
      },
    };
  });

  return result.concat(customEvents);
};

// get specific component's state activeState and bindedState
export const getState = ({ interactions, id }) => {
  const interaction = interactions.find((o) => o.id === id);
  const iState = interaction ? interaction.state : undefined;
  const iActiveState = interaction ? interaction.activeState : undefined;
  const bindedInteractionState = interactions
    .filter((o) => o.controllers && o.controllers.includes(id))
    .map((o) => ({ id: o.id, state: o.state, activeState: o.activeState }));

  return {
    iState,
    iActiveState,
    bindedInteractionState,
  };
};

export const getCallbacks = (component) => {
  if (!component || !component.config) return [];

  const result: any = [];
  const configs = _reduceConfig(component.config);
  const interaction = configs.interaction;

  if (interaction) {
    const callbackList = interaction.callback;
    callbackList &&
      Object.values(callbackList).map((o) => {
        result.push(o);
      });
  }

  return result;
};

// filter layers with events
export const filterLayersWithEvents = (layers, components, componentsWithInfo, panels) => {
  return layers.reduce((result, current) => {
    if (isGroup(current.id)) {
      const componentsResult = filterLayersWithEvents(
        current.components,
        components,
        componentsWithInfo,
        panels,
      );
      if (componentsResult.length > 0) {
        return result.concat([
          {
            ...current,
            components: componentsResult,
          },
        ]);
      } else {
        return result;
      }
    } else {
      if (Number.isNaN(Number(current.id))) return result;

      const component = components.find((o) => +o.id === +current.id);

      if (component) {
        const { events: customEvents, config } = component;

        const events = getEvents(
          {
            id: current.id,
            config: JSON.parse(config),
            events: JSON.parse(customEvents),
          },
          componentsWithInfo,
          panels,
          components,
        );

        if (events.length > 0) {
          return result.concat([current]);
        }
      }
    }

    return result;
  }, []);
};

// add more infomations to layers like name and uniqueTag
export const getLayersWithInfo = (layers) => {
  return layers;
};

export const reduceInteractions = (interactions: any = [], payload) => {
  return interactions.reduce((result, current) => {
    if (current.id === payload.component) {
      payload.state = Object.keys(payload.state).reduce((obj, key) => {
        if (payload.state[key] === '$not') {
          obj[key] = !current.state[key];
        } else {
          obj[key] = payload.state[key];
        }

        return obj;
      }, {});

      return result.concat({
        ...current,
        state: {
          ...current.state,
          ...payload.state,
        },
        activeState: {
          ...current.activeState,
          ...payload.activeState,
        },
      });
    } else {
      return result.concat(current);
    }
  }, []);
};

export const getLayersWithCustomId = (layers: any = []) => {
  return layers.reduce((result, current) => {
    if (isComponent(current.id)) {
      return result.concat([
        {
          ...current,
          _id: `$component(${current.id})`,
        },
      ]);
    } else if (isGroup(current.id)) {
      return result.concat([
        {
          ...current,
          _id: `$group(${current.id})`,
          components: getLayersWithCustomId(current.components),
        },
      ]);
    } else if (isGeneralPanel(current.id)) {
      return result.concat([
        {
          ...current,
          _id: `$panel(${current.id})`,
          components: getLayersWithCustomId(current.components),
        },
      ]);
    } else if (current.id.toString().startsWith('screen_')) {
      return result.concat({
        ...current,
        _id: `$screen(${getId(current.id)})`,
        components: getLayersWithCustomId(current.components),
      });
    }
  }, []);
};

export const getId = (id: string): string | number => {
  const regs = {
    component: /^\$component\(([0-9]+)\)/,
    group: /^\$group\((group_\w+)\)/,
    panel: /^\$panel\((panel_[0-9]+)\)/,
    panel2: /^panel_([0-9]+)/,
    state: /^\$state\(([0-9]+)\)/,
    state2: /^state_([0-9]+)/,
    screen: /^\$screen\(([0-9]+)\)/,
    screen2: /^screen_([0-9]+)/,
    ref: /^ref_([0-9]+)/,
    ref2: /^\$panel\((ref_[0-9]+)\)/,
  };

  const reg = Object.values(regs).find((d) => d.test(id));
  if (reg) {
    id = id.replace(reg, (_match, p) => p);
  }

  return isNaN(+id) ? id : +id;
};

export function getActions({ data, events }) {
  return events.reduce((all, item) => {
    const { reverse = true } = item;
    if (isOnConditions({ type: item.conditionType, conditions: item.conditions, data })) {
      let action;
      if (item.actions) {
        action = item.actions.reduce((all, acc) => all.concat(getAction(acc, data)), []);
      } else {
        action = getAction(item, data);
      }
      if (action) {
        return all.concat(action);
      } else {
        return all;
      }
    } else if (reverse) {
      let action;
      if (item.actions) {
        action = item.actions.reduce((all, acc) => all.concat(getReverseAction(acc)), []);
      } else {
        action = getReverseAction(item);
      }

      if (action && action.length > 0) {
        // 将反向的操作放置在满足的动作之前执行
        all.unshift(...action);
        return all;
      } else {
        return all;
      }
    } else {
      return all;
    }
  }, []);
}

function isOnConditions({ type, conditions, data }) {
  if (conditions.length === 0) {
    return true;
  } else if (type === 'all') {
    return conditions.every((condition) => isOnCondition({ condition, data }));
  } else if (type === 'one') {
    return conditions.some((condition) => isOnCondition({ condition, data }));
  }
}

function isOnCondition({ condition, data }) {
  const { type, field, code, compare, expected } = condition;
  const search = document.location.search.split('?')[1];
  const query = search && qs.parse(search);
  if (type === 'field') {
    if (Array.isArray(data)) {
      return data.some((d) => {
        return typeof d === 'object' && d !== null && compareValue(d[field], expected, compare);
      });
    } else if (typeof data === 'object' && data !== null) {
      return compareValue(data[field], expected, compare);
    } else {
      return compareValue(data, expected, compare);
    }
  } else {
    if (query && query.useFilter && query.useFilter === 'false') {
      return data;
    } else {
      let result = false;
      try {
        result = eval(`(function(data){${code}})(data)`);
      } catch (error) {
        console.error(`自定义事件自定义条件执行时出错code:\n${code}`);
      }
      return result;
    }
  }
}

function compareValue(value1, value2, symbol) {
  switch (symbol) {
    case '==':
      return value1 == value2;
    case '!=':
      return value1 != value2;
    case '>':
      return toNumber(value1) > toNumber(value2);
    case '>=':
      return toNumber(value1) >= toNumber(value2);
    case '<':
      return toNumber(value1) < toNumber(value2);
    case '<=':
      return toNumber(value1) <= toNumber(value2);
    case 'include':
      return value1?.includes(value2);
    case 'exclude':
      return !value1?.includes(value2);
    default:
      return false;
  }
}

export function getAction(
  {
    component,
    stateId,
    panel,
    action,
    actionData,
    actionDataFn = 'return data;',
    componentConfig,
    animation,
    unmount,
    translate = {},
    scale = {},
    rotate = {},
  }: {
    component: any;
    stateId: any;
    panel: any;
    action: any;
    actionData: any;
    actionDataFn: string;
    componentConfig: any;
    animation: any;
    unmount: boolean;
    translate: any;
    scale: any;
    rotate: any;
  },
  data: any,
) {
  if (!action) {
    return;
  }

  if (action !== 'switchState' && !component) {
    return;
  }

  component = Array.isArray(component) ? component : [component];

  if (action === 'show') {
    return component.map((d) => ({
      type: action,
      component: d,
      state: {
        show: true,
      },
      activeState: {
        animation: {
          key: 'show',
          ...getAnimation(animation),
        },
      },
      animation,
    }));
  }

  if (action === 'hide') {
    return component.map((d) => ({
      type: action,
      component: d,
      state: {
        show: false,
        unmount: unmount,
      },
      activeState: {
        animation: {
          key: 'show',
          ...getAnimation(animation),
        },
      },
      animation,
    }));
  }

  if (action === 'show/hide') {
    return component.map((d) => ({
      type: action,
      component: d,
      state: {
        show: '$not',
        unmount: unmount,
      },
      activeState: {
        animation: {
          key: 'show',
          ...getAnimation(animation),
        },
      },
      animation,
    }));
  }

  if (action === 'switchState') {
    let panelId;
    if (component && stateId) {
      panelId = component[0];
    } else {
      const panelValue = isJsonString(panel) && JSON.parse(panel);
      if (panelValue) {
        panelId = panelValue.panelId;
        stateId = panelValue.stateId;
      }
    }

    if (panelId && stateId) {
      return {
        type: action,
        component: panelId,
        state: {
          show: true,
          stateId: stateId,

          [getId(stateId)]: {
            unmount,
            animation: {
              key: 'show',
              ...getAnimation(animation),
            },
          },
        },
        animation,
      };
    }
  }

  if (action === 'updateConfig') {
    return {
      type: action,
      component: component[0],
      componentConfig,
      animation,
    };
  }

  if (action === 'translate') {
    return component.map((d) => ({
      type: action,
      component: d,
      state: {
        translateToX: translate.toX || 0,
        translateToY: translate.toY || 0,
      },
      activeState: {
        animation: {
          ...getAnimation({ ...animation, type: undefined }),
        },
      },
      animation,
    }));
  }

  if (action === 'scale') {
    return component.map((d) => ({
      type: action,
      component: d,
      state: {
        scaleX: scale.x || 1,
        scaleY: scale.y || 1,
        transformOrigin: scale.origin || '50% 50%',
      },
      activeState: {
        animation: {
          ...getAnimation({ ...animation, type: undefined }),
        },
      },
      animation,
    }));
  }

  if (action === 'rotate') {
    return component.map((d) => ({
      type: action,
      component: d,
      state: {
        rotate: rotate,
      },
      activeState: {
        animation: {
          ...getAnimation({ ...animation, type: undefined }),
        },
      },
      animation,
    }));
  }

  function getActionData(data: any) {
    let result: any;
    try {
      result = eval(`(function emitData(data){
        ${actionDataFn}
      })(data)`);
    } catch (error) {
      console.error(error);
    }

    return result;
  }

  return {
    type: action,
    component: getId(component[0]),
    data: actionData,
    dynamicData: getActionData(data),
    animation,
  };
}

export function getReverseAction({ component, action, animation, unmount }) {
  if (!action) {
    return [];
  }

  component = Array.isArray(component) ? component : [component];

  if (action === 'show') {
    return component.map((d) => ({
      type: 'hide',
      component: d,
      state: {
        show: false,
        unmount: unmount,
      },
      activeState: {
        animation: {
          key: 'show',
          ...getAnimation(animation),
        },
      },
    }));
  }

  if (action === 'hide') {
    return component.map((d) => ({
      type: 'show',
      component: d,
      state: {
        show: true,
      },
      activeState: {
        animation: {
          key: 'show',
          ...getAnimation(animation),
        },
      },
    }));
  }

  if (action === 'updateConfig') {
    return [
      {
        type: action,
        component: component[0],
        componentConfig: {},
      },
    ];
  }

  if (action === 'rotate') {
    return component.map((d) => ({
      type: action,
      component: d,
      state: {
        rotate: undefined,
      },
    }));
  }

  if (action === 'translate') {
    return component.map((d) => ({
      type: action,
      component: d,
      state: {
        translateToX: undefined,
        translateToY: undefined,
      },
    }));
  }

  if (action === 'scale') {
    return component.map((d) => ({
      type: action,
      component: d,
      state: {
        scaleX: undefined,
        scaleY: undefined,
        transformOrigin: undefined,
      },
    }));
  }

  return [];
}

export function getAnimation(config) {
  const { type, ...rest } = config;

  switch (type) {
    case 'slide':
    case 'slideLeft':
      return slideFromLeft(rest);
    case 'slideRight':
      return slideFromRight(rest);
    case 'slideUp':
      return slideFromTop(rest);
    case 'slideDown':
      return slideFromBottom(rest);
    case 'zoom':
      return zoom(rest);
    case 'fade':
      return fade(rest);
    default:
      return { config: rest };
  }
}

const fade = (config) => ({
  from: {
    opacity: 0,
  },
  to: {
    opacity: 1,
  },
  config,
});

const slideFromLeft = (config) => ({
  from: {
    opacity: 0,
    transform: 'translateX(-200px)',
  },
  to: {
    opacity: 1,
    transform: 'translateX(0px)',
  },
  config,
});

const slideFromRight = (config) => ({
  from: {
    opacity: 0,
    transform: 'translateX(200px)',
  },
  to: {
    opacity: 1,
    transform: 'translateX(0px)',
  },
  config,
});

const slideFromTop = (config) => ({
  from: {
    opacity: 0,
    transform: 'translateY(-200px)',
  },
  to: {
    opacity: 1,
    transform: 'translateY(0px)',
  },
  config,
});

const slideFromBottom = (config) => ({
  from: {
    opacity: 0,
    transform: 'translateY(200px)',
  },
  to: {
    opacity: 1,
    transform: 'translateY(0px)',
  },
  config,
});

const zoom = (config) => ({
  from: {
    opacity: 0,
    transform: 'scale(0)',
  },
  to: {
    opacity: 1,
    transform: 'scale(1)',
  },
  config,
});

export function hasInteraction(component: any = {}) {
  const { config = [], events = [] } = component;
  if (events.length > 0) {
    return true;
  } else {
    const eventsConfig = getValueFromConfig(config, ['interaction', 'events']);
    if (eventsConfig && eventsConfig.length > 0) {
      return true;
    } else {
      return false;
    }
  }
}

/**
 *  获取组件选择列表，包含组、组件、子组件、动态面板
 * @param {screensById}
 * @param {panelsById}
 * @param {componentsById}
 * @param {screenId} 屏id
 * @param {stateId} 状态id
 * @param {mode} 模式：当前屏（状态） | 全局
 */

export function getComponentOptions({
  screensById,
  panelsById,
  componentsById,
  screenId,
  stateId,
  mode,
}) {
  if (mode === 'current') {
    const currentScreen = screensById[stateId];

    if (currentScreen) {
      const { layers = [] } = currentScreen;
      return deepMap(layers, (item) => {
        if (isComponent(item.id)) {
          return getComponentLayerWithChildren({ componentsById, componentLayer: item });
        } else {
          return item;
        }
      });
    } else {
      return [];
    }
  } else {
    const topScreen = screensById[screenId];

    if (topScreen) {
      const { layers = [] } = topScreen;
      return deepMap(layers, (item) => {
        if (isComponent(item.id)) {
          return getComponentLayerWithChildren({ componentsById, componentLayer: item });
        } else if (isGeneralPanel(item.id)) {
          const panelId: any = getId(item.id);
          const panel = panelsById[panelId];

          if (panel) {
            const { states = [] } = panel;
            return {
              ...item,
              type: 'panel',
              components: states.reduce((result, stateId) => {
                const stateScreen = screensById[stateId];
                if (stateScreen) {
                  return result.concat({
                    id: `screen_${stateId}`,
                    name: stateScreen.name,
                    type: 'state',
                    components: getComponentOptions({
                      screensById,
                      componentsById,
                      panelsById,
                      screenId: stateId,
                      stateId: stateId,
                      mode,
                    }),
                  });
                } else {
                  return result;
                }
              }, []),
            };
          } else {
            return item;
          }
        } else {
          return item;
        }
      });
    } else {
      return [];
    }
  }
}

/**
 * 获取单组件的图层信息，包含子组件
 * @param {componentsById}
 * @param {componentId}
 */
function getComponentLayerWithChildren({ componentsById, componentLayer }) {
  const component = componentsById[componentLayer.id];
  if (component) {
    let { children = [] } = component;
    if (children.length > 0) {
      children = children.reduce((result, childId) => {
        const child = componentsById[childId];
        if (child) {
          const { config } = child;
          return result.concat({
            id: childId,
            name: child.name,
            type: 'child',
            show: config[0]._show !== false,
          });
        } else {
          return result;
        }
      }, []);

      return {
        ...componentLayer,
        components: children,
      };
    } else {
      return componentLayer;
    }
  } else {
    return {
      ...componentLayer,
      show: false,
    };
  }
}

export function insertLayersWithCustomId(layers: any = []) {
  return layers.map((layer) => {
    if (isComponent(layer.id)) {
      return {
        ...layer,
        id: `$component(${layer.id})`,
        components: insertLayersWithCustomId(layer.components),
      };
    } else if (isGroup(layer.id)) {
      return {
        ...layer,
        id: `$group(${layer.id})`,
        components: insertLayersWithCustomId(layer.components),
      };
    } else if (isGeneralPanel(layer.id)) {
      return {
        ...layer,
        id: `$panel(${layer.id})`,
        components: insertLayersWithCustomId(layer.components),
      };
    } else if (isScreen(layer.id)) {
      return {
        ...layer,
        id: `$screen(${getId(layer.id)})`,
        components: insertLayersWithCustomId(layer.components),
      };
    }
  });
}

export function getTransformStyle(
  transform: any = {},
  iState: { [x: string]: any },
  iActiveState: { animation: { config?: { [x: string]: any } } },
  position: { left: number; top: number },
) {
  const {
    type = 'custom',
    rotate = {},
    scale = {},
    translate = {},
    open = false,
    skewX = 0,
    skewY = 0,
  } = transform;
  const { x: rotateX = 0, y: rotateY = 0, z: rotateZ = 0 } = rotate;
  const { x: scaleX = 1, y: scaleY = 1 } = scale;
  const { x: translateX = 0, y: translateY = 0, z: translateZ = 0 } = translate;

  const {
    scaleX: actionScaleX,
    scaleY: actionScaleY,
    transformOrigin,
    translateToX,
    translateToY,
    rotate: actionRotate,
  } = iState || {};
  const { animation: actionAnimation = {} } = iActiveState || {};
  const { config: actionAnimationConfig = {} } = actionAnimation;

  let useTransform = false;
  let resultTranslateX = 0;
  let resultTranslateY = 0;
  let resultTranslateZ = 0;
  let resultScaleX = 1;
  let resultScaleY = 1;
  let resultRotateX = 0;
  let resultRotateY = 0;
  let resultRotateZ = 0;
  let resultSkewX = 0;
  let resultSkewY = 0;
  let resultTransformOrigin;
  let resultTransition;

  if (open) {
    useTransform = true;

    if (type === '1') {
      resultRotateX = 54.736;
      resultRotateZ = 45;
    } else if (type === '2') {
      resultRotateX = 54.736;
      resultRotateZ = -45;
    } else if (type === '3') {
      resultRotateX = 35.264;
      resultRotateY = 45;
    } else if (type === '4') {
      resultRotateX = 35.264;
      resultRotateY = -45;
    } else {
      resultTranslateX = translateX;
      resultTranslateY = translateY;
      resultTranslateZ = translateZ;
      resultRotateX = rotateX;
      resultRotateY = rotateY;
      resultRotateZ = rotateZ;
      resultSkewX = skewX;
      resultSkewY = skewY;
      resultScaleX = scaleX;
      resultScaleY = scaleY;
    }
  }

  if (actionScaleX !== undefined || actionScaleY !== undefined) {
    useTransform = true;
    resultScaleX = actionScaleX;
    resultScaleY = actionScaleY;
    resultTransformOrigin = transformOrigin;
  }

  if (translateToX !== undefined || translateToY !== undefined) {
    useTransform = true;
    resultTranslateX = translateToX - position.left;
    resultTranslateY = translateToY - position.top;
  }

  if (
    actionRotate &&
    (actionRotate.rotateX != null || actionRotate.rotateY != null || actionRotate.rotateZ != null)
  ) {
    useTransform = true;
    resultRotateX = actionRotate.rotateX || 0;
    resultRotateY = actionRotate.rotateY || 0;
    resultRotateZ = actionRotate.rotateZ || 0;
  }

  if (actionAnimationConfig) {
    resultTransition = `transform ${actionAnimationConfig.timingFunction} ${actionAnimationConfig.duration}ms ${actionAnimationConfig.delay}ms`;
  }

  const result = useTransform
    ? {
        transform: `translate3d(${resultTranslateX}px, ${resultTranslateY}px, ${resultTranslateZ}px) scaleX(${resultScaleX}) scaleY(${resultScaleY}) rotateX(${resultRotateX}deg) rotateY(${resultRotateY}deg) rotateZ(${resultRotateZ}deg) skewX(${resultSkewX}deg) skewY(${resultSkewY}deg)`,
        transformOrigin: resultTransformOrigin,
        transition: resultTransition,
      }
    : resultTransition
    ? { transition: resultTransition }
    : {};

  return result;
}
