import { Tree, message, Modal, Popconfirm, Spin, Layout, Drawer } from 'antd';
import React, { useEffect, useState, useRef } from 'react';
import * as d3 from 'd3';
import qs from 'qs';
import MergeDialog from '../components/dialog/mergeDialog';
import CopyDialog from '../components/dialog/copyDialog';
import inset from '../../public/img/back/inset.png';
import { getLabel } from '../util/i18n.js';

import {
  HomeOutlined,
  FolderOutlined,
  ClusterOutlined,
  ApartmentOutlined,
  QuestionCircleOutlined,
} from '@ant-design/icons';
const { Header, Footer, Sider, Content } = Layout;
import './index.less';

const DragTree = () => {
  const [gData, setGData] = useState([]);
  const [expandedKeys, setExpandedKeys] = useState([undefined]);
  const childRef = useRef(null);
  const copyChildRef = useRef(null);
  const [tip, setTip] = useState('');
  const [loading, setLoading] = useState(false);
  const [showCanceled, setShowCanceled] = useState(0);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [iframe, setIframe] = useState('');

  const [open, setOpen] = useState(false);
  const [mergeId, setMergeId] = useState(null);
  const [copyopen, setCopyOpen] = useState(false);
  const [copyId, setCopyId] = useState(null);
  const [labelData, setLabelData] = useState({});

  useEffect(() => {
    d3.json('/api/bs/hrmorganization/orgchart/i18n').then((res) => {
      setLabelData(res.data);
      setTip(`${getLabel(547473, res.data)}`);
    });
    getMoveTree(0);
  }, [true]);

  const getMoveTree = (showCanceled, expandedKeys = '') => {
    setLoading(true);
    d3.json(
      `/api/bs/hrmorganization/orgchart/getMovingTree?showCanceled=${showCanceled}&expandedKeys=${expandedKeys}`,
    ).then((data) => {
      setGData(data.movingTree);
      setExpandedKeys(data.expandedKeys);
      setLoading(false);
    });
  };

  const onDragEnter = (info) => {
    //console.log(info);
    // expandedKeys 需要受控时设置
    // setExpandedKeys(info.expandedKeys)
  };

  const loop = (data, key, callback) => {
    for (let i = 0; i < data.length; i++) {
      if (data[i].key === key) {
        return callback(data[i], i, data);
      }
      if (data[i].children) {
        loop(data[i].children, key, callback);
      }
    }
  };

  const onDrop = (info) => {
    const dropKey = info.node.key;
    const dragKey = info.dragNode.key;
    const dropPos = info.node.pos.split('-');
    const dropPosition =
      info.dropPosition - Number(dropPos[dropPos.length - 1]);

    if (dropPosition == -1) {
      return message.error(`${getLabel(547475, labelData)}`, 2);
    }
    let pos =
      dropPosition == 0
        ? `${getLabel(547476, labelData)}`
        : `${getLabel(547477, labelData)}`;

    let title = `${getLabel(547478, labelData)}【${
      info.dragNode.title
    } ${getLabel(547479, labelData)} 【${info.node.title}】${pos}`;
    Modal.confirm({
      title: `${getLabel(547480, labelData)}`,
      content: title,
      okText: `${getLabel(547319, labelData)}`,
      cancelText: `${getLabel(547318, labelData)}`,
      onOk() {
        setLoading(true);
        setTip(`${getLabel(547481, labelData)}`);

        fetch('/api/bs/hrmorganization/dept/dragDepartment', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            sourcekey: dragKey,
            targetkey: dropKey,
            dropPosition: dropPosition,
          }),
        })
          .then((response) => response.json())
          .then((res) => {
            if (res.code == 200) {
              const data = [...gData];
              // Find dragObject
              let dragObj;
              loop(data, dragKey, (item, index, arr) => {
                arr.splice(index, 1);
                dragObj = item;
              });
              if (!info.dropToGap) {
                // Drop on the content
                loop(data, dropKey, (item) => {
                  item.children = item.children || [];
                  // where to insert 示例添加到头部，可以是随意位置
                  item.children.unshift(dragObj);
                });
              } else if (
                (info.node.props.children || []).length > 0 &&
                // Has children
                info.node.props.expanded &&
                // Is expanded
                dropPosition === 1 // On the bottom gap
              ) {
                loop(data, dropKey, (item) => {
                  item.children = item.children || [];
                  // where to insert 示例添加到头部，可以是随意位置
                  item.children.unshift(dragObj);
                  // in previous version, we use item.children.push(dragObj) to insert the
                  // item to the tail of the children
                });
              } else {
                let ar = [];
                let i;
                loop(data, dropKey, (_item, index, arr) => {
                  ar = arr;
                  i = index;
                });
                if (dropPosition === -1) {
                  ar.splice(i, 0, dragObj);
                } else {
                  ar.splice(i + 1, 0, dragObj);
                }
              }
              setGData(data);
              message.success(`${getLabel(547482, labelData)}`, 2);
            } else {
              message.warning(res.msg, 2);
            }
            setLoading(false);
          })
          .catch((error) => {
            message.error(`${getLabel(547483, labelData)}`);
          });
      },
      onCancel() {},
    });
  };

  /**
   * 删除
   * @param {*} nodeData
   */
  const onDelete = (nodeData) => {
    const extend = nodeData.type == '1' ? 'comp' : 'dept';
    fetch(`/api/bs/hrmorganization/${extend}/deleteByIds`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ ids: nodeData.id.substring(1) }),
    })
      .then((response) => response.json())
      .then((res) => {
        if (res.code == 200) {
          if (res.data.status == '1') {
            const data = [...gData];
            loop(data, nodeData.key, (item, index, arr) => {
              arr.splice(index, 1);
            });
            setGData(data);
            message.success(`${getLabel(547484, labelData)}`, 2);
          } else {
            message.warning(res.data.message, 2);
          }
        }
      })
      .catch((error) => {
        message.error(`${getLabel(547483, labelData)}`);
      });
  };

  /**
   * 封存
   * @param {*} nodeData
   */
  const onCancel = (nodeData) => {
    setShowCanceled(0);
    const extend = nodeData.type == '1' ? 'comp' : 'dept';
    fetch(`/api/bs/hrmorganization/${extend}/updateForbiddenTagById`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        id: nodeData.id.substring(1),
        canceled: nodeData.canceled != '0',
      }),
    })
      .then((response) => response.json())
      .then((res) => {
        if (res.code == 200) {
          const data = [...gData];
          if (nodeData.canceled != '0') {
            message.success(`${getLabel(547485, labelData)}`, 2);
            loop(data, nodeData.key, (item, index, arr) => {
              arr[index].canceled = '0';
            });
          } else {
            loop(data, nodeData.key, (item, index, arr) => {
              arr.splice(index, 1);
            });
            message.success(`${getLabel(547486, labelData)}`, 2);
          }
          setGData(data);
        } else {
          message.warning(res.msg, 2);
        }
      })
      .catch((error) => {
        message.error(`${getLabel(547483, labelData)}`);
      });
  };

  /**
   * 合并
   * @param {*} nodeData
   */
  const onMerge = (nodeData) => {
    if (childRef.current) {
      childRef.current.getTreeData();
    }
    setMergeId(nodeData.id);
    setOpen(true);
  };

  const onMergeCreate = (values) => {
    let params = {
      department: values.department.substring(1),
      mergeName: values.mergeName,
      id: mergeId.substring(1),
    };
    fetch('/api/bs/hrmorganization/dept/mergeDepartment', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params),
    })
      .then((response) => response.json())
      .then((res) => {
        if (res.code == 200) {
          getMoveTree(0, values.department);
          message.success(`${getLabel(547487, labelData)}`, 2);
        } else {
          message.warning(res.msg, 2);
        }
        setOpen(false);
      })
      .catch((error) => {
        message.error(`${getLabel(547483, labelData)}`);
      });
  };

  /**
   * 复制
   * @param {*} nodeData
   */
  const onCopy = (nodeData) => {
    if (copyChildRef.current) {
      copyChildRef.current.getTreeData();
    }
    setCopyOpen(true);
    setCopyId(nodeData.id);
  };

  const onCopyCreate = (values) => {
    let params = {
      company: values.company,
      copySubDept: values.copySubDept ? '1' : '0',
      ids: copyId.substring(1),
    };
    fetch(`/api/bs/hrmorganization/dept/copyDepartment`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params),
    })
      .then((response) => response.json())
      .then((res) => {
        if (res.code == 200) {
          setCopyOpen(false);
          getMoveTree(0, values.company);
          message.success(`${getLabel(547488, labelData)}`, 2);
        } else {
          message.warning(res.msg, 2);
        }
      })
      .catch((error) => {
        message.error(`${getLabel(547483, labelData)}`);
      });
  };

  const onTitleRender = (nodeData) => {
    let extend = nodeData.type == '1' ? 'companyExtend' : 'departmentExtend';
    let attr =
      nodeData.type == '1' || nodeData.canceled == '1'
        ? 'none'
        : 'inline-block';
    let icon = nodeData.type == '1' ? <HomeOutlined /> : <FolderOutlined />;
    return (
      <>
        {nodeData.type == 0 ? (
          <span>
            <ClusterOutlined />
            <span style={{ marginLeft: '5px' }}>{nodeData.title}</span>
          </span>
        ) : (
          <>
            <span>
              {icon}
              <span style={{ marginLeft: '5px' }}>
                {nodeData.title}
                {nodeData.canceled == '1' ? (
                  <span style={{ color: 'red', marginLeft: '5px' }}>
                    ({getLabel(547489, labelData)})
                  </span>
                ) : (
                  ''
                )}
              </span>
            </span>
            <div id="drag-button-ops">
              <span
                className="drag-button"
                onClick={() => {
                  setDrawerOpen(true);
                  setIframe(
                    `/spa/organization/static/index.html#/main/organization/${extend}/${nodeData.id.substring(
                      1,
                    )}`,
                  );
                }}
              >
                {getLabel(547490, labelData)}
              </span>
              <Popconfirm
                title={`${getLabel(547491, labelData)}[${nodeData.title}]?`}
                onConfirm={() => onDelete(nodeData)}
                okText={getLabel(547319, labelData)}
                cancelText={getLabel(547318, labelData)}
              >
                <span className="drag-button">
                  {getLabel(547492, labelData)}
                </span>
              </Popconfirm>
              <Popconfirm
                title={`${getLabel(547493, labelData)} [${nodeData.title}]?`}
                onConfirm={() => onCancel(nodeData)}
                okText={getLabel(547319, labelData)}
                cancelText={getLabel(547318, labelData)}
              >
                <span className="drag-button">
                  {nodeData.canceled == '0'
                    ? `${getLabel(547494, labelData)}`
                    : `${getLabel(547495, labelData)}`}
                </span>
              </Popconfirm>
              <span
                style={{ display: attr }}
                className="drag-button"
                onClick={() => onMerge(nodeData)}
              >
                {getLabel(547194, labelData)}
              </span>
              <span
                style={{ display: attr }}
                className="drag-button"
                onClick={() => onCopy(nodeData)}
              >
                {getLabel(547196, labelData)}
              </span>
            </div>
          </>
        )}
      </>
    );
  };

  const onExpand = (info) => {
    setExpandedKeys(info);
  };

  return (
    Object.keys(labelData).length != 0 && (
      <div className="drag-wrapper">
        <Spin tip={tip} spinning={loading}>
          <div className="drag-layout">
            <div className="drag-header">
              <img src={inset} />
              <div>{getLabel(547282, labelData)}</div>
            </div>
            <div className="drag-content">
              <ApartmentOutlined
                className="drag-showcanceled"
                style={{ color: showCanceled == 0 ? '#000' : '#1890ff' }}
                onClick={() => {
                  const value = showCanceled == 0 ? 1 : 0;
                  setTip(`${getLabel(547473, labelData)}`);
                  setShowCanceled(value);
                  getMoveTree(value);
                }}
              />
              <Tree
                className="draggable-tree"
                //defaultExpandedKeys={expandedKeys}
                expandedKeys={expandedKeys}
                onExpand={onExpand}
                draggable
                icon={false}
                blockNode
                onDragEnter={onDragEnter}
                onDrop={onDrop}
                treeData={gData}
                titleRender={onTitleRender}
              />
            </div>
            <Drawer
              width="60%"
              placement="right"
              closable={false}
              onClose={() => setDrawerOpen(false)}
              open={drawerOpen}
            >
              <iframe src={iframe} width="100%" height="100%" />
            </Drawer>

            <div className="drag-footer">
              <p>
                <QuestionCircleOutlined />
                {getLabel(547283, labelData)}
              </p>
              <div className="tips">
                <div>1.{getLabel(547284, labelData)}</div>
                <div>2.{getLabel(547285, labelData)}</div>
                <div>3.{getLabel(547286, labelData)}</div>
                <div>4.{getLabel(547287, labelData)}</div>
              </div>
            </div>
          </div>
        </Spin>

        <MergeDialog
          ref={childRef}
          open={open}
          onCreate={onMergeCreate}
          onCancel={() => {
            setOpen(false);
          }}
          labelData={labelData}
        />
        <CopyDialog
          ref={copyChildRef}
          open={copyopen}
          onCreate={onCopyCreate}
          onCancel={() => {
            setCopyOpen(false);
          }}
          labelData={labelData}
        />
      </div>
    )
  );
};
export default DragTree;
