import React, { useEffect, useCallback, useState, useMemo } from 'react';
import { Button, Dropdown, Icon, Input, Menu, Tooltip, Select, Upload, message, Spin, Modal } from 'antd';
import { getImageUrl, timeAgo } from 'educoder';
import cookie from 'react-cookies';
import CopyTool from '../Component/CopyTool';
import Welcome from './Welcome';
import RenderHtml from "../../components/render-html";

import { wikiPages, getWiki, parseSidebar, updateWiki, treeToMd } from './api';
import { httpUrl, TokenKey } from './fetch';
import './Index.scss';
import './components/ModalFun/index.scss';
import { isArray } from 'lodash';
import { Base64 } from 'js-base64';
import Sidebar from './components/sidebar';
import UploadWiki from './components/uploadWiki';
const InputGroup = Input.Group;
const { Option } = Select;

export default (props) => {
  const { match, history, showNotification, project, projectDetail } = props;
  const {location:{pathname}} = history;
  const permission = projectDetail && projectDetail.permission && projectDetail.permission !== "Reporter";
  let projectsId = match.params.projectsId;
  let owner = match.params.owner;

  const [fileArrInit, setFileArrInit] = useState(null);
  const [checkItem, setCheckItem] = useState({});
  const [itemDetail, setItemDetail] = useState({});

  const [fileArr, setFileArr] = useState([]);
  const [fileList, setFileList] = useState([]);
  const [reload, setReload] = useState();

  const [urlType, setUrlType] = useState('HTTPS');
  const [visible, setVisible] = useState(false);
  const [menuName, setMenuName] = useState(undefined);
  const [addMenuError, setAddMenuError] = useState(undefined);
  const [sidebar, setSidebar] = useState(undefined);
  const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(undefined);

  useEffect(()=>{
    window.scrollTo(0,0);
  }, [])

  useEffect(()=>{
    if(projectDetail){
      const { author, name} = projectDetail;
      if(Object.keys(checkItem).length === 0){
        document.title = `维基-${author.name}/${name}`;
      }else{
        document.title = `${checkItem.name}-维基-${author.name}/${name}`;
      }
    }
  }, [projectDetail, checkItem])

  // 加载wiki列表
  useEffect(() => {
    project && wikiPages({
      owner: owner,
      repo: projectsId,
      projectId: project.id
    }).then(async res => {
      if (res && res.message === "200" && isArray(res.data)) {
        setFileArr(res.data);
        setFileArrInit(res.data);
        // 解析sidebar获取目录list
        const info = await parseSidebar(res.data, {
          owner: owner,
          repo: projectsId,
          projectId: project.id
        })
        if(!info){return}
        const {menuList, sidebar} = info;
        setSidebar(sidebar)
        setFileList(menuList);
        let firstWikiNode = undefined;
        const arr = pathname.split('/');
        if(!pathname.endsWith('/wiki')){
          firstWikiNode = findNodeByName(menuList, arr[arr.length-2]);
        } else{
          // 找到目录树中第一个[[页面]]
          firstWikiNode = findFirstWiki(menuList);
        }
        // 当前选中wiki被删除
        !firstWikiNode && (firstWikiNode = findFirstWiki(menuList));
        // 设置目录 选中节点初始化
        setDefaultSelectedKeys([firstWikiNode.key+""]);
        const title = firstWikiNode.title.trim().substring(2,firstWikiNode.title.trim().length-2);
        const firstWiki = res.data.filter(item => { return title === item.name })[0];
        setCheckItem({
          ...firstWiki,
          key: firstWikiNode.key
        })
        history.push(`/${owner}/${projectsId}/wiki/${title}/${firstWikiNode.key}`);
      } else {
        setFileArr([]);
        setFileArrInit([]);
      }
    });
  }, [project, reload])

  // 加载单个wiki详情，参数尽量用驼峰，此处由于后端太麻烦所以不标准
  useEffect(() => {
    project && checkItem.name && getWiki({
      owner: owner,
      repo: projectsId,
      pageName: checkItem.name,
      projectId: project.id
    }).then(res => {
      if (res && res.message === "200") {
        setItemDetail(res.data);
      } else {
        showNotification("加载失败")
      }
    });
  }, [project, checkItem]);

  function findNodeByName(list, name){
    for (let index = 0; index < list.length; index++) {
      const element = list[index];
      if (element.title.indexOf(`[[${name}]]`) !== -1) {
        return element;
      }else if (element.children.length) {
        let result = findNodeByName(element.children, name);
        if (result) {
          return result;
        }
      }
    }
  }

  // 初始化页面：递归menulist找到第一个页面
  function findFirstWiki(list){
    for (let index = 0; index < list.length; index++) {
      const element = list[index];
      if (element.title.trim().startsWith('[[')) {
        return element;
      }else if (element.children.length) {
        let result = findFirstWiki(element.children);
        if (result) {
          return result;
        }
      }
    }
  }


  function filterTree(list, value, arr = []){
    if(!list.length) return []
    for(let item of list){
      const bool = item.title.match(new RegExp(value, 'i'));
      let node = JSON.parse(JSON.stringify(item));
      node.children = [];
      bool && arr.push(node);
      if(item.children && item.children.length){
        filterTree(item.children, value, bool ? node.children : arr);
      }
    }
    return arr
  }


  function goUser(login) {
    window.location.href = `/${login}`;
  }

  function addFile() {
    // 新增一级页面
    history.push(`/${owner}/${projectsId}/wiki/add`);
  }

  // 新增目录
  function addMenu(){
    if(!menuName){
      setAddMenuError('请输入目录名称');
      return;
    }
    if(new RegExp("^[ ]+$").test(menuName)){
      setAddMenuError("不能仅输入空格");
      return;
    }
    const regEn = /[\\/:*?"<>|[\]-]/g;
    if (regEn.test(menuName)) {
      setAddMenuError("不能有特殊字符: \\ / : * ? \" < > | [ \] -");
      return;
    }
    // 校验一级目录中是否有相同名称
    const oneMenuList = fileList.filter(item=>!item.title.trim().startsWith('[[')).map(i=>i.title.trim())
    if(oneMenuList.includes(`- ${menuName}`)){
      setAddMenuError('不能与已有文件标题相同');
      return;
    }

    // 重写fileList，再转换成md内容，最后保存sidebar
    const newSidebarList = fileList.concat({title: `- ${menuName}`, children: []})
    updateWikiFun(newSidebarList, 1);
  }

  // 更新wiki sidebar文件
  function updateWikiFun(sidebarList, type){
    updateWiki({
      owner,
      repo: projectsId,
      projectId: project.id,
      pageName: '_Sidebar',
      title: '_Sidebar',
      commit_message: '',
      content_base64: Base64.encode(treeToMd(sidebarList))
    }).then(res => {
      if (res && res.message === "200") {
        if(type === 1){
          setVisible(false);
          setMenuName(undefined);
          message.success('操作成功');
        }
        // setFileList(sidebarList);
        setReload(Math.random());
      }else {
        message.error(res.data || "操作失败");
      }
    });
  }

  function goEdit() {
    history.push(`/${owner}/${projectsId}/wiki/${encodeURI(checkItem.name)}/${checkItem.key}/edit`);
  }

  function preview() {
    window.open(`/${owner}/${projectsId}/wiki/preview/${encodeURI(project.name)}/${project.id}`);
  }

  // 支持 Markdown，Html，Pdf格式文件
  const menu = (
    <Menu >
      <Menu.Item key="1" onClick={() => { downloadWiki('markdown') }}>
        Markdown
      </Menu.Item>
      <Menu.Item key="2" onClick={() => { downloadWiki('html') }}>
        HTML
      </Menu.Item>
      <Menu.Item key="3" onClick={() => { downloadWiki('pdf') }}>
        PDF
      </Menu.Item>
    </Menu>
  );

  function downloadWiki(type) {
    window.open(`${httpUrl}/api/wikiExport/wikiExport-wrapper?repoName=${projectsId}&owner=${owner}&type=${type}&projectName=${project.name}&projectId=${project.id}`);
  }

  function changeitem(item){
    const {name, key} = item;
    const wiki = fileArrInit.filter(item => { return item.name == name })[0];
    setCheckItem({
      ...wiki,
      key
    })
    history.push(`/${owner}/${projectsId}/wiki/${name}/${key}`);
  }

  return (
    <Spin spinning={!fileArrInit} className="opacitySpin">
      {fileArrInit && fileArrInit.length ?
        <div className="wiki-main">
          <div className="wiki-head">

            <span className="head-title">
              {
                permission ?
                  <div>
                    <Button type="default" onClick={()=>{setVisible(true)}} className='mr15'><Icon type="plus"/>新增目录</Button>
                    <Button type="default" onClick={addFile}><Icon type="plus" />新增页面</Button>
                  </div> : "Wiki文档"
              }
            </span>
            <div>
              {
                permission && <UploadWiki {...props} fileList={fileList} setFileList={setFileList} fileArrInit={fileArrInit} setReload={setReload}/>
              }
              <Dropdown overlay={menu}>
                <Button type="default" className="ml10">导出<Icon type="caret-down" /></Button>
              </Dropdown>
              <Button type="default" className="ml10" onClick={preview}>预览</Button>

            </div>
          </div>

          <div className="wiki-body">
            <div className="wiki-nav-parent">
              <div className='wiki-nav-scroll'>
                <div className="wiki-nav">

                  {/* 读sidebar转换成目录树 */}
                  <Sidebar fileList = {fileList} changeitem={changeitem} projectsId={projectsId} owner={owner} project={project} setReload={setReload} sidebar={sidebar} history={history} permission={permission} defaultSelectedKeys={defaultSelectedKeys} fileArrInit={fileArrInit}/>
                </div>
              </div>


              {checkItem.wiki_clone_link && <InputGroup className="copy-url" compact>
                <Select dropdownClassName="wiki-url-type" defaultValue="HTTPS" onChange={(v) => { setUrlType(v) }}>
                  <Option value="HTTPS">HTTPS</Option>
                  <Option value="SSH">SSH</Option>
                </Select>
                <Input id="wikiUrl" value={urlType === 'HTTPS' ? checkItem.wiki_clone_link.https : checkItem.wiki_clone_link.ssh} />
                <CopyTool className="copy-wiki" inputId="wikiUrl" />
              </InputGroup>}

            </div>

            <div className="wiki-content">
              <div className="wiki-content-head">
                <div className="wiki-content-head-left">
                  <h3 className="wiki-detail-title">{checkItem.name}</h3>
                  <span className="user-box mr10" onClick={() => { checkItem.commit && goUser(checkItem.commit.author.name) }}>
                    {itemDetail.image_url && <img alt="头像" className="head-log-small" src={getImageUrl(`/${itemDetail.image_url}`)} />}
                    <span className='font-14'>{itemDetail.userName}</span>
                  </span>
                  <span className="time-ago font-14">上次修改于{checkItem.commit ? timeAgo(checkItem.commit.author.date) : '刚刚'}</span>
                </div>
                {permission && <Button type="primary" onClick={goEdit}>编辑</Button>}
              </div>

              {itemDetail&&itemDetail.md_content&&<RenderHtml className="wiki-content-detail editor-content-panel" value={ itemDetail && Base64.decode(itemDetail.md_content) } url={history.location}/>}
            </div>
          </div>
        </div >
        :
        <Welcome {...props} reloadList={setReload} fileList={fileList} setFileList={setFileList} fileArrInit={fileArrInit} setReload={setReload}/>
      }
      <Modal title="新增目录" visible={visible} onCancel={()=>{setVisible(false);setAddMenuError(undefined);setMenuName(undefined);}} onOk={addMenu} className="wikiAddMenu myself-modal" width={450} centered>
        <div className='mb10'>目录名称: </div>
        <Input placeholder='请输入目录名称' value={menuName} onChange={(e)=>{setMenuName(e.target.value);setAddMenuError(undefined)}} maxLength={50}></Input>
        <div className='wikiAddMenuError mt5'>{addMenuError}</div>
      </Modal>
    </Spin>
  )
}
