import React, { useContext, useState, useEffect, useRef, useCallback } from 'react';
import Sortable from 'react-sortablejs';
import classNames from 'classnames';
import { Input } from '@easyv/antd';
import GroupItem from '../../../screen-list/components/GroupItem';
import UngroupItem from '../../../screen-list/components/UngroupItem';
import styles from '../../../screen-list/components/GroupMenu.less';
import { SourceContext } from '../../index';
import { addGroup, deleteGroup, editGroup, sortGroup, editItem } from '../../api';
import { GROUP_FIELDS as F, STATIC } from '../../constant';
import trim from 'lodash/trim';
import message from 'components/message';

export default function MenuItem({
  groupId = [],
  type,
  list: propsList = [],
  title,
  titleIcon = null,
  onChange,
  isSlide = false,
  style = {}
}: any) {
  const { refresh, draggingId, draggingType, draggingGroupId } = useContext(SourceContext);
  const [add, setAdd] = useState(false);
  const [moveParams, setMoveParams] = useState<any>();
  const [count, setCount] = useState(0);
  const [slide, setSlide] = useState<boolean>(true);

  const inputRef = useRef<Input>(null);

  const list = propsList.slice(0, -1);

  useEffect(() => {
    if (add) {
      inputRef.current?.focus();
    }
  }, [add]);

  useEffect(() => {
    if (!moveParams) return;
    const { oldIndex, newIndex } = moveParams;
    const newList = [...list];
    newList[oldIndex] = list[newIndex];
    newList[newIndex] = list[oldIndex];
    sortGroup(
      newList.map(({ id }) => id),
      type
    ).then(() => {
      refresh();
    });
  }, [moveParams]);

  const handleAddClick = () => {
    setAdd(true);
    setSlide(true);
  };

  const handleBlur = (e) => {
    const value = trim(e.target.value);
    if (value) {
      addGroup(value, type).then(() => {
        refresh();
      });
    }
    setAdd(false);
  };

  const handleSelectGroup = (id: number) => {
    onChange(id);
  };

  // 移动组
  const moveGroup = ({ oldDraggableIndex: oldIndex, newDraggableIndex: newIndex }) => {
    //在该函数中取不到list所以通过state进行后续操作
    setMoveParams({
      oldIndex,
      newIndex
    });
  };

  const moveScreenToGroup = ({ groupId }) => {
    if (draggingType !== type) return;
    if (draggingGroupId == groupId) {
      const toGroup = propsList.find((o) => o.id === groupId);
      const toGroupName = toGroup ? toGroup.name : '未分组';
      message.error(`该资源已在${toGroupName}组中`);
      return;
    }
    editItem(STATIC[type], draggingId, groupId)?.then(() => {
      refresh();
    });
  };

  const handleEdit = (params) => {
    editGroup(params, type).then((result) => {
      refresh();
      !result && setCount(Date.now());
    });
  };

  const handleDelete = (id) => {
    deleteGroup(id, type).then(() => {
      handleSelectGroup(0);
      refresh();
    });
  };

  // eslint-disable-next-line @typescript-eslint/no-empty-function
  const handleDrag = useCallback(() => {}, []);

  const unCount = propsList[propsList.length - 1]?.[F.COUNT] || 0;
  const totalCount = propsList.reduce((total, item) => (total += item[F.COUNT]), 0);
  const current = Number(groupId[2] === type ? groupId[0] : undefined);

  return (
    <div>
      <div className={styles.title} style={style}>
        <p className={styles.title_left} onClick={() => setSlide(!slide)}>
          {isSlide && (
            <i
              className={classNames('icon iconfont icon-sanjiaoxing ' + styles.app_icon_drop)}
              style={{ transform: slide ? 'rotate(90deg)' : 'rotate(0deg)' }}
            />
          )}
          {titleIcon}
          <span style={{ width: '70px' }} className={styles.app_list}>
            {title}
          </span>
        </p>
        <i className={'icon iconfont icon-btn_addgroup ' + styles.addIcon} onClick={handleAddClick} />
      </div>
      <div className={styles.menu} style={{ display: slide ? 'block' : 'none' }}>
        <div
          className={classNames(styles.menuItem, {
            [styles.active]: current === 0
          })}
          onClick={() => handleSelectGroup(0)}>
          <p>全部</p>
          <p>{totalCount}</p>
        </div>
        {add && (
          <div className={classNames(styles.menuItem, styles.inputItem)}>
            <Input ref={inputRef} onBlur={handleBlur} onPressEnter={(e: any) => e.target.blur()} maxLength={12} />
          </div>
        )}
        <div
          className={classNames(styles.dropContainer, {
            [styles.isDragging]: draggingType === type
          })}>
          <Sortable
            tag="div"
            className={styles.dropContainerChild}
            onChange={handleDrag}
            options={{
              group: type,
              animation: 150,
              swapThreshold: 0.65,
              direction: 'vertical',
              onUpdate: moveGroup,
              scroll: true
            }}>
            {list.map((item, i) => {
              return (
                <GroupItem
                  key={item.id + count}
                  id={item.id}
                  index={i}
                  name={item[F.NAME]}
                  active={current === item.id}
                  isFirst={i === 0}
                  groupedCount={item[F.COUNT]}
                  moveScreenToGroup={moveScreenToGroup}
                  selectGroup={handleSelectGroup}
                  updateGroup={handleEdit}
                  deleteGroup={handleDelete}
                />
              );
            })}
          </Sortable>
          {/* TODO 屏蔽未分组 */}
          <UngroupItem
            active={current === -1}
            groupedCount={unCount}
            moveScreenToGroup={moveScreenToGroup}
            selectGroup={handleSelectGroup}
          />
        </div>
      </div>
    </div>
  );
}
