import React, { Component } from 'react';
import { Jsme } from 'jsme-react';
import qs from 'qs';
import request from '../../utils/request';
import Graphin, { GraphinContext, Components, Utils } from '@antv/graphin';
import { ContextMenu } from '@antv/graphin-components';
import Animate from 'rc-animate';
import { ContextMenuValue } from '@antv/graphin';
// import { TooltipValue } from '@antv/graphin'

import { Select, message, Form, Button, Input, Checkbox, Row, Col, Card, Tag } from 'antd';
import './index.css';
const { Option } = Select;
const { Menu } = ContextMenu;
// const { Tooltip } = Components

export default class KnowledgeMap extends Component {
  state = {
    collapsed: false,
    show: true,
    show2: true,
    classList: [],
    childClassList: [],
    allClassList: [],
    searchData: {
      label: '',
      property: '',
      // CHEMBL1921
      data: '',
      id: null,
      type_list: '',
    },
    typeList: [],
    nodeData: {
      nodes: [],
      edges: [],
    },
    checkedList: [],
    modelData: {},
    optionsEdge: [
      {
        key: 'details',
        name: '详情',
      },
    ],
  };
  componentDidMount() {
    this.getSelectList();
  }
  onClick = () => {
    this.setState({
      show: !this.state.show,
    });
  };

  getReferences2 = (e) => {
    window.open(e);
  };
  toggleCollapsed = () => {
    this.setState({
      collapsed: !this.state.collapsed,
    });
  };
  childClassChange = (e) => {
    let searchData = this.state.searchData;
    searchData.property = e;
    this.setState(() => ({ searchData: searchData }));
  };
  getClassData = (e) => {
    // console.log(e)
    let searchData = this.state.searchData;
    searchData.label = e;
    let classList = this.state.classList;
    let childData = [];
    classList.forEach((item) => {
      if (e === item.name) {
        childData = item.content;
      }
    });

    this.setState({ childClassList: childData });
  };
  getSelectList = () => {
    localStorage.getItem('token') &&
      request
        .get('kg/title')
        .then((res) => {
          if (res.data.code === 200) {
            let searchData = this.state.searchData;
            let typeList = [];
            res.data.data.type_list.forEach((item) => {
              typeList.push(item.name);
            });
            searchData.type_list = typeList.toString();

            this.setState({
              classList: res.data.data.all_class,
              allClassList: res.data.data.type_list,
              checkedList: typeList,
              searchData: searchData,
            });
          } else {
            message.error(res.data.msg);
          }
        })
        .catch((err) => {
          console.error(err);
        });
  };
  getMap = () => {
    request
      .post('kg/search', qs.stringify(this.state.searchData))
      .then((res) => {
        if (res.data.code === 200) {
          const expandData = res.data;
          expandData.edges.forEach((edge) => {
            edge.style = {};
            edge.style.label = {
              value: edge.name,
            };
            edge.id = '';
          });
          expandData.nodes.forEach((node) => {
            console.log(node);

            if (node.label == 'Drug') {
              node.type = 'circle';
              node.size = [50, 50];

              node.label = node.style.label.value;
              node.style = {
                stroke: node.colour,
                fill: node.colour,
                opacity: 1,
                fillOpacity: 1,
              };
              node.labelCfg = {
                position: 'bottom',
              };
            }
            if (node.label == 'Receptor') {
              node.type = 'rect';
              node.size = [50, 50];

              node.label = node.style.label.value;
              node.style = {
                stroke: node.colour,
                fill: node.colour,
                opacity: 1,
                fillOpacity: 1,
              };
              node.labelCfg = {
                position: 'bottom',
              };
            }
            if (node.label == 'Indication') {
              node.type = 'diamond';
              node.size = [60, 60];

              node.label = node.style.label.value;
              node.style = {
                stroke: node.colour,
                fill: node.colour,
                opacity: 1,
                fillOpacity: 1,
              };
              node.labelCfg = {
                position: 'bottom',
              };
            }
            if (node.label == 'Mutation') {
              node.type = 'triangle';
              node.size = [40, 40];

              node.label = node.style.label.value;
              node.style = {
                stroke: node.colour,
                fill: node.colour,
                opacity: 1,
                fillOpacity: 1,
              };
              node.labelCfg = {
                position: 'bottom',
              };
            }

            node.style.keyshape = {
              stroke: node.colour,
              fill: node.colour,
              opacity: 1,
              fillOpacity: 1,
            };
          });
          console.log(expandData.nodes);

          var dedupe = require('dedupe');
          let newNodes = dedupe([...this.state.nodeData.nodes, ...expandData.nodes]);
          let newEdges = dedupe([...this.state.nodeData.edges, ...expandData.edges]);
          let arr = [];
          let arr2 = [];
          newNodes.forEach((element) => {
            arr.push(element.id);
          });
          newEdges.forEach((element) => {
            element = element.id + '22';
          });

          this.setState({
            nodeData: {
              // 还需要对Node和Edge去重，这里暂不考虑
              nodes: newNodes,
              edges: newEdges,
            },
          });
          // console.log(this.state.nodeData)
        } else {
          message.error(res.data.msg);
        }
      })
      .catch((err) => {
        console.error(err);
      });
  };
  getMapButton = () => {
    let searchData = this.state.searchData;
    searchData.id = null;
    this.setState(() => ({
      searchData: searchData,
      nodeData: {
        nodes: [],
        edges: [],
      },
    }));

    this.sb();

    this.getMap();
  };
  sb = () => {
    function fun() {
      var a = 5;
      function getA() {
        return a;
      }
      return getA;
    }
    var f = fun();

    f();
  };
  onChange = (checkedValues) => {
    let searchData = this.state.searchData;
    searchData.type_list = checkedValues.toString();
    // console.log(checkedValues.toString())
    this.setState({
      checkedList: checkedValues,
      searchData: searchData,
    });
  };
  handleChange = (menuItem, menuData) => {
    // console.log(menuItem)
    // console.log(menuData)

    if (menuItem.key === 'details') {
      this.setState(() => ({ modelData: menuData.data }));
    } else {
      // console.log(menuData)

      let searchData = this.state.searchData;
      searchData.id = menuData.id;
      this.getMap();
    }
  };
  getInputValue = (e) => {
    const { value } = e.target;
    let searchData = this.state.searchData;
    searchData.data = value;
    this.setState(() => ({ searchData: searchData }));
  };

  render() {
    const { classList, childClassList, allClassList, nodeData, modelData, optionsEdge } = this.state;
    // const data1 = Utils.mock(5)
    //   .circle()
    //   .graphin()
    // console.log(data1)
    // const layout = {
    //   type: 'concentric',
    //   minNodeSpacing: 50,
    // }
    const defSpreingLen = (_edge, source, target) => {
      /** 默认返回的是 200 的弹簧长度 */
      /** 如果你要想要产生聚类的效果，可以考虑 根据边两边节点的度数来动态设置边的初始化长度：度数越小，则边越短 */
      const nodeSize = 30;
      const Sdegree = source.data.layout.degree;
      const Tdegree = target.data.layout.degree;
      const minDegree = Math.min(Sdegree, Tdegree);
      // console.log(minDegree < 3 ? nodeSize * 5 : minDegree * nodeSize)
      return minDegree < 3 ? nodeSize * 5 : minDegree * nodeSize;
    };

    const options = [
      // {
      //   key: 'tag',
      //   // icon: <TagFilled />,
      //   name: '打标',
      // },
      {
        key: 'details',
        // icon: <DeleteFilled />,
        name: '详情',
      },
      {
        key: 'expand',
        // icon: <ExpandAltOutlined />,
        name: '扩散',
      },
    ];

    const CanvasMenu = () => {
      const { graph, contextmenu } = React.useContext(GraphinContext);
      const context = contextmenu.canvas;
      const handleDownload = () => {
        graph.downloadFullImage('canvas-contextmenu');
        context.handleClose();
      };
      const handleClear = () => {
        message.info(`清除画布成功`);
        context.handleClose();
      };
      const handleStopLayout = () => {
        message.info(`停止布局成功`);
        context.handleClose();
      };
      return (
        <Menu bindType='canvas'>
          {/* <Menu.Item onClick={handleClear}>清除画布</Menu.Item>
          <Menu.Item onClick={handleStopLayout}>停止布局</Menu.Item>
          <Menu.Item onClick={handleDownload}>下载画布</Menu.Item> */}
        </Menu>
      );
    };

    return (
      <div className='KnowledgeMap-div'>
        <div className='KnowledgeMap-left-div'>
          <Card hoverable style={{ width: '100%' }}>
            <Animate transitionName='fade' transitionAppear>
              {this.state.show ? (
                <Form onSubmit={this.handleSubmit} className='login-form'>
                  <Form.Item>
                    <Select placeholder='请选择' style={{ width: 270 }} size='large' onChange={this.getClassData}>
                      {classList.map((item, index) => {
                        return (
                          <Option key={index} value={item.name}>
                            {item.name}
                          </Option>
                        );
                      })}
                    </Select>
                  </Form.Item>
                  <Form.Item>
                    <Select placeholder='请选择' style={{ width: 270 }} size='large' onChange={this.childClassChange}>
                      {childClassList.map((item, index) => {
                        return (
                          <Option key={index} value={item.name}>
                            {item.name}
                          </Option>
                        );
                      })}
                    </Select>
                  </Form.Item>
                  <Form.Item>
                    <Input placeholder='请输入' size='large' onChange={this.getInputValue} value={this.state.searchData.data} />
                  </Form.Item>
                  <Checkbox.Group style={{ width: '100%' }} onChange={this.onChange} value={this.state.checkedList}>
                    <Row>
                      {allClassList.map((item, index) => {
                        return (
                          <Col span={16} key={index}>
                            <Checkbox value={item.name}>{item.name}</Checkbox>
                            <Button
                              shape='circle'
                              style={{
                                height: '20px',
                                width: '20px',
                                backgroundColor: item.colour,
                              }}
                            />
                          </Col>
                        );
                      })}
                    </Row>
                  </Checkbox.Group>
                  <Form.Item>
                    <Button onClick={this.getMapButton} type='primary' htmlType='submit' className='login-form-button'>
                      搜索
                    </Button>
                  </Form.Item>
                </Form>
              ) : null}
            </Animate>
            <Button type='primary' htmlType='submit' className='login-form-button' onClick={this.onClick}>
              {this.state.show ? '收起' : '展开'}
            </Button>
          </Card>
        </div>
        <div className='KnowledgeMap-right-div'>
          <Graphin
            data={nodeData}
            layout={{
              type: 'graphin-force',
              preset: {
                type: 'concentric',
              },
              animation: true,
              preventOverlap: true,
              nodeSize: 40,
              leafCluster: true, // 是否需要叶子节点聚类
              nodeClusterBy: 'label', // 节点聚类的映射字段
              clusterNodeStrength: 20, // 节点聚类作用力
              // defSpringLen: defSpreingLen,
            }}
          >
            {/* <Tooltip bindType="node" style={{ width: '200px', "background": "#fff", }} >
              {(value) => {
                if (value.model) {
                  const { model } = value
                  return (
                    <div >
                      {
                        model.data && Object.keys(model.data).map((item, index) => {

                          if (item != 'smiles') {
                            return (
                              <div key={index}>
                                <span className='left-title'>{item}: </span>{model.data[item]}
                              </div>

                            )


                          }
                          // else {
                          //   return (
                          //     model.data[item] && <Jsme key={index} height="150px" width="" options="depict,useopenchemlib" smiles={model.data[item]} />
                          //   )

                          // }

                        })

                      }
                    </div>
                  )
                }
                return null
              }}
            </Tooltip> */}

            <ContextMenu style={{ width: '80px' }}>
              <Menu options={options} onChange={this.handleChange} bindType='node' />
            </ContextMenu>
            <ContextMenu style={{ width: '80px' }} bindType='canvas'>
              {/* <CanvasMenu /> */}
            </ContextMenu>
            <ContextMenu style={{ width: '120px', background: '#fff' }} bindType='edge'>
              <Menu
                options={optionsEdge.map((item) => {
                  return { ...item, name: `${item.name}` };
                })}
                onChange={this.handleChange}
                bindType='edge'
              />
            </ContextMenu>
            {/* <Tooltip bindType="edge" style={{ "background": "#fff", }} >
              {(value) => {
                if (value.model) {
                  const { model } = value
                  return (
                    <div >
                      {
                        model.data && Object.keys(model.data).map((item, index) => {

                          return (
                            <div key={index}>
                              <span className='left-title'>{item}: </span> {model.data[item]}
                            </div>
                          )
                        })

                      }
                    </div>
                  )
                }
                return null
              }}
            </Tooltip> */}
          </Graphin>
        </div>
        <div className='KnowledgeMap-details-div'>
          <Card hoverable style={{ width: '100%' }}>
            <Animate transitionName='fade' transitionAppear>
              {this.state.show2
                ? Object.keys(modelData).map((item, index) => {
                    if (item != 'smiles') {
                      return (
                        <div key={index}>
                          <span className='left-title'>{item}: </span>

                          {typeof modelData[item] === 'object' &&
                            modelData[item] != null &&
                            modelData[item].map((item2, index) => {
                              if (item == 'reference') {
                                return (
                                  <Tag
                                    color='blue'
                                    style={{
                                      wordWrap: 'break-word',

                                      wordBreak: 'normal',
                                    }}
                                    onClick={() => {
                                      this.getReferences2(item2);
                                    }}
                                  >
                                    {item2}
                                  </Tag>
                                );
                              } else {
                                return (
                                  <span
                                    color='blue'
                                    onClick={() => {
                                      this.getReferences2(item2);
                                    }}
                                  >
                                    {item2}
                                  </span>
                                );
                              }
                            })}
                          {typeof modelData[item] != 'object' && (
                            <span key={index}>
                              {/* <span className="left-title">{item}: </span> */}
                              {modelData[item]}
                            </span>
                          )}
                        </div>
                      );
                    } else {
                      return modelData[item] && <Jsme key={index} height='150px' width='' options='depict,useopenchemlib' smiles={modelData[item]} />;
                    }
                  })
                : null}
            </Animate>
          </Card>
        </div>
      </div>
    );
  }
}
