<template>
  <tbody class="es-data-form-body">
    <tr v-for="(items, indexs) in data" :key="indexs">
      <td class="numbers" v-if="numbers">{{ indexs + 1 }}</td>
      <td v-for="(item, index) in cols" :align="item.align">
        <template
          v-if="
            readonly ||
            items.canEdit === false ||
            (items.cantEditKey &&
              items.cantEditKey.indexOf(item.field || item.prop) > -1)
          "
        >
          <expand-dom
            v-if="item.render"
            :key="index"
            :item="item"
            :row="items"
            :render="item.render"
          ></expand-dom>
          <div
            class="cell"
            :class="{ 'is-textarea': item.type === 'textarea' }"
            :key="index"
            v-else
          >
            {{ getLabels(items, item) }}
          </div>
        </template>
        <template v-else>
          <eo-radio
            v-if="item.type === 'radio'"
            v-bind="item"
            v-model="items[item.field || item.prop]"
            :index="indexs"
            :options="options[item.field || item.prop]"
          ></eo-radio>
          <eo-checkbox
            v-if="item.type === 'checkbox'"
            v-bind="item"
            v-model="items[item.field || item.prop]"
            :index="indexs"
            :options="options[item.field || item.prop]"
          ></eo-checkbox>
          <textarea
            v-else-if="item.type === 'textarea'"
            class="el-textarea__inner"
            v-model.lazy="items[item.field]"
            @blur="
              (event) => {
                handleBlur({ item: item, event: event, data: items });
              }
            "
            @focus="
              (event) => {
                handleFocus({
                  item: item,
                  event: event,
                  data: items
                });
              }
            "
            @change="
              (value) => {
                handleChange({
                  name: item.field || item.prop,
                  value: value,
                  data: items
                });
              }
            "
          ></textarea>
          <div v-else class="es-input-box">
            <div
              v-if="item.type === 'select' || item.type === 'selector'"
              class="el-input__inner es-select"
              :class="{
                'es-select-multiple':
                  item.type === 'select'
                    ? item.multiple
                    : item.multiple !== false
              }"
              @click="
                (event) => {
                  handeClick({ item: item, event: event, data: items });
                }
              "
            >
              <template
                v-if="
                  item.type === 'select'
                    ? item.multiple
                    : item.multiple !== false
                "
              >
                <template v-if="item.collapseTags">
                  <span class="el-tag el-tag--info el-tag--small el-tag--light">
                    <span class="el-select__tags-text">{{
                      showLabel(getLabels(items, item, true)[0], item.labelKey)
                    }}</span>
                    <i
                      class="el-tag__close el-icon-close"
                      @click.stop="
                        handleDelete(
                          items,
                          item,
                          0,
                          getLabels(items, item, true)[0]
                        )
                      "
                    ></i
                  ></span>
                  <span
                    class="el-tag el-tag--info el-tag--small el-tag--light"
                    v-if="getLabels(items, item, true).length > 1"
                  >
                    <span class="el-select__tags-text"
                      >+ {{ getLabels(items, item, true).length - 1 }}</span
                    ></span
                  >
                </template>
                <template v-else>
                  <span
                    class="el-tag el-tag--info el-tag--small el-tag--light"
                    v-for="(ele, x) in getLabels(items, item, true)"
                    :key="x"
                  >
                    <span class="el-select__tags-text">{{
                      showLabel(ele, item.labelKey)
                    }}</span>
                    <i
                      class="el-tag__close el-icon-close"
                      @click.stop="handleDelete(items, item, x, ele)"
                    ></i>
                  </span>
                </template>
              </template>
              <template v-else>
                {{ getLabels(items, item) }}
              </template>
            </div>
            <input
              v-else
              class="el-input__inner"
              :readonly="item.type && item.type !== 'text'"
              v-model.lazy="items[item.field]"
              @click="
                (event) => {
                  handeClick({ item: item, event: event, data: items });
                }
              "
              @blur="
                (event) => {
                  handleBlur({ item: item, event: event, data: items });
                }
              "
              @focus="
                (event) => {
                  handleFocus({
                    item: item,
                    event: event,
                    data: items
                  });
                }
              "
              @change="
                (value) => {
                  handleChange({
                    name: item.field || item.prop,
                    value: value,
                    data: items
                  });
                }
              "
            />
          </div>
        </template>
      </td>
    </tr>
  </tbody>
</template>
<script>
// import rules from 'eoss-ui/src/utils/rules.js';
import util from 'eoss-ui/src/utils/util';
import eoRadio from './radio.vue';
import eoCheckbox from './checkbox.vue';
export default {
  name: 'EoTbody',
  inject: ['eoTable'],
  components: {
    [eoRadio.name]: eoRadio,
    [eoCheckbox.name]: eoCheckbox,
    expandDom: {
      functional: true,
      props: {
        item: Object,
        row: Object,
        render: [Function, String]
      },
      render: (h, ctx) => {
        if (typeof ctx.props.render == 'string') {
          try {
            return util.toFunction(ctx.props.render)(h, params);
          } catch (error) {
            throw error;
          }
        }
        return ctx.props.render(h, ctx.props.item, ctx.props.row);
      }
    }
  },
  props: {
    numbers: Boolean,
    readonly: Boolean,
    cols: Array,
    data: Array,
    options: Object
  },
  methods: {
    handleBlur(data) {
      this.$emit('formBlur', data);
      this.$emit('form-blur', data);
    },
    handleFocus(data) {
      this.$emit('formFocus', data);
      this.$emit('form-focus', data);
    },
    handleChange(data) {
      this.$emit('formChange', data);
      this.$emit('form-change', data);
    },
    handeClick(res) {
      let { item, data, event } = res;
      let style = event.target.getBoundingClientRect();
      this.eoTable.setStyle(style, data, item.field || item.prop);
      let type =
        item.type == 'date' ||
        item.type == 'year' ||
        item.type == 'month' ||
        item.type == 'date' ||
        item.type == 'dates' ||
        item.type == 'week' ||
        item.type == 'datetime' ||
        item.type == 'datetimerange' ||
        item.type == 'daterange' ||
        item.type == 'monthrange' ||
        item.type == 'quarter' ||
        item.type == 'halfyear'
          ? 'date'
          : item.type;
      this.eoTable.changeData(type, data[item.field || item.prop]);
    },
    getLabels(data, col, multiple) {
      let value = data[col.field || col.prop];
      if (col.label === false) {
        return Array.isArray(value) ? value.join(',') : value;
      }
      let option = this.options[col.field || col.prop];
      if (util.isObject(value)) {
        if (multiple) {
          return [value];
        }
        return (
          value[col.labelKey] ||
          value['name'] ||
          value['label'] ||
          value['showname']
        );
      } else if (Array.isArray(value)) {
        let label = value.map((item) => {
          if (util.isObject(item)) {
            if (multiple) {
              return item;
            }
            return (
              item[col.labelKey] || item.name || item.label || item.showname
            );
          } else {
            if (option) {
              let str = this.getLabel(item, option, col, multiple);
              if (str) {
                return str;
              }
            } else {
              return item;
            }
          }
        });
        return multiple ? label : label.join(',');
      } else {
        if (option) {
          return this.getLabel(value, option, col, multiple);
        } else {
          if (multiple) {
            return [value];
          }
          return value;
        }
      }
    },
    getLabel(value, option, col, multiple) {
      for (let i = 0; i < option.length; i++) {
        let item = option[i];
        if (value == item) {
          return value;
        }
        if (value == item[col.valueKey] || value == item.value) {
          if (multiple) {
            return item;
          }
          return item[col.labelKey] || item.name || item.label || item.showname;
        }
      }
      return value;
    },
    showLabel(res, labelKey) {
      return typeof res === 'string'
        ? res
        : res[labelKey] || res.name || res.label || res.showname;
    },
    handleDelete(data, col, index, res) {
      let value = data[col.field];
      value = value.filter((item) => {
        let target = util.isObject(item)
          ? item[col.labelKey] || item.name || item.label || item.showname
          : item;
        let val = util.isObject(res)
          ? res[col.labelKey] || res.name || res.label || res.showname
          : res;
        return target != val;
      });
      data[col.field] = value;
    }
  }
};
</script>
