import React, { memo, useState, useEffect, useMemo, Fragment, useContext } from 'react';
import { Rnd } from '../ReactRnd';
import classNames from 'classnames';
import styles from './Draggable.less';
import { useLocalStorage } from 'components/easyUse';
import { getLayerHoverStatus } from 'utils/effects';
import { Icon } from 'components/easyDesign';
import { DraggableContext } from './Context';
import { isComponent, isGeneralPanel, isRefScreen } from 'utils/utils';
import { useDispatch } from 'react-redux';
import { useSelector } from 'react-redux';
import { RootState } from 'models';
import { openEdit, closeEdit } from 'models/create-app';
import { useAuth } from 'components/easyUse';

const getGroupHideStatus = (id: number | string, focusLayers: (number|string)[], hideDefault: boolean, hided: boolean) => {
  // 1.成组本身是独显，【勾选hided，勾选hideDefault，勾选hided未勾选hideDefault，勾选hideDefault未勾选hided，hided和hideDefault都未勾选】
  // 2.成组本身不是独显，不存在其他独显【勾选hided，勾选hideDefault，勾选hided未勾选hideDefault，勾选hideDefault未勾选hided，hided和hideDefault都未勾选】
  // 3. 成组本身不是独显，存在其他独显【勾选hided，勾选hideDefault，勾选hided未勾选hideDefault，勾选hideDefault未勾选hided，hided和hideDefault都未勾选】
  // 如果存在独显的组件,并且当前是成组
  if (focusLayers.length > 0 && /^group_/.test(id+'')) {
    //成组本身是独显
    if (focusLayers.includes(id)) {
      return hideDefault && !hided;
    }
    //成组本身不是独显
    return false;
  }
  // 如果不存在独显的组件
  return hideDefault && !hided;
};

function Draggable({
  id,
  hided,
  modalEditId,
  scale,
  children,
  x,
  y,
  width,
  height,
  selected,
  locked,
  hideDefault,
  useInteraction,
  isDefaultHide,
  changeComponentConfigActiveKey
}) {
  x = x ? x : 0;
  y = y ? y : 0;
  width = width ? width : 0;
  height = height ? height : 0;
  const { focusLayers = [] } = useContext(DraggableContext);
  const dispatch = useDispatch();
  const createApp = useSelector<RootState>((state) => state.createApp) as RootState['createApp'];
  const componentsById = useSelector<RootState>((state) => state.componentsById) as RootState['componentsById'];

  const { editId } = createApp;
  const { checkAuth } = useAuth();

  const [value, setValue] = useState({ x, y });
  const [axis] = useState<'x' | 'y' | 'both' | 'none'>('both');
  const [layerStick, setLayerStick] = useLocalStorage('layerStick');

  useEffect(() => {
    const handleLayerStickChange = (e) => {
      const layerStick = e.value;
      setLayerStick(layerStick);
    };
    window.addEventListener('layerStickChange', handleLayerStickChange);
    return () => {
      window.removeEventListener('layerStickChange', handleLayerStickChange);
    };
  }, []);

  useEffect(() => {
    setValue({ x, y });
  }, [x, y, scale]);

  useEffect(() => {
    if (!selected) {
      dispatch(closeEdit());
    }
  }, [selected]);

  const isHover = getLayerHoverStatus(id);

  const style = useMemo(() => {
    const styleObj: any = {
      pointerEvents: 'auto'
    };

    if (layerStick) {
      if (selected) {
        styleObj.zIndex = 2;
      }
    }
    return styleObj;
  }, [layerStick, selected]);

  const size = useMemo(() => {
    return { width, height };
  }, [width, height]);

  const position = useMemo(() => {
    return { x: value.x, y: value.y };
  }, [value]);

  const toEditText = () => {
    const { base } = componentsById[id];
    const { module_name, version } = base;
    const m = module_name + '@' + version;
    const component = window.component && window.component[m].getDefaultConfig();
    const editable = component.extra?.editable || false;
    if (editable && checkAuth('editText')) {
      dispatch(openEdit(id));
    }
  };

  return (
    <Rnd
      id={`rnd_${id}`}
      className={classNames({
        selected: selected,
        hide: isDefaultHide && getGroupHideStatus(id, focusLayers, hideDefault, hided),
        hideAfter: hided,
        isPanel: isGeneralPanel(id) && !locked,
        isRef: isRefScreen(id),
        'z-hover': isHover
      })}
      dragAxis={axis}
      size={size}
      position={position}
      scale={scale}
      enableResizing={false}
      disableDragging={true}
      style={style}>
      {!hideDefault && <div style={{ position: 'absolute', left: -x, top: -y, visibility: hided ? 'hidden' : 'visible' }}>{children}</div>}

      {/* 用于遮罩，禁用组件内部的事件 */}
      {isGeneralPanel(id) ? (
        <div  style={{ position: 'absolute', top: 0, left: 0, width, height }} />
      ) : isComponent(id) && !editId ? (
        <div  onDoubleClick={toEditText} style={{ position: 'absolute', top: 0, left: 0, width, height }} />
      ) : null}

      {!modalEditId && (
        <Fragment>
          <span
            className={styles.line}
            style={{ top: 0, left: 0, width: 1, height: '100%', transform: `translate(-50%, 0) scaleX(${1 / scale})` }}
          />
          <span
            className={styles.line}
            style={{ top: 0, right: 0, width: 1, height: '100%', transform: `translate(50%, 0) scaleX(${1 / scale})` }}
          />
          <span
            className={styles.line}
            style={{ top: 0, left: 0, width: '100%', height: 1, transform: `translate(0, -50%) scaleY(${1 / scale})` }}
          />
          <span
            className={styles.line}
            style={{ bottom: 0, left: 0, width: '100%', height: 1, transform: `translate(0, 50%) scaleY(${1 / scale})` }}
          />
        </Fragment>
      )}
      {!hided && useInteraction && (
        <div
          className={styles.interactionIcon}
          style={{
            transform: `scale(${1 / scale})`
          }}
          onClick={() => changeComponentConfigActiveKey('3')}>
          <Icon type="icon_color" style={{ color: '#E8AA2E' }} />
        </div>
      )}
    </Rnd>
  );
}

export default memo(Draggable);
