import React, { useState, useCallback, useEffect } from 'react';
import { connect } from 'react-redux';
import { useHistory } from 'react-router-dom';
import classNames from 'classnames';
import message from 'components/message';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
import PageItem from './PageItem';
import PageMenu from './PageMenu';
import DeleteConfirmModal from '../../../components/DeleteConfirmModal/Modal';
import CopyModal from './CopyModal';
import styles from './Pages.less';
import { appActions } from '../models';
import { resetSelect } from 'models/create-app';
import { updateScreen } from 'models/screens';

function Pages({ id, pages, pageId, addable, onAdd, onDelete, onCopy, updatePageName, onSort, resetSelect, copyLoading }) {
  const [collapsed, setCollapse] = useState(false);
  const [contextMenuVisible, setContextMenuVisible] = useState(false);
  const [contextMenuId, setContextMenuId] = useState(null);
  const [deleteVisible, setDeleteVisible] = useState(false);
  const [pos, setPos] = useState({ x: 0, y: 0 });
  const [copyVisible, setCopyVisible] = useState(false);
  const history = useHistory();

  useEffect(() => {
    const hideContextMenu = () => {
      setContextMenuVisible(false);
    };

    window.addEventListener('click', hideContextMenu, false);
    return () => {
      window.removeEventListener('click', hideContextMenu, false);
    };
  }, []);

  const onMoveEnd = useCallback(
    ({ draggableId, destination }) => {
      const targetId = destination.index === pages.length - 1 ? -1 : pages[destination.index].id;
      onSort({ id, origin: draggableId, target: targetId });
    },
    [id, pages]
  );

  const onClick = (nextPageId) => {
    if (nextPageId !== pageId) {
      resetSelect();
      history.push(`/app/edit/${id}/${nextPageId}`);
    }
  };

  const handleContextMenu = useCallback((pageId, position) => {
    setContextMenuVisible(true);
    setContextMenuId(pageId);
    setPos(position);
  }, []);

  const handleAdd = async () => {
    const result = await onAdd(id);
    if (result) {
      history.push(`/app/edit/${id}/${result.id}`);
    }
  };

  const showDeleteModal = useCallback(() => {
    if (pages.length > 1) {
      setDeleteVisible(true);
    } else {
      message.error('项目不能少于一个页面');
    }
  }, [pages]);

  const hideDeleteModal = useCallback(() => {
    setDeleteVisible(false);
  }, []);

  const handleDelete = useCallback(() => {
    const uniqueTag = pages.find((d) => d.id === contextMenuId).uniqueTag;
    onDelete({ id, uniqueTag });
    setContextMenuId(null);
    setDeleteVisible(false);
    if (contextMenuId === pageId) {
      const firstPage = pages.filter((d) => d.id !== contextMenuId).find((d) => !d.deleted);
      history.push(`/app/edit/${id}/${firstPage.id}`);
    }
  }, [id, contextMenuId, pageId, pages]);

  const handleCopy = useCallback(async () => {
    const uniqueTag = pages.find((d) => d.id === contextMenuId).uniqueTag;
    const result = await onCopy({ target: id, origin: id, uniqueTag });
    setContextMenuVisible(false);
    if (result) {
      history.push(`/app/edit/${id}/${result.pageId}`);
    }
  }, [id, contextMenuId, pages]);

  const showCopyModal = useCallback(() => {
    setCopyVisible(true);
  }, []);

  const hideCopyModal = useCallback(() => {
    setCopyVisible(false);
  }, []);

  const handleCopyComplete = useCallback(
    (appId) => {
      const uniqueTag = pages.find((d) => d.id === contextMenuId).uniqueTag;

      onCopy({
        origin: id,
        target: appId,
        uniqueTag
      });

      setCopyVisible(false);
    },
    [id, contextMenuId, pages]
  );

  return (
    <div>
      <div className={styles.header}>
        <span className={styles.title}>页面</span>
        {/* {addable && (
          <span className={styles.icon} onClick={handleAdd}>
            <i className="icon iconfont icon-icon_add" />
          </span>
        )} */}
        <span className={classNames(styles.icon, { [styles.collapsed]: collapsed })} onClick={() => setCollapse(!collapsed)}>
          <i className="icon iconfont icon-icon_fold" />
        </span>
      </div>
      <DragDropContext onDragEnd={onMoveEnd}>
        <Droppable droppableId="droppable">
          {(provided) => (
            <ul
              {...provided.droppableProps}
              ref={provided.innerRef}
              className={classNames(styles.content, { [styles.collapsed]: collapsed })}>
              {pages.map((d, i) => (
                <Draggable key={d.id} draggableId={d.id} index={i}>
                  {(provided) => (
                    <PageItem
                      key={d.id}
                      provided={provided}
                      active={pageId === d.id}
                      id={d.id}
                      text={d.name}
                      onClick={onClick}
                      onContextMenu={handleContextMenu}
                      onUpdate={updatePageName}
                    />
                  )}
                </Draggable>
              ))}
            </ul>
          )}
        </Droppable>
      </DragDropContext>

      <PageMenu visible={contextMenuVisible} position={pos} onCopy={handleCopy} onDelete={showDeleteModal} onCopyToApp={showCopyModal} />

      <DeleteConfirmModal visible={deleteVisible} onClose={hideDeleteModal} onOk={handleDelete} />

      {copyVisible && <CopyModal visible={copyVisible} onCancel={hideCopyModal} loading={copyLoading} onComplete={handleCopyComplete} />}
    </div>
  );
}

function mapStateToProps({ createApp, interactionEdit, user }) {
  const { id: pageId } = createApp;
  const { id, pages, copyLoading } = interactionEdit;
  const showPages = pages.filter((d) => !d.deleted);

  return {
    id,
    pages: showPages,
    pageId,
    copyLoading,
    addable: !(window.appConfig.LOCAL && user.userInfo.type === 'education')
  };
}

const mapDispatchToProps = {
  onAdd: appActions.addPage,
  onDelete: appActions.deletePage,
  onCopy: appActions.copyPage,
  updatePageName: updateScreen,
  onSort: appActions.sortPages,
  resetSelect
};

export default connect(mapStateToProps, mapDispatchToProps)(Pages);
