import React from 'react';
import CodeMirror from 'codemirror';
import { codeCheck } from './request';
import 'codemirror/lib/codemirror.css'; // CodeMirrory原生样式
import 'codemirror/mode/sql/sql';
import 'codemirror/mode/python/python';
import 'codemirror/mode/shell/shell';
import 'codemirror/addon/display/placeholder';
import 'codemirror/addon/hint/show-hint.css'; // 用来做代码提示
import 'codemirror/addon/hint/show-hint.js'; // 用来做代码提示
import 'codemirror/addon/hint/sql-hint.js'; // 用来做代码提示
import 'codemirror/addon/lint/lint.js';
import 'codemirror/addon/lint/lint.css';
import { message } from 'antd';
import { getEditorTemplate } from './utils';

// const pyTemplate = "# 参考模板\ndef run(input0, input1):\n    r0 = input0\n    r1 = input1\n    return [r0, r1]\n"

// const sqlTemplate = "/* 参考模板 */\nselect * from input0 where input0 = input0;\nselect * from input1 where input1 = input1;"

export default class ScriptEditor extends React.Component<any, any> {
  constructor(props: any) {
    super(props);
    this.state = {
      editor: {}
    };
  }

  python_validator(content: any, updateLinting: any, options: any, cm: any) {
    const text = cm.getValue() + '\n';

    if (text.trim() == '') {
      updateLinting(cm, []);
      return;
    }

    console.log('options:', options);
    updateLinting(cm, options.error_list);
  }

  async checkSyntax() {
    message.loading({ content: '正在校验代码，请稍等...', key: 'check' });
    const editor = this.state.editor;
    const code = editor.getValue();
    const code_type = this.props.type === 'sql' ? 'sql' : 'python';
    const { data } = await codeCheck({
      code,
      code_type
    });
    const error_list: Array<any> = [];
    if (data.code === 200) {
      switch (code_type) {
        case 'python':
          data.data.forEach((item: any) => {
            if (item.type === 'error' || item.type === 'warning') {
              error_list.push({
                from: CodeMirror.Pos(item.line - 1, 0),
                to: CodeMirror.Pos(item.line - 1, 0),
                message: item.message,
                severity: item.type
              });
            }
          });
          break;
        case 'sql':
          data.data.forEach((item: any) => {
            error_list.push({
              from: CodeMirror.Pos(item.line_no - 1, 0),
              to: CodeMirror.Pos(item.line_no - 1, 0),
              message: item.description,
              severity: 'error'
            });
          });

        default:
          break;
      }
    } else {
      message.error('获取校验数据失败');
    }
    editor.setOption('lint', {
      getAnnotations: this.python_validator,
      async: true,
      options: {
        error_list
      }
    });
    message.success({ content: '代码校验完成!', key: 'check', duration: 2 });
  }

  componentDidMount() {
    const editor = CodeMirror.fromTextArea(
      document.querySelector('.editor') as any,
      {
        lineNumbers: true,
        mode: this.props.type === 'sql' ? 'sql' : 'python',
        gutters: ['CodeMirror-lint-markers'],
        lint: {
          getAnnotations: this.python_validator,
          async: true,
          options: {
            error_list: []
          }
        },
        indentUnit: 4,
        tabSize: 4,
        extraKeys: {
          Tab: cm => {
            const indentUnit = cm.getOption('indentUnit') as number;
            var spaces = Array(indentUnit + 1).join(' ');
            cm.replaceSelection(spaces);
          }
        }
      }
    );
    editor.setSize(null, '100%');
    const template = getEditorTemplate(this.props);
    const value = this.props.scriptText.trim();
    editor.setValue(value ? value : template);
    this.setState({ editor });
  }

  render() {
    return <textarea className="editor"></textarea>;
  }
}
