import React, { useEffect, useCallback, useState } from 'react';
import { Button, Checkbox, Form, Icon, Radio, Input, message } from 'antd';
import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor";
import DelModal from './components/ModalFun';
import { weekModal, monthModal } from './components/config';
import { getWiki, wikiPages, addWiki, updateWiki, markdownToTree, treeToMd } from './api';
import './Index.scss';
import { Base64 } from 'js-base64';


export default Form.create()(({ form, history, showNotification, projectDetail, match, project }) => {
  const {location:{pathname, search}} = history;
  const permission = projectDetail && projectDetail.permission && projectDetail.permission !== "Reporter";

  const { getFieldDecorator, validateFields, setFieldsValue } = form;
  let projectsId = match.params.projectsId;
  let owner = match.params.owner;
  let wikiName = ''
  let key = '';
  if (!pathname.endsWith('/wiki/add')) {
    wikiName = decodeURI(pathname.split('/')[4]);
    key = pathname.split('/')[5];
  }else{
    key = search.split('=').pop();
  }

  const [fileArrInit, setFileArrInit] = useState(null);
  const [content, setContent] = useState("欢迎来到Wiki");
  const [modal, setModal] = useState(false);
  const [operateFlag, setOperateFlag ] = useState(false);
  const [modalType, setModalType] = useState();
  const [sidebar, setSidebar] = useState(undefined);
  const [menuList, setMenuList] = useState(undefined);

  useEffect(()=>{
    if(projectDetail){
      const { author, name} = projectDetail;
      if(wikiName){
        document.title = `编辑${wikiName}-维基-${author.name}/${name}`;
      }else{
        document.title = `新建维基-${author.name}/${name}`;
      }
    }
  }, [projectDetail, wikiName])

  useEffect(() => {
    wikiName && project && getWiki({
      owner,
      repo: projectsId,
      pageName: wikiName,
      projectId: project.id
    }).then(res => {
      if (res && res.data) {
        const content = Base64.decode(res.data.md_content);
        setContent(content);
        setFieldsValue({
          title: res.data.name,
          md_content: content,
        });
      }
    });
  }, [owner, wikiName]);

  // 加载wiki列表
  useEffect(() => {
    project && wikiPages({
      owner: owner,
      repo: projectsId,
      projectId: project.id
    }).then(res => {
      if (res && res.message === "200" && Array.isArray(res.data)) {
        setFileArrInit(res.data);
        // 仓库存在没有创建过wiki的情况
        if(res.data.length){
          // 获取sidebar文件内容
          getWiki({
            owner,
            repo: projectsId,
            pageName: '_Sidebar',
            projectId: project.id
          }).then(res => {
            if (res && res.data) {
              const sidebarDecode = Base64.decode(res.data.md_content);
              setSidebar(sidebarDecode);
              key && setMenuList(markdownToTree(sidebarDecode))
            }
          });
        }
      } else {
        setFileArrInit([]);
      }
    });
  }, [project]);

  const helper = useCallback(
    (label, name, rules, widget, initialValue, rightComponent) => (
      <Form.Item label={label} className="mb0">
        {getFieldDecorator(name, { rules, initialValue, validateFirst: true, })(widget)}
        {rightComponent}
      </Form.Item>
    ), []);


  function onContentChange(value) {
    setContent(value);
    setFieldsValue({
      md_content: value
    });
  };

  // 保存wiki文件，包括新增和修改
  function saveFile() {
    if(operateFlag) {
      setOperateFlag(true);
      return;
    };
    validateFields((err, values) => {
      if (!err) {
        let regEn = /[\\/:*?"<>|[\]-]/g;
        if (regEn.test(values.title)) {
          message.error('文件名不能有特殊字符: \\ / : * ? \" < > | [ \] -');
          setOperateFlag(false);
          return;
        }
        const {md_content, title} = values;
        if (wikiName) {
          updateWiki({
            owner,
            repo: projectsId,
            projectId: project.id,
            pageName: wikiName,
            title,
            commit_message: '',
            content_base64: Base64.encode(md_content)
          }).then(res => dealRes(res, title));
        } else {
          // 由于wiki在底层是由wikiname标识的md文件，所以对于所有的页面，都不能重名
          if (Array.isArray(fileArrInit)) {
            for (const item of fileArrInit) {
              if (item.name === title) {
                message.error('不能与已有文件标题相同');
                setOperateFlag(false);
                return false;
              }
            }
          }
          addWiki({
            owner,
            repo: projectsId,
            projectId: project.id,
            pageName: title,
            title,
            message: '',
            content_base64: Base64.encode(md_content)
          }).then(res => dealRes(res, title));
        }
      }
    })
  }

  function dealRes(res, title) {
    if (res && (res.message === "201" || res.message === "200")) {
      if(wikiName){
        // 如果有更改wiki文件名，则修改sidebar
        if(wikiName === title){
          message.success("操作成功");
          goBack();
        }else{
          // 找到相同的key值node修改title参数，再保存sidebar
          const newMenuList = menuList;
          editTitleByKey(newMenuList, key, title);
          updateSidebar(treeToMd(newMenuList), title);
        }
      }else{
        // 根据路由判断是新增的一级页面还是子页面
        if(search.includes("?key")){
          // 遍历menuList找到相同key的节点，children push[[页面]]
          const list = menuList;
          addChildrenByKey(list, key, title);
          updateSidebar(treeToMd(list), title);
        }else{
          if(fileArrInit.length){
            updateSidebar(`${sidebar}\n[[${title}]]`, title);
          }else{
            // 仓库第一次创建wiki文件
            addWiki({
              owner,
              repo: projectsId,
              projectId: project.id,
              pageName: "_Sidebar",
              title: "_Sidebar",
              message: '',
              content_base64: Base64.encode(`[[${title}]]`)
            }).then(res => {
              if(res && res.message === "201"){
                message.success("操作成功");
                goBack();
              }
            });
          }
        }
      }
    } else if (res && res.message === "500") {
      setOperateFlag(false);
      message.error('请检查格式是否正确或文件名是否重复');
    } else {
      setOperateFlag(false);
      showNotification(res.data || "操作失败");
    }
  }

  function updateSidebar(content, newTitle){
    updateWiki({
      owner,
      repo: projectsId,
      projectId: project.id,
      pageName: '_Sidebar',
      title: '_Sidebar',
      commit_message: '',
      content_base64: Base64.encode(content)
    }).then(res => {
      if (res && res.message === "200") {
        message.success("操作成功");
        if(newTitle){
          // 用户修改了wiki名称
          history.push(`/${owner}/${projectsId}/wiki/${encodeURI(newTitle)}/${key}`)
          return;
        }
        goBack();
      }
    });
  }

  // 递归menuList, 找到相同key值修改title名称
  function editTitleByKey(list, key, newTitle){
    for (let index = 0; index < list.length; index++) {
      const element = list[index];
      if (element.key == key) {
        const {title} = element;
        element.title = `${title.substring(0, title.indexOf('[['))}[[${newTitle}]]`;
        return true;
      }else if (element.children.length) {
        let result = editTitleByKey(element.children, key, newTitle);
        if (result) {
          return result;
        }
      }
    }
  }

  // 递归menuList 创建子页面
  function addChildrenByKey(list, key, name){
    for (let index = 0; index < list.length; index++) {
      const element = list[index];
      if (element.key == key) {
        const {title} = element;
        element.children.push({
          title: `\t${title.substring(0, title.indexOf('- '))}[[${name}]]`,
          children: []
        });
        return true;
      }else if (element.children.length) {
        let result = addChildrenByKey(element.children, key, name);
        if (result) {
          return result;
        }
      }
    }
  }

  function goBack() {
    history.go(-1);
  }

  function changeModal(e) {
    setModal(e.target.checked);
    if (!e.target.checked) {
      setModalType();
    }
  }

  function changeModalType(e) {
    let value = e.target.value;
    if (!content) {
      setModalContent(value);
      return;
    }
    DelModal({
      title: '添加模版',
      contentTitle: `您确定要添加“${value}”模板吗`,
      content: `此操作会将“${value}”模板替换编辑栏内所有内容，请确认以防文件的丢失`,
      okText: '确认添加',
      onOk: () => {
        setModalType(value);
        setModal(true);
        setModalContent(value);
      }
    });
  }

  function setModalContent(value) {
    if (value === '周报') {
      setContent(weekModal);
      setFieldsValue({
        md_content: weekModal
      });
    } else if (value === '月报') {
      setContent(monthModal);
      setFieldsValue({
        md_content: monthModal
      });
    }
  }


  return (
    <div className="wiki-main">
      <div className="wiki-head">
        <span className="head-title"><span className="back-wiki" onClick={goBack}>Wiki</span> <Icon type="right" /> {wikiName ? '编辑' : '新增'}页面</span>
      </div>

      <div >
        <h4 className="mt20 mb0">标题</h4>
        {helper(
          "",
          "title",
          [
            { required: true, message: "请输入标题" },
            // { pattern: /[^`\[\]\/:*?''<>|%-+_]/g, message: '不允许部分特殊字符' }
          ],
          <Input
            placeholder={"请输入标题"}
            className="contact-input"
            maxLength={50}
          />
        )}

        <Form.Item className="mb0 wiki-md">
          <MDEditor
            placeholder={"请输入wiki内容"}
            height={500}
            mdID={"order-new-description"}
            initValue={content}
            onChange={onContentChange}
            className="mt20 wikiMEDEditor"
          ></MDEditor>
          {getFieldDecorator('md_content', {
            rules: [{ required: true, message: "请输入wiki内容" }],
            validateFirst: true,
            initialValue: "欢迎来到Wiki"
          })(<Input style={{ display: 'none' }} />)}
        </Form.Item>

        <Checkbox checked={modal} onChange={changeModal}>添加模版</Checkbox>

        <Radio.Group onChange={changeModalType} value={modalType}>
          <Radio value='周报'>周报</Radio>
          <Radio value='月报'>月报</Radio>
        </Radio.Group>

      </div>

      {permission && <Button className="mt25" type="primary" onClick={saveFile}>保存</Button>}
    </div>

  )
})