/**
 @ Name：表格冗余列可展开显示
 @ Author：hbm
 @ License：MIT
 */

layui.define(['form', 'table'], function (exports) {
  var $ = layui.$
      , table = layui.table
      , form = layui.form
      , VERSION = 1.0, MOD_NAME = 'opTable'
      // 展开 , 关闭
      , ON = 'on', OFF = 'off', KEY_STATUS = "status"
      //openType 0、默认效果同时只展开一项  1、点击展开多项 2、 展开全部  3、关闭全部
      , OPEN_DEF = 0, OPEN_NO_CLOSE = 1, OPEN_ALL = 2, CLOSE_ALL = 3
      //外部接口
      , opTable = {
        index: layui.opTable ? (layui.opTable.index + 10000) : 0

        //设置全局项
        , set: function (options) {
          var that = this;
          that.config = $.extend({}, that.config, options);
          return that;
        }

        //事件监听
        , on: function (events, callback) {
          return layui.onevent.call(this, MOD_NAME, events, callback);
        }
      }
      // 展开列需要需要显示的数据 数据格式为 每个页面唯一的（LAY_IINDEX）下标绑定数据  对应的数据
      , openItemData = {}
      , getOpenClickClass = function (elem, isAddClickClass) {
        return elem.replace("#", '').replace(".", '') + (isAddClickClass ? 'opTable-i-table-open' : '')
      }
      , getOpenAllClickClass = function (elem) {
        return getOpenClickClass(elem, true) + "-all"
      }
      //操作当前实例
      , thisIns = function () {
        var that = this
            , options = that.config
            , id = options.id || options.index;

        return {
          reload: function (options) {
            that.config = $.extend(that.config, options);
            that.config.cols[0].splice(0, 1);
            that.render();
            return this;
          }
          , config: options

          // 展开全部
          , openAll: function () {
            // 表格 同时只支持展开一项
            if (that.config.openTable || this.isOpenAll()) {
              return;
            }
            var def = that.config.openType;
            that.config.openType = OPEN_ALL;
            $("." + getOpenClickClass(that.config.elem, true)).parent().click();
            that.config.openType = def;

            $("." + getOpenAllClickClass(that.config.elem))
                .addClass("opTable-open-dow")
                .removeClass("opTable-open-up")
                .attr(KEY_STATUS, ON);
          }
          // 关闭全部
          , closeAll: function () {
            if (!this.isOpenAll()) {
              return;
            }

            var def = that.config.openType;
            that.config.openType = CLOSE_ALL;
            $("." + getOpenClickClass(that.config.elem, true)).parent().click();
            that.config.openType = def;

            $("." + getOpenAllClickClass(that.config.elem))
                .addClass("opTable-open-up")
                .removeClass("opTable-open-dow")
                .attr(KEY_STATUS, ON);
          }

          // 通过下标展开一项
          , openIndex: function (index) {
            var dom = $("." + getOpenClickClass(that.config.elem, true)).eq(index);
            if (dom.length <= 0) {
              return false;
            }
            var status = dom.attr(KEY_STATUS);
            if (status === ON) {
              return true;
            }
            dom.click();
            return true;
          }
          // 通过下标展开一项
          , closeIndex: function (index) {
            var dom = $("." + getOpenClickClass(that.config.elem, true)).eq(index);
            if (dom.length <= 0) {
              return false;
            }
            var status = dom.attr(KEY_STATUS);
            if (status === OFF) {
              return true;
            }
            dom.click();
            return true;
          }
          // 当前展开状态取反
          , toggleOpenIndex: function (index) {
            var dom = $("." + getOpenClickClass(that.config.elem, true)).eq(index);
            if (dom.length <= 0) {
              return false;
            }
            dom.parent().click();
            return true;
          }
          // 当前是否全部展开
          , isOpenAll: function () {
            var localTag = $("." + getOpenClickClass(that.config.elem, true));
            var allTag = localTag.length;
            var openTag = localTag.parent().parent().parent().parent().find(".opTable-open-dow").length;
            // 当所有的选项都被展开 则 true
            return allTag === openTag;
          }
        }
      }

      //构造器
      , Class = function (options) {
        var that = this;
        that.index = ++opTable.index;
        that.config = $.extend({}, that.config, opTable.config, options);
        that.render();
        return this;
      };

  //默认配置
  Class.prototype.config = {
    openType: OPEN_DEF
    // 展开的item (垂直v|水平h) 排序
    , opOrientation: 'v'
    // layui table 对象
    , table: null
  };

  //渲染视图
  Class.prototype.render = function () {
    var that = this
        , options = that.config
        , colArr = options.cols[0]
        , openCols = options.openCols || []
        , openNetwork = options.openNetwork || null
        , openTable = options.openTable || null
        , done = options.done;


    // 展开显示表格 同时只支持展开一个
    options.openType = openTable ? OPEN_DEF : options.openType;

    delete options["done"];
    //  1、在第一列 插入可展开操作
    colArr.splice(0, 0, {
      align: 'left',
      width: 50,
      title: openTable ? ''
          : '<i class="opTable-i-table-open ' + getOpenAllClickClass(options.elem) + ' " ' + KEY_STATUS + '="off"  title="(展开|关闭)全部"></i>',
      templet: function (item) {
        // 解决页面多个表格问题
        var cla = getOpenClickClass(options.elem, false);

        openItemData[cla] = openItemData[cla] || {};
        openItemData[cla][item.LAY_INDEX] = item;
        return "<i class='opTable-i-table-open " + cla + "opTable-i-table-open' " + KEY_STATUS + "='off'  data='"
            //  把当前列的数据绑定到控件
            + item.LAY_INDEX
            + " ' elem='"
            + cla
            + "' title='展开'></i>";
      }
    });


    //  2、表格Render
    options.table = table.render(
        $.extend({
          done: function (res, curr, count) {
            initExpandedListener();
            if (done) {
              done(res, curr, count)
            }
          }
        }, options));


    // 3、展开事件
    function initExpandedListener() {
      $("." + getOpenClickClass(options.elem, true))
          .parent()
          .unbind("click")
          .click(function () {
            var that = $(this).children()
                , _this = this
                , itemIndex = parseInt(that.attr("data"))
                , bindOpenData = openItemData[that.attr("elem")][itemIndex]
                , status = that.attr(KEY_STATUS) === 'on'
                // 操作倒三角
                , dowDom = that.parent().parent().parent().parent().find(".opTable-open-dow")
                // 展开的tr
                , addTD = that.parent().parent().parent().parent().find(".opTable-open-td");

            // 关闭全部
            if (options.openType === CLOSE_ALL) {
              dowDom
                  .addClass("opTable-open-up")
                  .removeClass("opTable-open-dow")
                  .attr(KEY_STATUS, OFF);
              addTD.slideUp(100, function () {
                addTD.remove();
              });
              return;
            }

            // 展开全部
            if (options.openType === OPEN_ALL) {
              dowDom
                  .addClass("opTable-open-dow")
                  .removeClass("opTable-open-up")
                  .attr(KEY_STATUS, ON);
              if (status) {
                _this.addTR.remove();
              }
            }

            if (options.openType === OPEN_DEF) {
              // 关闭类型
              var sta = dowDom.attr(KEY_STATUS),
                  isThis = (that.attr("data") === dowDom.attr("data"));
              //1、关闭展开的
              dowDom
                  .addClass("opTable-open-up")
                  .removeClass("opTable-open-dow")
                  .attr(KEY_STATUS, OFF);

              //2、如果当前 = 展开 && 不等于当前的 关闭
              if (sta === ON && isThis) {
                addTD.slideUp(100, function () {
                  addTD.remove();
                });
                return;
              } else {
                that.attr(KEY_STATUS, OFF);
                addTD.remove();
              }
            } else if (options.openType === OPEN_NO_CLOSE) {
              //  1、如果当前为打开，再次点击则关闭
              if (status) {
                that.removeClass("opTable-open-dow");
                that.attr(KEY_STATUS, 'off');
                this.addTR.find("div").slideUp(100, function () {
                  _this.addTR.remove();
                });
                return;
              }
            }

            // 把添加的 tr 绑定到当前 移除时使用
            this.addTR = $([
              "<tr><td class='opTable-open-td'  colspan='" + (colArr.length + 1) + "'>"
              , "<div style='margin-left: 50px;display: none'></div>"
              , "</td></tr>"].join("")
            );

            // 所有内容的主容器
            var divContent =
                _this.addTR
                    .children()
                    .children();

            that.parent().parent().parent().after(this.addTR);

            var html = [];

            // 1、从网络获取
            if (openNetwork) {
              loadNetwork();
            } else if (openTable) {
              var id = openTable.elem.replace("#", '').replace(".", '');
              //2、展开显示表格

              divContent
                  .empty()
                  .append("<table id='" + id + "' lay-filter='" + id + "'></table>")
                  .css({
                    "padding": "0 10px 0 50px", "margin-left": "0", "width":
                        _this.addTR.width()
                  })
                  .fadeIn(200);

              // 设置展开表格颜色为浅色背景
              addTD.css("cssText", "background-color:#FCFCFC!important");

              layui.table.render(openTable);
            } else {
              //  3、从左到右依次排列 Item 默认风格
              openCols.forEach(function (val, index) {
                appendItem(val, bindOpenData);
              });
              divContent.append(html.join(''));
              this.addTR.find("div").slideDown(200);
              bindBlur(bindOpenData);
            }

            function loadNetwork() {
              divContent.empty()
                  .append('<div class="opTable-network-message" ><i class="layui-icon layui-icon-loading layui-icon layui-anim layui-anim-rotate layui-anim-loop" data-anim="layui-anim-rotate layui-anim-loop"></i></div>');
              _this.addTR.find("div").slideDown(200);


              openNetwork.onNetwork(bindOpenData
                  //加载成功
                  , function (obj) {
                    //  2、从左到右依次排列 Item
                    openNetwork.openCols.forEach(function (val, index) {
                      appendItem(val, obj);
                    });
                    // 填充展开数据
                    divContent.empty().append(html.join(''));
                    bindBlur(obj);
                  }
                  , function (msg) {
                    divContent.empty()
                        .append("<div class='opTable-reload opTable-network-message' style='text-align: center;margin-top: 20px'>" + (msg || "没有数据") + "</div>")

                    $(".opTable-reload")
                        .unbind()
                        .click(function (e) {
                          loadNetwork();
                        });
                  })
            }

            /**
             * 添加默认排版风格 item
             * @param colsItem  cols配置信息
             * @param openData  展开数据
             */
            function appendItem(colsItem, openData) {
              //  1、自定义模板
              if (colsItem.templet) {

                html.push("<div class='opTable-open-item-div' opOrientation='" + options.opOrientation + "'>")
                html.push(colsItem.templet(openData));
                html.push("</div>")
                //  2、可下拉选择类型
              } else if (colsItem.type && colsItem.type === 'select') {
                var child = ["<div id='" + colsItem.field + "' class='opTable-open-item-div' opOrientation='" + options.opOrientation + "' >"];
                child.push("<span style='color: #99a9bf'>" + colsItem["title"] + "：</span>");
                child.push("<div class='layui-input-inline'><select  lay-filter='" + colsItem.field + "'>");
                colsItem.items.forEach(function (it) {
                  it = colsItem.onDraw(it, openData);
                  child.push("<option value='" + it.id + "' ");
                  child.push(it.isSelect ? " selected='selected' " : "");
                  child.push(" >" + it.value + "</option>");
                });
                child.push("</select></div>");
                child.push("</div>");
                html.push(child.join(""));
                setTimeout(function () {
                  layui.form.render();
                  //  监听 select 修改
                  layui.form.on('select(' + colsItem.field + ')', function (data) {

                    if (options.edit && colsItem.isEdit(data, openData)) {
                      var json = {};
                      json.value = data.value;
                      json.field = colsItem.field;
                      openData[colsItem.field] = data.value;
                      json.data = JSON.parse(JSON.stringify(openData));
                      options.edit(json);
                    }
                  });
                }, 20);
              } else {
                var text = colsItem.onDraw ? colsItem.onDraw(openData) : openData[colsItem["field"]];
                // 3、默认类型
                html.push("<div class='opTable-open-item-div' opOrientation='" + options.opOrientation + "'>");
                html.push("<span class='opTable-item-title'>" + colsItem["title"] + "：</span>");
                html.push((colsItem.edit ?
                        ("<input  class='opTable-exp-value opTable-exp-value-edit' autocomplete='off' name='" + colsItem["field"] + "' value='" + text + "'/>")
                        : ("<span class='opTable-exp-value' >" + text + "</span>")
                ));
                html.push("</div>");
              }

            }

            /**
             * 绑定监听 修改失焦点监听
             * @param bindOpenData
             */
            function bindBlur(bindOpenData) {
              $(".opTable-exp-value-edit")
                  .unbind("blur")
                  .blur(function () {
                    var that = $(this), name = that.attr("name"), val = that.val();
                    // 设置了回调 &&发生了修改
                    if (options.edit && bindOpenData[name] + "" !== val) {
                      var json = {};
                      json.value = that.val();
                      json.field = that.attr("name");
                      bindOpenData[name] = val;
                      json.data = bindOpenData;
                      options.edit(json);
                    }
                  })
                  .keypress(function (even) {
                    even.which === 13 && $(this).blur()
                  })
            }

            that.addClass("opTable-open-dow");
            that.attr(KEY_STATUS, 'on');
          });

      // (展开|关闭)全部
      $("." + getOpenAllClickClass(options.elem))
          .parent()
          .parent()
          .unbind("click")
          .click(function () {
            var tag = $(this).find("i"), status = tag.attr(KEY_STATUS);
            if (status === ON) {
              tag
                  .addClass("opTable-open-up")
                  .removeClass("opTable-open-dow")
                  .attr(KEY_STATUS, OFF);
              options.thisIns.closeAll();
            } else {
              tag
                  .addClass("opTable-open-dow")
                  .removeClass("opTable-open-up")
                  .attr(KEY_STATUS, ON);
              options.thisIns.openAll();
            }

          })
    }

    //  4、监听排序事件
    var elem = $(options.elem).attr("lay-filter");

    //  5、监听表格排序
    table.on('sort(' + elem + ')', function (obj) {
      if (options.sort) {
        options.sort(obj)
      }
      // 重新绑定事件
      initExpandedListener();
    });

    //  6、单元格编辑
    layui.table.on('edit(' + elem + ')', function (obj) {
      if (options.edit) {
        options.edit(obj)
      }
    });

  };

  //核心入口
  opTable.render = function (options) {
    var ins = new Class(options);
    var ex = thisIns.call(ins);
    ins.config.thisIns = ex;
    return ex;
  };

  //加载组件所需样式
  layui.link(layui.cache.base + '/opTable.css?v=1' + VERSION, function () {
    //此处的“opTable”要对应 opTable.css 中的样式： html #layuicss-opTable{}
  }, 'opTable');

  exports('opTable', opTable);

});
