import React,{Component} from 'react';
import classNames from 'classnames';
import config from '@config/index.js';
import style from './index.less';
import {deepClone,filterArr,handleEnter,isIE,getPageCoordinate,windowEventHandler,filterDataArr} from '@utils/tools.js';
import {Notify} from '@commonComp';
import ReactDom from "react-dom";
import {getIds} from '@common/js/func.js';
import $ from 'jquery';
/****
 * 标签组合下拉,选中的项目展开
 * author:zn@2018-11-21
 * 接收参数：
 * keepSelf:展开标签后是否保留原标签
 * data:下拉内容
 * placeholder:灰显文字
 *
 * ***/


class SpreadDrop extends Component{
  constructor(props){
    super(props);
    const {nones,noneOn,noneIds,withOn,exists,nowOn,withs,exclusion,excluName} = deepClone(props.selecteds||[]);
    this.state = {
      nones:nones||'',       //无,字符串拼接
      exists:exists||[],      //主症状id
      excluName:excluName||'',
      withs:withs||[],       //伴随 id
      noneIds:noneIds||[],
      noneOn:noneOn||false,       //无是否选中
      withOn:withOn||false,       //伴是否选中
      nowOn:nowOn||'',           //最近选中“无”还是“伴”
      exclusion:exclusion||'',      //选中互斥项id
      timer:null,  //延时，区分单击双击
      ban:{},  //放'伴'字段
      editable:false,      //双击编辑
      labelVal:'',  //存放标签原有的值--主诉字数限制用
      boxLeft:0,
      boxTop:0,
      tmpScroll:0,
      tmpTop:0,
    };
    this.$div = React.createRef();
    this.handleSelect = this.handleSelect.bind(this);
    this.clearState = this.clearState.bind(this);
    this.handleClear = this.handleClear.bind(this);
    this.handleShow = this.handleShow.bind(this);
    this.handleConfirm = this.handleConfirm.bind(this);
    this.changeToEdit = this.changeToEdit.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.onChange = this.onChange.bind(this);
    /*是否点击确定按钮标记，处理点击其他等同于确定操作bug,
      如不区分确定按钮提交和点击其他提交，确定按钮提交后会多更新一次状态导致数据重复*/
    this.btnClickFlag = false;
  }
  handleShow(e){//单击
    e&&e.stopPropagation();
    // let boxLeft = e.pageX -175 + 'px';
    // let offsetTop = e.target.offsetTop;
    // const ht = e.target.offsetHeight;   //如杂音选中文字有多行时，写死会遮挡
    // let boxTop = offsetTop + ht +2 + 'px';
    // this.setState({
    //   boxLeft:boxLeft,
    //   boxTop:boxTop
    // })
    this.setState({
      boxLeft:getPageCoordinate(e).boxLeft,
      boxTop:getPageCoordinate(e).boxTop,
      tmpScroll: $("#addScrollEvent")[0].scrollTop,
      tmpTop:getPageCoordinate(e).boxTop
    });
    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
      let scrollYs = $("#addScrollEvent")[0].scrollTop;
      this.setState({
        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
      })
    },$("#addScrollEvent")[0])
    // window.event? window.event.cancelBubble = true : e.stopPropagation();
     this.setStateInit();      //恢复初始选中状态
    const {ikey,handleShow,placeholder,flag,id,value,tagType,type} = this.props;
    const that = this;
    this.btnClickFlag = false;
    clearTimeout(this.state.timer);
    this.state.timer = setTimeout(function(){
      if (that.state.editable) {//如果处于编辑状态点击不显示下拉框
        return
      }else{
        handleShow&&handleShow({ikey,placeholder,flag,id,value,tagType,type});
      }
    },300)

  }

  changeToEdit(e){//双击
    const {value,id,placeholder,handleDbclick,handleHide} = this.props;
    let text = e.target.innerText || e.target.innerHTML;
    handleHide&&handleHide();       //展开情况下双击收起
    // clearTimeout(this.state.timer);//取消延时的单击事件
    e.stopPropagation();
    // e.preventDefault();
    if(value&&value.trim()){//有选中值的标签才能双击编辑
      this.setState({
        labelVal:text,
        editable:true
      });
      //失焦关闭编辑状态
      setTimeout(()=>{
        e.target.focus();
      })
      handleDbclick && handleDbclick({value,id,placeholder});
    }
  }

  onChange(e){
    const {mainSaveText,ikey,type,handleLabelChange} = this.props;
    const {labelVal,editable} = this.state;
    let mainText = filterDataArr(mainSaveText);//主诉字数
    if(editable){//避免IE中点击标签也会触发
      let val = e.target.innerText || e.target.innerHTML;
      if(+type==1){// 主诉字数达到上限时不允许输入
        if(mainText.length >= config.limited){
          if(val.length > labelVal.length){
            e.target.innerText?(e.target.innerText = labelVal):(e.target.innerHTML = labelVal);
            Notify.info(config.limitText);
            return
          }else if(val.length == labelVal.length){
            this.setState({
              labelVal:val
            });
          }else{
            handleLabelChange && handleLabelChange({ikey,changeVal:val,type});
          }
        }
      }
    }
  }

  handleBlur(e){
    e.stopPropagation();
    const {ikey,type,handleLabelChange} = this.props;
    const {editable} = this.state;
    const ev = e || window.event;
    if(editable){
      // 更改标签的value值
      let changeVal = ev.target.innerText || ev.target.innerHTML;
      if(!isIE()){
        e.target.innerText?(e.target.innerText = ''):(e.target.innerHTML = '');      //避免出现重复输入值
      }
      handleLabelChange && handleLabelChange({ikey,changeVal,type});
    }
    this.setState({
      editable:false
    });


  }
  setStateInit(){
    const {nones,noneOn,noneIds,withOn,exists,nowOn,withs,exclusion,excluName,ban} = deepClone(this.props.selecteds||[]);
    this.setState({
      nones:nones||'',
      exists:exists||[],
      excluName:excluName||'',
      withs:withs||[],
      noneIds:noneIds||[],
      noneOn:noneOn||false,
      withOn:withOn||false,
      nowOn:nowOn||'',
      exclusion:exclusion||'',
      ban:ban||{},
    });
  }
  clearState(){
    this.setState({
      nones:'',
      exists:[],
      //existsName:{},
      //withsName:{},
      withs:[],
      noneIds:[],
      noneOn:false,
      withOn:false,
      nowOn:'',
      exclusion:'',
      excluName:'',
      ban:{}
    });
    this.btnClickFlag = false;
  }
  handleClear(e){
    e.stopPropagation();
    this.clearState();
  }
  handleConfirm(e){
    e.stopPropagation();
    const {handleConfirm,ikey,type,tagType,order,mainSaveText,copyType,value,mainData} = this.props;
    const params = Object.assign({},this.state,{ikey,type,tagType,order,mainSaveText,copyType,value,mainData});
    handleConfirm&&handleConfirm(params);
	this.btnClickFlag = true;
    //点确定后隐藏弹窗
    this.props.handleHide();
  }
  handleSelect(item,isExclu,joint,listIndex,selected){//console.log(item,selected)
    let {withOn,withs,noneOn,exclusion,exists,nowOn,nones,noneIds,ban} = this.state;
    /*if(this.props.selecteds)
    console.log(exists,this.props.selecteds.exists,exists===this.props.selecteds.exists)*/
    const id = item.id;
    const linkStr = joint||'';
    const name = item.name+linkStr;
    if(isExclu){      //操作“互斥项”
      if([...noneIds,...exists,...withs].length>0){     //已选非互斥项，互斥项不可操作
        return;
      }
      let temp = '';
      if(exclusion==''){
        temp = id;
      }else if(exclusion!=''&&exclusion!==id){
        temp = exclusion;
      }
      this.setState({
        exclusion:temp,
        excluName:temp ===''?'':name
      });
      return;
    }
    //操作单选项
    if(selected){
      const tIndex= exists.findIndex((it)=>it.questionId===item.questionId);
      const bIndex= withs.findIndex((it)=>it.questionId===item.questionId);
      if(tIndex!=-1){
        exists.splice(tIndex,1,Object.assign({},item,{name}));    //修改单选列连接字符不显示bug
        this.setState({
          exists,
        })
      }
      if(bIndex!=-1){
        withs.splice(tIndex,1,item);
        this.setState({
          withs,
        })
      }
      return;
    }
    if(exclusion!==''){     //互斥项被选中，其他不可操作
      return;
    }
    if(+item.code===1){     //操作“伴”类型
      this.setState({
        withOn:!withOn,
        // withs:withOn?[]:[...withs,id],     //取消“伴”选中，伴随症状全部取消选中    
        // withs:withOn?[]:[...withs,{id:item.id,name:name}],
        withs:withOn?[]:withs,
        ban:withOn?{}:{id:id,name:name,value:name},
        //withsName:withOn?"":withsName+name,     //取消“伴”选中，伴随症状全部取消选中
        nowOn:withOn?(noneOn?'none':''):'with'
      });
      return;
    }
    if(+item.code===2){     //操作“无”类型
      this.setState({
        noneOn:!noneOn,
        noneIds:noneOn?[]:[...noneIds,id],
        nones:noneOn?'':name,
        nowOn:noneOn?(withOn?'with':''):'none'
      });
      return;
    }
    //操作普通项
    let existsIds = exists.length>0? getIds(exists):[];
    let withsIds = withs.length>0? getIds(withs):[];


    if(existsIds.includes(id)){
      let existsData = exists;
      exists.forEach((it,i)=>{
        if(it.id==id){
         existsData.splice(i,1); 
        }
      })
      exists = existsData;
    }else if(noneIds.includes(id)){
      nones = nones.replace(name+'、','');
      noneIds.splice(noneIds.indexOf(id),1);
    }else if(withsIds.includes(id)){
      let withsData = withs;
      withs.forEach((it,i)=>{
        if(it.id==id){
         withsData.splice(i,1); 
        }
      })
      withs = withsData;
    }else{        //选中普通项
      if(nowOn=='none'){
        nones += name+'、';
        noneIds.push(id);
      }else if(nowOn=='with'){
        withs.push({id:id,name:name,questionId:item.questionId});
      }else{
        exists.push({id:id,name:name,listIndex,questionId:item.questionId});
      }
    }
    this.setState({
      nones,
      noneIds,
      exists,
      withs,
      ban
      //existsName,
      //withsName,
    });
  }
  getClass(){
    const {isImports,show,value} = this.props;
    const blueBorder = this.state.editable?style['blue-border']:'';
    const orgBorder = isImports&&!value?style['orange-border']:'';
    if(show){
      $(this.$div.current).addClass(style['borderd']);
    }else{
      $(this.$div.current).removeClass(style['borderd']);
    }
    if(value){
      return classNames(style['selected-tag'],blueBorder);
    }
    return classNames(style['tag'],orgBorder);
  }

  componentDidMount(){
    if(isIE()){
      $(this.$div.current).onIe8Input(function(e){
        this.onChange(e)
      },this);
    }
  }

  render(){
    const {placeholder,value,show,data} = this.props;
    const {editable,boxLeft,boxTop} = this.state;
    return  <div className={style['container']}
              onFocus={(e)=>e.stopPropagation()}
              onBlur={(e)=>e.stopPropagation()}
              onInput={(e)=>e.stopPropagation()}>
        <div
        ref={this.$div}
        onClick={this.handleShow}
        className={this.getClass()}
        contentEditable={editable}
        onDoubleClick={this.changeToEdit}
        onBlur={this.handleBlur}
        onInput={this.onChange}
        onkeydown={handleEnter}
        >{value||placeholder}</div>
          <ListItems data={data} left={boxLeft}
            top={boxTop} show={show} handleSelect={this.handleSelect} handleConfirm={this.handleConfirm} handleClear={this.handleClear} {...this.state}></ListItems>
      </div>
  }
}

class ListItems extends Component{
  constructor(props){
    super(props);
  }
  getLabels(){
    const {data,handleSelect} = this.props;
    let detail = [];
    let isSpecialPos = false;       //是否特殊位置（单行在上面，如无殊）
    let isExclu = false;      //是否与其他互斥
    let isRadio;      //是否为单选列，默认多选列
    const list = data&&data.map((it,i)=>{
      isSpecialPos = (+it.formPosition === 1);
      isExclu = (+it.exclusionType===1);
      isRadio = (+it.tagType ===1&&+it.controlType === 1);
      if(+it.controlType===0){
        detail = it.questionMapping;
      }else{
        detail = it.questionDetailList;
      }
      return <ListItem datas={detail}
                       isRadio={isRadio}
                       joint={it.joint}
                       listIndex={i}
                       isSpecialPos={isSpecialPos}
                       isExclu={isExclu}
                       handleClick={handleSelect}
                       {...this.props}></ListItem>;
    });
    return list;
  }
  getStyle(){
    const {left,top,show} = this.props;
    return {
      left:left?left+'px':'',
      top:top?top+'px':'',
      display:show?'block':'none'
    }
  }
  render (){
    const {handleClear,handleConfirm} = this.props;
    const domNode = document.getElementById('root');
    return ReactDom.createPortal(
      <div className={style["drop-list"]} style={this.getStyle()} contentEditable="false" onClick={(e)=>{e.stopPropagation();}}>
        {this.getLabels()}
        <div className="oper">
          <span className={style['clear']} onClick={handleClear}>清空选项</span>
          <span className={style['confirm']} onClick={handleConfirm}>确定</span>
        </div>
      </div>
    ,domNode)
  }
}

class ListItem extends Component{
  constructor(props){
    super(props);
  }
  handleClick(e,item,i){
    e.stopPropagation();
    // window.event? window.event.cancelBubble = true : e.stopPropagation();
    const {handleClick,isExclu,isRadio,data,exists,noneIds,withs,joint,listIndex} = this.props;
    const index=listIndex+''+i;
    //列单选处理
    if(isRadio){
      let selected = exists.find((i)=>{
        return i.questionId===item.questionId;
      })||withs.find((i)=>{
        return i.questionId===item.questionId;
      })||noneIds.find((i)=>{
        return i.id===item.questionId;
      });
      /*const selected = data.find((it)=>{console.log(exists)
        return exists.findIndex((i)=>i.questionId===it.id)!==-1||noneIds.includes(it.id)||withs.findIndex((i)=>i.questionId===it.id)!==-1;
      });*/
      if(selected&&selected.id!=item.id){     //该列已有选中项，传回已选中的id,name取消选中
        handleClick&&handleClick(item,isExclu,joint,index,{id:selected.id,name:selected.name,questionId:selected.questionId});
      }else{
        handleClick&&handleClick(item,isExclu,joint,index);
      }
      return;
    }
    handleClick&&handleClick(item,isExclu,joint,index);
  }
  getClass(id){     //无之后显示黑色，之前显示蓝色
    const {exclusion,nones,noneIds,exists,withs,isExclu,ban} = this.props;
    if(exclusion!=''){
      if(+id===+exclusion){
        return style['selected'];
      }else{
        return style['exclusion'];
      }
    }else{
      if(isExclu&&([...noneIds,...exists,...withs].length>0||ban.id)){
        return style['exclusion'];
      }
      if(noneIds.includes(id)){
        return style['none-selected'];
      }
      let existsIds = getIds(exists);
      let withsIds = getIds(withs);
      // if(existsIds.includes(id)||withsIds.includes(id)){
      if(existsIds.includes(id)||withsIds.includes(id)||ban.id && ban.id==id){
        return style['selected'];
      }

      return '';
    }
  }
  render(){
    const {datas,isSpecialPos} = this.props;
    const pos = isSpecialPos?style['independent']:'';
    return <ul className={classNames(style['row'],pos)} onBlur={(e)=>e.stopPropagation()}>
      {datas&&datas.map((it,i)=>{
        /*return <li onClick={(e)=>this.handleClick(e,it,i)}
                   className={this.getClass(it.id)}>{it.labelPrefix}{it.name}{it.labelSuffix}</li>*/
          return <li onClick={(e)=>this.handleClick(e,it,i)} className={this.getClass(it.id)} title={it.name.length>8?it.name:''}>{it.name&&it.name.length>8?it.name.slice(0,8)+'...':it.name}</li>
      })}
    </ul>;
  }
}
export default SpreadDrop;