import React from 'react';
import {
  MinusCircleOutlined,
  PlusCircleOutlined,
  EditOutlined
} from '@ant-design/icons';
import {
  Button,
  Form,
  Input,
  Space,
  Modal,
  Collapse,
  Table,
  Empty,
  message
} from 'antd';
import ScriptEditor from './ScriptEditor';
import { getNodeResult, getSqlDsTable } from './request';
import { getEditorTemplate } from './utils';

const { Panel } = Collapse;

export default class ScriptNodeInfo extends React.Component<any, any> {
  formRef = React.createRef();

  constructor(props: any) {
    super(props);
    this.state = {
      scriptModalVisible: false,
      checking: false,
      inputNumber: 1,
      outputNumber: 1,
      columns: [],
      tableData: [],
      editorValue: '',
      nodeName: ''
    };
  }

  editorRef = React.createRef();

  showScriptModal = () => {
    this.setState({ scriptModalVisible: true });
  };

  // 保存编辑的代码
  submitScriptEdit = () => {
    this.setState({ scriptModalVisible: false });
    const editorValue = (this.editorRef.current as any).state.editor.getValue();
    this.setState({ editorValue: editorValue });
  };

  // 提交代码校验
  submitSyntaxCheck = async () => {
    this.setState({ checking: true });
    await (this.editorRef.current as any).checkSyntax();
    this.setState({ checking: false });
  };

  componentDidMount(): void {
    this.setState({
      inputNumber: this.props.nodeInfo.inputNumber,
      outputNumber: this.props.nodeInfo.outputNumber,
      editorValue: this.props.nodeInfo.scriptText,
      nodeName: this.props.nodeInfo.nodeName
    });
    this.props.node.setData({
      ...this.props.nodeInfo
    });
    this.changeCollapse('input0');
  }

  submit() {
    const { nodeId, nodeName } = (this.formRef.current as any).getFieldsValue();
    if (nodeName) {
      this.props.nodeInfo.inputNumber = this.state.inputNumber;
      this.props.nodeInfo.nodeName = nodeName;
      this.props.nodeInfo.nodeId = nodeId;
      this.props.nodeInfo.outputNumber = this.state.outputNumber;
      const script = getEditorTemplate({
        inputNumber: this.state.inputNumber,
        outputNumber: this.state.outputNumber,
        type: this.props.nodeInfo.label
      });
      this.props.nodeInfo.scriptText = this.state.editorValue || script;
      this.updateInputPorts(this.state.inputNumber);
      this.updateOutputPorts(this.state.outputNumber);
      this.props.node.setData({ ...this.props.nodeInfo });
      this.props.close();
      this.props.changeStatus(this.props.nodeInfo.nodeId);
    } else {
      message.error('请输入节点名字');
    }
  }

  onReset() {
    this.props.nodeInfo.nodeName = this.state.nodeName;
    this.props.node.setData({ ...this.props.nodeInfo });
    this.props.close();
  }

  // 添加输入端点
  updateInputPorts = (number: number) => {
    const id = this.props.nodeInfo.id;
    const node = this.props.graph.getCellById(id);
    const currentInputPortsNumber = node
      .getPorts()
      .reduce((pre: number, item: any) => {
        return item.group === 'top' ? pre + 1 : pre;
      }, 0);
    for (let i = number; i < currentInputPortsNumber; i++) {
      node.removePort(`input${number}`);
    }
    for (let i = currentInputPortsNumber; i < number; i++) {
      node.addPort({ group: 'top', id: `input${i}` });
    }
  };

  // 更新输入数量
  updateNumber = (inputNumber: number) => {
    this.setState({ inputNumber });
  };

  updateOutputNumber = (outputNumber: number) => {
    console.log(outputNumber);
    this.setState({ outputNumber });
  };

  updateOutputPorts = (number: number) => {
    const id = this.props.nodeInfo.id;
    const node = this.props.graph.getCellById(id);
    const currentOutputPortsNumber = node
      .getPorts()
      .reduce((pre: number, item: any) => {
        return item.group === 'bottom' ? pre + 1 : pre;
      }, 0);
    for (let i = number; i < currentOutputPortsNumber; i++) {
      node.removePort(`r${number}`);
    }
    for (let i = currentOutputPortsNumber; i < number; i++) {
      node.addPort({ group: 'bottom', id: `r${i}` });
    }
  };

  changeCollapse = async (val: any) => {
    if (
      this.props.scriptInputs[val]?.target_type === 'sql' &&
      this.props.scriptInputs[val]?.source_type === 'InputSource'
    ) {
      const { data } = await getSqlDsTable(
        this.props.scriptInputs[val].source_tableName
      );
      if (data.code === 200) {
        const { col, tableData } = this.formatTableData(data.data);
        this.setState({
          columns: col,
          tableData
        });
      }
    } else {
      const params = {
        dag_uuid: this.props.dagId,
        node_id: this.props.scriptInputs[val].nodeId,
        out_pin: this.props.scriptInputs[val].out_pin
      };
      const { data } = await getNodeResult(params);
      if (data.code === 200) {
        const { col, tableData } = this.formatTableData(data.data);
        this.setState({
          columns: col,
          tableData
        });
      }
    }
  };

  formatTableData = (data: any) => {
    const col = data.header.map((item: any) => ({
      title: item,
      dataIndex: item,
      key: item
    }));
    const tableData = data.content.map((item: any, index: number) => {
      const obj = {
        key: index.toString()
      } as any;
      item.forEach((item: any, index: any) => {
        obj[col[index].key] = item;
      });
      return obj;
    });
    return {
      col,
      tableData
    };
  };

  render() {
    return (
      <div className="node-script">
        {/* 脚本节点信息 */}
        <Form
          ref={this.formRef as any}
          name="datasourceInfo"
          autoComplete="off"
          layout="vertical"
          initialValues={{
            nodeId: this.props.nodeInfo.nodeId,
            paramText: this.props.nodeInfo.paramText,
            nodeName: this.props.nodeInfo.nodeName
          }}
          onValuesChange={(changedValue, values) => {
            const paramText = values.paramText;
            const nodeName = values.nodeName;
            this.props.nodeInfo.paramText = paramText;
            this.props.nodeInfo.nodeName = nodeName;
            this.props.node.setData({ ...this.props.nodeInfo });
          }}
        >
          <Form.Item name="nodeId" label="节点ID">
            <Input disabled />
          </Form.Item>
          <Form.Item name="nodeName" label="节点名称:">
            <Input placeholder="请输入节点名称" />
          </Form.Item>
          <p>输入:</p>
          {Array.from({ length: this.state.inputNumber }, (_, i) => (
            <div
              style={{
                display: 'flex',
                alignItems: 'center',
                columnGap: '2px',
                width: '30%',
                marginBottom: '5px'
              }}
              key={i}
            >
              <Input
                disabled
                style={{ width: '70%' }}
                defaultValue={`input` + i}
              />
              {i === this.state.inputNumber - 1 && (
                <MinusCircleOutlined
                  onClick={() => {
                    this.updateNumber(this.state.inputNumber - 1);
                  }}
                  style={{ color: '#147BD1' }}
                />
              )}
            </div>
          ))}
          <Button
            type="link"
            onClick={() => {
              this.updateNumber(this.state.inputNumber + 1);
            }}
            icon={<PlusCircleOutlined />}
            style={{ paddingLeft: 0, paddingRight: 0 }}
          >
            添加输入
          </Button>
          {/* <Form.Item name='paramText' label="参数文本:">
            <Input.TextArea placeholder='# input will be transfered into context_string'/>
          </Form.Item> */}
          <Form.Item label="脚本编辑:">
            <Button
              type="link"
              onClick={this.showScriptModal}
              icon={<EditOutlined />}
              style={{ paddingLeft: 0, paddingRight: 0 }}
            >
              编辑脚本
            </Button>
          </Form.Item>
          <p>输出结果:</p>
          {Array.from({ length: this.state.outputNumber }, (_, i) => (
            <div
              style={{
                display: 'flex',
                alignItems: 'center',
                columnGap: '2px',
                width: '30%',
                marginBottom: '5px'
              }}
              key={i}
            >
              <Input disabled style={{ width: '70%' }} defaultValue={`r` + i} />
              {i === this.state.outputNumber - 1 && (
                <MinusCircleOutlined
                  onClick={() => {
                    this.updateOutputNumber(this.state.outputNumber - 1);
                  }}
                  style={{ color: '#147BD1' }}
                />
              )}
            </div>
          ))}
          {!(
            this.props.nodeInfo.label === 'sql' && this.state.outputNumber > 0
          ) && (
            <Button
              type="link"
              onClick={() => {
                this.updateOutputNumber(this.state.outputNumber + 1);
              }}
              icon={<PlusCircleOutlined />}
              style={{ paddingLeft: 0, paddingRight: 0 }}
            >
              添加输出
            </Button>
          )}
          <Form.Item style={{ marginTop: '20px' }}>
            <Space>
              <Button
                type="primary"
                onClick={() => {
                  this.submit();
                }}
              >
                确认
              </Button>
              <Button
                onClick={() => {
                  this.onReset();
                }}
              >
                取消
              </Button>
            </Space>
          </Form.Item>
        </Form>
        {/* 脚本编辑弹窗 */}
        <Modal
          title="编辑脚本"
          open={this.state.scriptModalVisible}
          onOk={this.submitScriptEdit}
          className="script-modal"
          destroyOnClose={true}
          width={'90%'}
          style={{ top: 20 }}
          onCancel={() => {
            this.setState({ scriptModalVisible: false });
          }}
          footer={[
            <Button
              key="back"
              onClick={() => {
                this.setState({ scriptModalVisible: false });
              }}
            >
              取消
            </Button>,
            <Button
              loading={this.state.checking}
              key="check"
              type="primary"
              onClick={() => {
                this.submitSyntaxCheck();
              }}
            >
              代码校验
            </Button>,
            <Button key="submit" type="primary" onClick={this.submitScriptEdit}>
              确定修改
            </Button>
          ]}
        >
          <div className="modal-container">
            {/* 数据表展示 */}
            <div className="modal-table">
              {this.state.inputNumber === 0 ? (
                <Empty
                  style={{
                    margin: '50% 0',
                    transform: 'translate(0, -50%)'
                  }}
                  image={Empty.PRESENTED_IMAGE_SIMPLE}
                  description={<span>暂无输入数据</span>}
                />
              ) : (
                <Collapse
                  accordion
                  onChange={this.changeCollapse}
                  defaultActiveKey={'input0'}
                >
                  {Array.from({ length: this.state.inputNumber }, (_, i) => (
                    <Panel
                      header={`input${i}`}
                      key={`input${i}`}
                      style={{ position: 'relative', paddingTop: 0 }}
                    >
                      <div style={{ position: 'absolute', right: 0, left: 0 }}>
                        <Table
                          showHeader={this.state.tableData?.length !== 0}
                          bordered
                          columns={this.state.columns}
                          dataSource={this.state.tableData}
                          scroll={{ x: this.state.columns * 120, y: 400 }}
                          pagination={{ showSizeChanger: false }}
                        />
                      </div>
                    </Panel>
                  ))}
                  {/* <Panel header="input1" key="1" style={{position: 'relative', paddingTop: 0}}>

                  </Panel>
                  <Panel header="input2" key="2"></Panel>
                  <Panel header="input3" key="3"></Panel> */}
                </Collapse>
              )}
            </div>
            {/* 脚本编辑 */}
            <div className="modal-script">
              <div className="script-header"></div>
              <ScriptEditor
                inputNumber={this.state.inputNumber}
                outputNumber={this.state.outputNumber}
                type={this.props.nodeInfo.label}
                scriptText={this.state.editorValue}
                ref={this.editorRef as any}
              />
            </div>
          </div>
        </Modal>
      </div>
    );
  }
}
