<template>
  <div class="goods-specifications">
    <div class="spe-con" v-for="(speItem,index) in speData" :key="index">
      <div class="el-form-item-h" >
        <label class="el-form-item-h__label">规格名称:</label>
        <div class="el-form-item-h__content">
          <div>
            <el-select
              :ref="'speNameDom' + index "
              v-model="speItem.spec_name"
              size="small"
              style="width: 300px"
              filterable
              default-first-option
              :clearable="true"
              @change="speNameChange(speItem.spec_name,index)"
              @visible-change='bv=> visibleChange(bv,"speNameDom",index)'
            >
              <el-option
                v-for="(itemSN,indexSN) in speOptions"
                :key="itemSN.id"
                :label="itemSN.name"
                :value="itemSN.name"
              >
                <span style="float: left" class="span-style">{{ itemSN.name }}</span>
                <div class="flag">
                  <svg-icon icon="edit" iconClass="template_edit_style" @click="addSpeName(index)"/>
                </div>
              </el-option>
            </el-select>
            <!--<span>数据填写不完整</span>-->
          </div>
          <div class="spe-params-con">
            <div style="display: inline-block" v-for="(itemSV,indexSV) in speItem.spec_value" :key="indexSV">
              <el-input v-model="itemSV.value" size="small" placeholder="请输入规格参数" class="spe-params-input-item" @blur="paramNameInputBlur(index,indexSV)">
                <i v-if="speItem.spec_value.length !== 1" slot="suffix" class="el-input__icon el-icon-delete el-icon-delete-h" @click="deleteSpeParam(index,indexSV)"></i>
              </el-input>
            </div>

            <el-button type="primary" plain class="el-icon-plus" size="mini" @click="addSpeParam(index)">添加规格参数</el-button>
          </div>
        </div>
      </div>
      <div style="margin-right:auto;" v-if="(speData.length > 1) && speData.length !== 1">
        <el-button type="danger" plain icon="el-icon-delete" size="mini" @click="deleteSpe(index)">删除该规格</el-button>
      </div>
    </div>

    <el-button @click="addSpe" class="el-icon-plus" size="mini">添加规格</el-button>

    <!-- 添加 规格名称 -->
    <el-dialog
      title="添加规格名称"
      :visible.sync="addSpecNameDialog"
      :destroy-on-close="true"
      :before-close="cancelSpec"
      width="500px"
      center
      append-to-body
    >
      <div>
        <p class="add-spec-dialog-con">
          <span style="margin-right:30px;">输入规格名称:</span>
          <span>
            <el-input v-model="specName_sm" placeholder="请输入规格名称" size="small" style="width: 280px;"></el-input>
          </span>
        </p>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelSpec" size="mini">取 消</el-button>
        <el-button type="primary" @click="saveSpecName" size="mini">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import descartes from "@/utils/dikaerjs.js";
import { UploadImg } from '@/api/module/goods'
export default {
  name: "GoodsSpecifications",
   props: {
    specificationsdata: {
      type: Array,
      required: true
    }
  },
  data() {
    return {
      speData: [],  // 商品规格总数据
      specsGroup: {
        spec_name: '', // 规格名称
        spec_value: []
      },

      speParamName:{
        value: ''
      },
      speOptions: [{
        id: '1',
        name: '颜色'
      }, {
        id: '2',
        name: '尺码'
      }],
      localSpeOptions: [],
      // 规格名称,value组成的数组
      speNameList: [],
      addSpecNameDialog: false,
      specName_sm: '',
    };
  },
  created() {

  },
  mounted() {
    /** 先获取 本地存储的localStorage **/
    this.getLocalSpecNameOption();
    // 先判断是新增还是修改
    //console.log(123,this.specificationsdata)
    if(this.specificationsdata.length === 0) {
      this.$set(this.specsGroup.spec_value,this.specsGroup.spec_value.length,this.speParamName);
      this.speData = [];
      this.$set(this.speData,this.speData.length,this.specsGroup);
    }else {
      this.speData = this.specificationsdata;
      this.$forceUpdate()
    }
  },
  watch:{
    // 'specificationsdata': {
    //   handler(newValue) {
    //     console.log(133,newValue);
    //   },
    //   deep: true
    // }
  },
  methods: {
    /** 初始化 商品规格数据 */
    initInfo() {
      // debugger
      this.$set(this.specsGroup.spec_value,this.specsGroup.spec_value.length,this.speParamName);
      this.speData = [];
      this.$set(this.speData,this.speData.length,this.specsGroup);
    },
    /** 添加规格*/
    addSpe() {
      let specsGroup = {
        spec_name: '', // 规格名称
        spec_value: [{value: ''}]
      };
      this.$set(this.speData,this.speData.length,specsGroup);
    },
    /** 删除 规格数据 */
    deleteSpe(index) {
      this.$confirm('是否删除当前规格的所有数据?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async() => {
        this.speData.splice(index,1);
        this.specCalcResult();
      }).catch(() => {})
    },
    //
    /** 规格名称,值改变时, 此组件 lable 和 value 绑定同一个值 */
    speNameChange(val,index) {
      if( val ) {
        // 当有多个值的时候,才校验,规格名称是否重复
        if( this.speData.length > 1 ) {
          let coypSpeData = [];
          coypSpeData = this.speData.concat();
          coypSpeData.splice(index,1);
          for(let i = 0; i < coypSpeData.length; i++) {
            if( val === coypSpeData[i].spec_name ) {
              this.speData[index].spec_name = '';
              this.$message({type: 'error',message: '此规格名称已经使用,请重新选取或新增其他规格名称'});
              break;
            }
          }
        }
      }
      // 重新 计算 规格组合数据
      this.specCalcResult();
    },

    // 添加规格参数
    addSpeParam(index) {
      let valueObj = { value: ''}
      this.$set(this.speData[index].spec_value,this.speData[index].spec_value.length,valueObj);
    },
    /** 删除 规格参数 */
    deleteSpeParam(index,indexSV) {
      // 先判断,删除前是否有值,如果是空,则没有必要再次计算
      if( this.speData[index].spec_value[indexSV].value ) {
        this.speData[index].spec_value.splice(indexSV,1);
        this.specCalcResult();
      }else {
        this.speData[index].spec_value.splice(indexSV,1);
      }
    },
    /**
     * 规格名称 下拉框 出现/隐藏 触发
     * 为element-ui的Select和Cascader添加弹层底部操作按钮
     * @param visible
     * @param refName  设定的ref名称
     * @param index  保证操作是当前的下拉框
     * @param addname  底部按钮名称, 可不用
     */
    visibleChange(visible, refName, index) {
      let _this = this;
      let realRefName = refName + index;
      //console.log(realRefName);
      if(visible) {
        // 动态绑定 ref的值的时候,下面的dom需要  加一个 [0],非常重要
        const speNameDom = _this.$refs[realRefName][0];
        let popper = speNameDom.$refs.popper;
        if( popper.$el ) {
          popper = popper.$el;
        }
        if(!Array.from(popper.children).some(v => v.className === 'el-template-menu__list')) {
          const el = document.createElement('ul');
          el.className = 'el-template-menu__list';
          el.style = 'border-top\:1px solid rgb(219 225 241)\; padding\:0\;margin\:0\; color\:rgb(64 158 255)\;font-size\: 14px';
          el.innerHTML = '<li class="el-cascader-node text-center" style="height:40px;line-height: 40px">'
                + '<span class="el-cascader-node__label"><i class="el-icon-plus"></i>添加规格名称</span>'
                + '</li>';
          popper.appendChild(el)
          el.onclick = () => {
            // 底部按钮的点击事件
            _this.addSpeName(index);

            // localSttorage 存储 下拉数据
            if(speNameDom.toggleDropDownVisible) {
              speNameDom.toggleDropDownVisible(false);
            } else {
              speNameDom.visible = false;
            }

          }
        }
      }
    },
    getLocalSpecNameOption() {
      //console.log("先获取:",window.localStorage.getItem('localSpeOptions'));
      if(!window.localStorage.getItem('localSpeOptions')) {
        this.speOptions = [];
      }else {
        let options = JSON.parse(window.localStorage.getItem('localSpeOptions'));
        this.speOptions = options;
      }
    },
    /* 增加 规格名称 */
    addSpeName(index) {
      this.addSpecNameDialog = true;
    },

    // 添加规格名称,对话框的退出
    cancelSpec() {
      this.specName_sm = '';
      this.addSpecNameDialog = false;
    },
    // 规格名称,保存
    saveSpecName() {
      let localObj = {
        id: 0,
        name: ''
      };
      let localArr = [];
      let localJSON = '';
      // 去 首尾空格
      this.specName_sm = this.specName_sm.trim();

      if( !this.specName_sm ) {
        this.$message({ type:'error',message: '规格名称不能为空' });
        return
      }

      if(this.speOptions.length === 0) {
        let localObj = {
          id: 0,
          name: this.specName_sm
        };
        localArr.push(localObj);
        localJSON = JSON.stringify(localArr);
      }else {
        let localObj = {
          id: this.speOptions.length,
          name: this.specName_sm
        };
        this.speOptions.push(localObj);
        localJSON = JSON.stringify(this.speOptions)
      }

      window.localStorage.setItem('localSpeOptions',localJSON)
      this.addSpecNameDialog = false;
      this.$message({type:'success',message:'新增成功'});
      this.getLocalSpecNameOption();

    },

    /** 规格参数 失焦时,进行笛卡尔积算法,并渲染 商品售价 */
    paramNameInputBlur(index,indexSV) {
      // // 如果失焦的input中有值,才再次计算
      // if( this.speData[index].spec_value[indexSV].value ) {
        this.specCalcResult();
      // }
    },

    /** 规格参数 变化时,对数据进行处理后,再进行笛卡尔积算法,最终计算出商品售价的数据 */
    specCalcResult() {
      // 商品规格原始数据
      let orgSpeData = this.deepClone(this.speData);

      // 进行数据处理后的数据,
      let proSpeData = this.processData(orgSpeData);
      // 需要将 所有规格名称,提出一个数组集合,
      this.speNameList = [];
      orgSpeData.forEach((item,index)=> {
        if( item.spec_name ) {
          let obj = { spec_name: '' };
          // 注意, item.spec_value是否一定为一个长度大于 1 的数组
          if( item.spec_value.length > 0) {
            for(let i = 0; i < item.spec_value.length; i++) {
              if( item.spec_value[i].value ) {
                obj.spec_name = item.spec_name;
                this.speNameList.push(obj);
                break;
              }
            }
          }
        }
      })

      // 当处理后的数据,是一个空数组,则不需要再进行 笛卡尔积 计算,可以直接给出计算结果
      if (proSpeData.length === 0) {
        let goodsPam = {
          pamNameList: [],
          pamDataList: [],
          pamTableList: [],
        };
        this.$emit('calcSpeTable', goodsPam);
      } else {
        let goodsParametersList = this.cartesian(proSpeData);
        let goodsPam = {
          pamNameList: [],
          pamDataList: [],
          pamTableList: [],
        };
        goodsPam.pamNameList = this.speNameList;
        goodsPam.pamDataList = goodsParametersList;

        goodsParametersList.forEach((item)=> {
          let prePamTable = [
            { js_price:'', sl_price:'', price:'', sc_price:'', stock:'', weight:'', thumb:'',spec_values: [] }
          ];
          goodsPam.pamTableList.push(prePamTable)
        });
        this.$emit('calcSpeTable',goodsPam);
      }
    },

    /** 数据处理为,二维数组,供笛卡尔积算法方法使用,对空数据进行过滤 */
    processData(list) {
      let result = [];
      if (list && list.length > 0) {
        for (let i = 0; i < list.length; i++) {
          let childList = [];

          if(list[i].spec_name) {
            for(let j = 0; j < list[i].spec_value.length; j++) {
              if(list[i].spec_value[j].value) {
                childList.push(list[i].spec_value[j].value);
              }
            }
          }

          if(childList.length > 0) {
            result.push(childList);
          }

        }
      }
      return result;
    },
    /** 在保存时,同步更新界面dom */
    upDateDom() {
      if(this.speData.length === 1) {
        if(this.speData[0].spec_name === '' ) {
          this.speData[0].spec_value = [{ value: ''}]
        }else {
          for(let i = 0; i < this.speData[0].spec_value.length; i++) {
            if(this.speData[0].spec_value[i].value === '') {
              this.speData[0].spec_value.splice(i,1)
              i = i - 1;
            }
          }
          if(this.speData[0].spec_value.length === 0) {
            this.speData[0].spec_value = [{ value: '' }];
          }
        }

      }else if( this.speData.length > 1 ) {

        for(let i=0; i<this.speData.length; i++){

          if( this.speData[i].spec_name === '' || this.speData[i].spec_value.length === 0) {
            this.speData.splice(i,1);
          } else if( this.speData[i].spec_name !== '' ) {

            // for( let j = 0; j < this.speData[i].spec_value.length; j++) {
            //
            // }

          }

        }
      }

      //console.log(404,this.speData);

    },
    /** 笛卡尔积算法 */
    cartesian(arr) {
      if(arr.length < 2) {
        return arr[0] || [];
      }else {
        return [].reduce.call(arr, function(col, set) {
          let res = [];
          col.forEach( c => {
            set.forEach(s => {
              let t = [].concat(Array.isArray(c) ? c : [c]);
              t.push(s);
              res.push(t);
            });
          });
          return res
        });
      }
    }

  }, // methods end
};
</script>
<style scoped>
  .goods-specifications {
    padding: 20px;
    /*margin-top: 18px;*/
  }
  .spe-con {
    display: flex;
    justify-content: flex-start;
  }

  /* 仿 element 的from-item 样式,注意,size为  samll */
  .el-form-item-h {
    width:80%;
    margin: 0 20px 20px 0;
    padding: 20px 0 0;
    background: #F7F8FA;
    border: 1px solid #E5E5E5;
    border-radius: 2px;
  }
  .el-form-item-h__label {
    width: 150px;
    text-align: right;
    vertical-align: middle;
    float: left;
    font-size:14px;
    color: #606266;
    line-height: 32px;
    padding: 0 12px 0 0;
    box-sizing: border-box;
  }
  /*.el-form-item-h__label:before {*/
  /*  content: '';*/
  /*  color: #ff4949;*/
  /*  margin-right: 4px;*/
  /*}*/
  .el-form-item-h__content {
    margin-left: 150px;
    position: relative;
    font-size: 14px;
  }
  .spe-params-con {
    margin: 20px 0;
  }

  /* 商品规格 - 规格名称 - 参数input */
  .spe-params-input-item {
    width: 150px;
    margin: 0 10px 20px 0;
  }
  .el-icon-delete-h:hover {
    font-size: 14px;
    color: #ff4949;
    cursor: pointer;
  }

  .add-spec-dialog-con {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
  }
</style>