import React from 'react';
import { Form, Input, InputNumber, Tabs, Switch, Checkbox, Row, Col, Button, Tag, Dropdown, Menu } from 'antd';
import './index.less';
import Page from '@src/containers/Page';
import Block from '@src/components/Block';
import Editor from '@src/components/Editor';
// import ContextMenuLayout from '@src/layouts/ContextMenuLayout';
// import Select from '@src/components/Select';
// import FileUpload from '@src/components/FileUpload';
import { formatFormError, generateUUID } from '@src/services/Tools';
import { asyncSMessage } from '@src/services/AsyncTools';
import { SentenceOption } from '../../../../Constant';
// import { Preview } from '../../../stores/preview';
import { Exercise } from '../../../stores/exercise';
import { Sentence } from '../../../stores/sentence';
import config from './index';

const stopWords = [',', '.', ':', '!', ';', '?', '\\', '/', '`', '\'', '', '。', ',', '?', '!', '“', '”'];
const htmlReg = /[.,!?。,!?“”]*<[^>]+>[.,!?。,!?“”]*/i;
const sReg = /[.,!?。,!?“”]+/i;
// const uuidReg = /@(.*)@(.*)/i;

export default class extends Page {
  constructor(props) {
    super(props);
    this.targetWord = null;
    this.uuidMap = {};
    this.uuidList = [];

    const { id } = this.params;
    if (id) {
      config.title = '编辑长难句题目';
    } else {
      config.title = '添加长难句题目';
    }
  }

  initState() {
    return { currentKey: 'subject' };
  }

  init() {
    Exercise.allStruct().then(result => {
      result = result.filter(row => row.level === 2).map(row => { row.title = `${row.titleZh}/${row.titleEn}`; row.value = row.id; return row; });
      this.setState({ exercise: result });
    });
  }

  initData() {
    const { id } = this.params;
    const { form } = this.props;
    this.uuidMap = {};
    this.uuidList = [];
    this.targetWord = null;
    let handler;
    if (id) {
      handler = Sentence.getQuestion({ id });
      this.setState({ mode: 'setting' });
    } else {
      // "<p><span uuid='CmS0'>The</span> <span uuid='2BKs'>furthest</span> <span uuid='3JxJ'>distance</span> <span uuid='hVsF'>in</span> <span uuid='OlAJ'>the</span> <span uuid='RrCt'>world</span>&nbsp;<span uuid='Axff'></span>&nbsp;<span uuid='wovI'></span></p><p><span uuid='odI3'>Is</span> <span uuid='HHXm'>not</span> <span uuid='ld8s'>between</span> <span uuid='wuh2'>life</span> <span uuid='o29m'>and</span> <span uuid='NLCc'>death</span>&nbsp;<span uuid='GCaB'></span></p><p><span uuid='WENt'>But</span> <span uuid='kHpB'>when</span> <span uuid='nMb4'>I</span> <span uuid='CNoW'>stand</span> <span uuid='EwJh'>in</span> <span uuid='MOL4'>front</span> <span uuid='Vg1e'>of</span> <span uuid='aZAW'>you</span>&nbsp;<span uuid='z7zD'></span></p><p><span uuid='hLr7'>Yet</span> <span uuid='s7lJ'>you</span> <span uuid='xhmd'>don\"t</span> <span uuid='uKQk'>know</span> <span uuid='mDus'>that</span> <span uuid='neve'>I</span> <span uuid='yWSc'>love</span> <span uuid='7JRW'>you</span></p>"
      handler = Promise.resolve({ no: 1, question: { stem: '' } });
    }
    handler
      .then(result => {
        result.isPaper = !!result.isPaper;
        result.isTrail = !!result.isTrail;
        result.question.questionType = 'sentence';
        result.question.answer = result.question.answer || {};
        form.getFieldDecorator('question.answer.subject');
        form.getFieldDecorator('question.answer.predicate');
        form.getFieldDecorator('question.answer.object');
        form.getFieldDecorator('question.answer.options');

        form.getFieldDecorator('question.qxContent');
        form.getFieldDecorator('question.stem');
        form.getFieldDecorator('question.questionType');
        form.getFieldDecorator('question.place');
        form.getFieldDecorator('question.id');
        form.getFieldDecorator('questionId');
        form.getFieldDecorator('chinese');
        form.getFieldDecorator('title');
        form.getFieldDecorator('isPaper');
        form.getFieldDecorator('isTrail');
        form.getFieldDecorator('no');
        form.getFieldDecorator('id');
        form.setFieldsValue(result);
        const { stem } = result.question;
        const { subject, predicate, object } = result.question.answer;
        this.setState({ data: result, subject, predicate, object, stem });

        // 生成uuid列表
        this.uuidList = (stem || '').replace(/<span\suuid=["']([^>]*)["']>([^<>]*)<\/span>/g, '@@$1_@_$2@@').split('@@').filter(row => row.indexOf('_@_') >= 0).map(row => {
          const [uuid, content] = row.split('_@_');
          this.uuidMap[uuid] = content;
          return uuid;
        });
        console.log(this.uuidList, this.uuidMap);
      });
  }

  submit() {
    const { form } = this.props;
    const { mode } = this.state;
    if (mode !== 'setting') {
      asyncSMessage('请先退出编辑模式', 'warn');
      return;
    }
    form.validateFields((err) => {
      if (!err) {
        const data = form.getFieldsValue();
        data.isTrail = data.isTrail ? 1 : 0;
        data.isPaper = data.isPaper ? 1 : 0;
        data.question.stem = this.state.stem;
        data.question.description = data.question.stem.replace(/<[^>]+>/g, '');
        data.question.answer = data.question.answer || {};

        let handler;
        if (!data.id) {
          handler = Sentence.addQuestion(data);
        } else {
          handler = Sentence.editQuestion(data);
        }
        handler.then((result) => {
          asyncSMessage('保存成功');
          if (data.id) {
            linkTo(`/subject/sentence/question/${data.id}`);
          } else {
            linkTo(`/subject/sentence/question/${result.id}`);
          }
        }).catch((e) => {
          if (e.result) form.setFields(formatFormError(data, e.result));
        });
      }
    });
  }

  removeAnswer(key, index) {
    const { setFieldsValue, getFieldValue } = this.props.form;
    const data = getFieldValue(`question.answer.${key}`) || [];
    if (data.length > index) {
      data.splice(index, 1);
    }
    setFieldsValue({ [`question.answer.${key}`]: data });
    this.setState({ [key]: data });
  }

  addAnswer(key, uuid, text) {
    const { setFieldsValue, getFieldValue } = this.props.form;
    const data = getFieldValue(`question.answer.${key}`) || [];
    data.push([{ text, uuid }]);
    setFieldsValue({ [`question.answer.${key}`]: data });
    this.setState({ [key]: data });
  }

  appendAnswer(key, index, uuid, text) {
    const { setFieldsValue, getFieldValue } = this.props.form;
    const data = getFieldValue(`question.answer.${key}`) || [];
    data[index].push({ text, uuid });
    setFieldsValue({ [`question.answer.${key}`]: data });
    this.setState({ [key]: data });
  }

  renderContextMenu() {
    const { getFieldValue } = this.props.form;
    const { currentKey } = this.state;
    const uuid = this.targetWord.getAttribute('uuid');
    const text = this.targetWord.innerText;
    const data = getFieldValue(`question.answer.${currentKey}`) || [];
    const items = [];
    items.push({ title: '新答案', command: 'new' });
    data.forEach((row, i) => {
      // 过滤已经在的答案
      if (row.filter(r => r.uuid !== uuid).length !== row.length) return;
      items.push({ title: `插入: ${row.map(r => r.text).join(', ')}`, command: 'append', i });
    });
    return (
      <Menu onClick={k => this.clickContentMenu(currentKey, k, uuid, text)}>
        {items.map((item, i) => {
          return <Menu.Item key={i} command={item.command} i={item.i}>{item.title || item.name}</Menu.Item>;
        })}
      </Menu>
    );
  }

  clickContentMenu(key, k, uuid, text) {
    const item = k.item.props;
    switch (item.command) {
      case 'new':
        this.addAnswer(key, uuid, text);
        break;
      case 'append':
        this.appendAnswer(key, item.i, uuid, text);
        break;
      default:
    }
  }

  generateContent(content) {
    const { setFieldsValue } = this.props.form;
    // 处理编辑器未清除的标签: 主要是包含空格的标签属性
    content = content.replace(/<[^>]+\s+[^>]+>([^<>]*)<\/[^>]+>/g, '$1');
    this.index = 0;
    const list = ['</p><p>', ' ', ',', '.', '!', '?', '&nbsp;', ':', ';'];
    const result = this.splitList(list, 0, content);
    // console.log(this.uuidList, this.uuidMap);
    // 对比答案,是否uuid存在
    let { subject = [], predicate = [], object = [] } = this.state;
    let flag = false;
    subject = subject.map(row => {
      return row.filter(r => {
        if (this.uuidMap[r.uuid] === r.text) return true;
        flag = true;
        return false;
      });
    }).filter(row => row.length);
    predicate = predicate.map(row => {
      return row.filter(r => {
        if (this.uuidMap[r.uuid] === r.text) return true;
        flag = true;
        return false;
      });
    }).filter(row => row.length);
    object = object.map(row => {
      return row.filter(r => {
        if (this.uuidMap[r.uuid] === r.text) return true;
        flag = true;
        return false;
      });
    }).filter(row => row.length);

    if (flag) {
      asyncSMessage('修改影响答案,请再次确认答案', 'warn');
      setFieldsValue({ 'question.answer.subject': subject, 'question.answer.predicate': predicate, 'question.answer.object': object });
      // console.log(subject, predicate, object);
      this.setState({ subject, predicate, object });
    }
    return result;
  }

  splitList(list, index, content) {
    if (list.length === index) {
      return this.generateText(content);
    }
    const result = content.split(list[index]).map(row => {
      return this.splitList(list, index + 1, row);
    });
    if (result.length === 0) return content;
    if (result.length === 1) return result[0];
    return result.join(list[index]);
  }

  generateText(content) {
    if (content.indexOf(stopWords) >= 0) return content;
    // 判断是否包含html标签
    const r = htmlReg.exec(content);
    if (r === null) {
      const sr = sReg.exec(content);
      if (sr === null) {
        return this.generateTag(content);
      }
      // 句尾标点符号
      return `${this.generateTag(content.replace(sr[0], ''))}${sr[0]}`;
    }
    if (r.index === 0) {
      // 头部html标签
      return `${r[0]}${this.generateTag(content.replace(r[0], ''))}`;
    }
    // 尾部html标签
    return `${this.generateTag(content.replace(r[0], ''))}${r[0]}`;
  }

  generateTag(content) {
    // return `<span>${content}</span>`;
    // 处理uuid信息
    // const r = uuidReg.exec(content);
    // if (r === null) {

    let uuid;
    if (this.uuidList.length <= this.index) {
      do {
        uuid = generateUUID(4);
      } while (this.uuidMap[uuid]);
      this.uuidMap[uuid] = content;
      this.uuidList.push(uuid);
    } else {
      uuid = this.uuidList[this.index];
      this.uuidMap[uuid] = content;
    }
    this.index += 1;
    return `<span uuid='${uuid}'>${content}</span>`;
    // }
    // uuidMap[r[1]] = `${r[2]}`;
    // return `<span uuid='${r[1]}'>${r[2]}</span>`;
  }

  renderTitle() {
    const { getFieldDecorator } = this.props.form;
    return <Block>
      <Form>
        {getFieldDecorator('id')(<input hidden />)}
        <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='题目序号'>
          {getFieldDecorator('no', {
            rules: [
              { required: true, message: '请输入序号' },
              // {
              //   validator: (rule, value, callback) => {
              //     if (this.partList.indexOf(value) >= 0) callback('该part已被使用');
              //     else callback();
              //     callback();
              //   },
              // },
            ],
          })(
            <InputNumber min={1} precision={0} formatter={(v) => parseInt(v, 10) || 1} />,
          )}
        </Form.Item>
        <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='名称'>
          {getFieldDecorator('title', {
            rules: [
              { required: true, message: '请输入名称' },
            ],
          })(
            <Input placeholder='请输入' />,
          )}
        </Form.Item>
        <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='开放试用'>
          {getFieldDecorator('isTrail', {
            valuePropName: 'checked',
          })(
            <Switch checkedChildren='on' unCheckedChildren='off' />,
          )}
        </Form.Item>
        {/* 不允许修改组卷逻辑 */}
        <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='组卷题目' >
          {getFieldDecorator('isPaper', {
            valuePropName: 'checked',
          })(
            <Switch checkedChildren='on' unCheckedChildren='off' />,
          )}
        </Form.Item>
      </Form>
    </Block>;
  }

  renderBase() {
    const { getFieldDecorator, getFieldValue, setFieldsValue } = this.props.form;
    const { stem, mode } = this.state;
    return <Block flex>
      <h1>题干信息:
        <Switch checked={mode !== 'setting'} checkedChildren='编辑模式' unCheckedChildren='设置模式' onChange={(value) => {
          if (value) {
            // console.log(stem);
            getFieldDecorator('question.stem');
            setFieldsValue({ 'question.stem': stem });
            this.setState({ mode: 'edit' });
          } else {
            // 编辑器未修改会使用添加好uuid标签的结果
            // 通过保留onChange获取到最后一次修改记录
            this.setState({ mode: 'setting', stem: this.generateContent(this.stem || getFieldValue('question.stem') || '') });
          }
        }} /></h1>
      <Form>
        {getFieldDecorator('question.id')(<input hidden />)}
        {<Form.Item style={{ display: (mode === 'edit' || !mode) ? 'block' : 'none' }}>
          {getFieldDecorator('question.stem')(
            <Editor
              // onChange={(content, delta, source, editor) => {
              //   console.log(content, delta, source, editor);
              //   setFieldsValue({ 'question.stem': content });
              // }}
              onChange={(content) => {
                this.stem = content;
                // console.log(this.stem);
              }}
              placeholder='请输入内容' />,
          )}
        </Form.Item>}
        {mode === 'setting' && <Dropdown overlay={() => this.renderContextMenu()} trigger={['click']}><div className='stem-content' dangerouslySetInnerHTML={{ __html: stem }} onClick={(e) => {
          this.targetWord = e.target;
        }} /></Dropdown>}
      </Form>
    </Block>;
  }

  renderAnswer() {
    const { getFieldDecorator } = this.props.form;
    const { subject = [], predicate = [], object = [], currentKey } = this.state;
    return <Block flex>
      <h1>题目答案: <span>进入设置模式,选择主谓宾后,点击答案单词</span></h1>
      <table boarder cellSpacing className='answer'>
        <tr>
          <td width={30}><Checkbox checked={currentKey === 'subject'} onClick={(value) => value.target.checked && this.setState({ currentKey: 'subject' })} /> 主语</td>
          <td><Form.Item>
            {getFieldDecorator('question.answer.subject', {
              rules: [{ required: true, message: '请输入主语' }],
            })(<input hidden />)}
            {subject.map((row, index) => {
              return <Tag key={index} closable visible onClose={() => {
                this.removeAnswer('subject', index);
              }}>{row.map(r => r.text).join(', ')}</Tag>;
            })}
          </Form.Item></td>
        </tr>
        <tr>
          <td><Checkbox checked={currentKey === 'predicate'} onClick={(value) => value.target.checked && this.setState({ currentKey: 'predicate' })} /> 谓语</td>
          <td><Form.Item>
            {getFieldDecorator('question.answer.predicate', {
              rules: [{ required: true, message: '请输入谓语' }],
            })(<input hidden />)}
            {predicate.map((row, index) => {
              return <Tag key={index} closable visible onClose={() => {
                this.removeAnswer('predicate', index);
              }}>{row.map(r => r.text).join(', ')}</Tag>;
            })}
          </Form.Item></td>
        </tr>
        <tr>
          <td><Checkbox checked={currentKey === 'object'} onClick={(value) => value.target.checked && this.setState({ currentKey: 'object' })} /> 宾语</td>
          <td><Form.Item>
            {getFieldDecorator('question.answer.object', {
              rules: [{ required: true, message: '请输入宾语' }],
            })(<input hidden />)}
            {object.map((row, index) => {
              return <Tag key={index} closable visible onClose={() => {
                this.removeAnswer('object', index);
              }}>{row.map(r => r.text).join(', ')}</Tag>;
            })}
          </Form.Item></td>
        </tr>
      </table>
    </Block >;
  }

  renderOption() {
    const { getFieldDecorator } = this.props.form;
    return <Block flex>
      <h1>选项信息(长难句)</h1>
      <Form>
        <Form.Item>
          {getFieldDecorator('question.answer.options', {
            rules: [{ required: true, message: '请输入选项信息' }],
          })(
            <Checkbox.Group options={SentenceOption} />,
          )}
        </Form.Item>
      </Form>
    </Block>;
  }

  renderQX() {
    const { getFieldDecorator } = this.props.form;
    return <Block flex>
      <Form>
        <Form.Item label='千行解析'>
          {getFieldDecorator('question.qxContent', {
          })(
            <Editor placeholder='输入内容' />,
          )}
        </Form.Item>
      </Form>
    </Block>;
  }

  renderChinese() {
    const { getFieldDecorator } = this.props.form;
    return <Block flex>
      <Form>
        <Form.Item label='中文解析'>
          {getFieldDecorator('chinese', {
          })(
            <Editor placeholder='输入内容' />,
          )}
        </Form.Item>
      </Form>
    </Block>;
  }

  renderTab() {
    return <Tabs activeKey='sentence' onChange={(tab) => {
      switch (tab) {
        case 'textbook':
          linkTo('/subject/textbook/question');
          break;
        case 'base':
          linkTo('/subject/question');
          break;
        default:
      }
    }}>
      <Tabs.TabPane key='base' tab='考试题型' />
      <Tabs.TabPane key='sentence' tab='长难句' />
      <Tabs.TabPane key='textbook' tab='数学机经' />
    </Tabs>;
  }

  renderView() {
    return <div flex >
      {this.renderTab()}
      {this.renderTitle()}
      {this.renderBase()}
      {this.renderAnswer()}
      {this.renderOption()}
      {this.renderQX()}
      {this.renderChinese()}
      <Row type="flex" justify="center">
        <Col>
          <Button type="primary" onClick={() => {
            this.submit();
          }}>保存</Button>
        </Col>
      </Row>
    </div>;
  }
}