<template>
  <div v-if="filters" class="x-filter">
    <div class="body">
      <div class="left">
        <Dropdown placement="bottom-start" @on-click="select">
          <a href="javascript:void(0)">
            <Icon type="md-arrow-dropdown" />
          </a>
          <DropdownMenu slot="list">
            <DropdownItem
              v-for="(l, index) in filters"
              :name="l.field"
              :key="index"
              clearable
              >{{ l.title }}</DropdownItem
            >
          </DropdownMenu>
        </Dropdown>
        <span v-show="selectData.title">{{ selectData.title }}：</span>
      </div>
      <div class="content">
        <div v-for="(l, index) in filters" :key="index">
          <!-- type = input -->
          <Input
            v-if="types(l.type) === 'input'"
            v-show="current === l.field"
            v-model="form[l.field]"
            :type="typeValue(l.type) || 'text'"
            :placeholder="l.placeholder || `请输入${l.title}模糊查询`"
          />
          <!-- type = dict -->
          <Select
            v-else-if="types(l.type) === 'dict'"
            v-show="current === l.field"
            v-model="form[l.field]"
            clearable
            :placeholder="l.placeholder || `请选择${l.title}`"
          >
            <Option
              v-for="item in typeDicts(l.type)"
              :value="item.value"
              :key="item.value"
              >{{ item.name }}</Option
            >
          </Select>
          <!-- type = select -->
          <Select
            v-else-if="types(l.type) === 'select'"
            v-show="current === l.field"
            v-model="form[l.field]"
            clearable
            :placeholder="l.placeholder || `请选择${l.title}`"
          >
            <Option
              v-for="item in l.list"
              :value="item.value"
              :key="item.value"
              >{{ item.name }}</Option
            >
          </Select>
          <!-- type = time -->
          <DatePicker
            v-if="types(l.type) === 'time'"
            v-show="current === l.field"
            v-model="form[l.field]"
            style="width:100%"
            :type="typeDate(l.type)"
            :placeholder="l.placeholder || `请选择${l.title}查询`"
          />
        </div>
      </div>
      <div class="right">
        <Button style="width: 100%;height: 100%" @click="onSearch">
          <i style="font-size: 16px" class="ivu-icon ivu-icon-ios-search"></i>
        </Button>
      </div>
    </div>
    <div class="x-filter-list" v-show="filterList.length > 0">
      <div class="name"><Icon type="ios-funnel" />检索项：</div>
      <div class="x-filter-list__items">
        <span v-for="l in filterList" :key="l.field">
          {{ searchItem(l) }}
          <Icon type="md-close" @click="onRemove(l.field)" />
        </span>
        <a href="javascript:;" @click="onClear">清除</a>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "x-filter",
  props: {
    filters: Array
  },
  data() {
    return {
      selectData: {},
      form: {},
      current: "",
      query: {},
      filterList: [],
      filterMap: {},

      // 公共资源
      dicts: [],
      dictMap: {},
      units: [],
      unitMap: {}
    };
  },
  methods: {
    Reset() {
      this.query = {};
      this.filterList = [];
    },
    types(type) {
      let [ty] = type.split(":");
      return ty;
    },
    typeValue(type) {
      let [ty, value] = type.split(":");
      return value;
    },
    typeDicts(type) {
      if (!/[a-zA-Z0-9]+:[a-zA-Z0-9]/.test(type)) return [];
      let [ty, flag] = type.split(":");
      let o = this.dicts.find(r => r.id == flag);
      if (!o) return [];
      return o.values;
    },
    typeDate(type) {
      if (!/[a-zA-Z0-9]+:[a-zA-Z0-9]/.test(type)) return "date";
      let [ty, flag] = type.split(":");
      let types = [
        "date",
        "daterange",
        "datetime",
        "datetimerange",
        "year",
        "month"
      ];
      if (types.indexOf(flag) == -1) return "date";
      return flag;
    },
    select(value) {
      this.current = value;
      if (value) {
        this.selectData = this.filters.find(l => l.field == value);
      }
    },
    onRemove(field) {
      delete this.query[field];
      this.search();
    },
    onClear() {
      this.query = {};
      this.search();
    },
    onSearch() {
      let val = this.form[this.current];
      if (!val) {
        return;
      }
      let title = this.filters.find(r => r.field == this.current).title;
      this.query[this.current] = {
        title,
        value: val,
        time: new Date().getTime(),
        field: this.current
      };
      this.form = {};
      this.search();
    },
    search() {
      this.filterList = [];
      for (let k in this.query) {
        this.filterList.push(this.query[k]);
      }
      this.filterList = this.filterList.sort((a, b) => {
        return a.time > b.time;
      });
      let query = {};
      for (let o of this.filterList) {
        let fd = this.filterMap[o.field];
        switch (this.types(fd.type)) {
          case "time":
            if (fd.type.indexOf("range") != -1) {
              let [start, end] = o.field.split(",");
              if (!end) {
                query[o.field] = [
                  (o.value[0].getTime() || 0) / 1000,
                  (o.value[1].getTime() || 0) / 1000
                ];
              } else {
                query[start] = (o.value[0].getTime() || 0) / 1000;
                query[end] = (o.value[1].getTime() || 0) / 1000;
              }
            } else {
              query[o.field] = (o.value.getTime() || 0) / 1000;
            }
            break;
          default:
            let field = o.field;
            if (field.indexOf("[]") == 0) {
              query[field.replace("[]", "")] = [o.value];
            } else {
              query[o.field] = o.value;
            }
        }
      }
      this.$emit("on-search", query);
    },
    searchItem(v) {
      let [ty, vl] = this.filterMap[v.field].type.split(":");
      if (!vl) {
        vl = "text";
      }

      switch (ty) {
        case "dict":
          let dicts = this.dictMap[vl];
          if (!dicts) return "-";
          let o = dicts.values.find(r => r.value == v.value);
          if (!o) return "-";
          return o.name;
        case "time":
          if (vl.indexOf("range") != -1) {
            return (
              this.timeFormat(v.value[0], "yyyy-MM-dd") +
              " ~ " +
              this.timeFormat(v.value[1], "yyyy-MM-dd")
            );
          }
          return this.timeFormat(v.value, "yyyy-MM-dd");
        default:
          return v.value;
      }
    },
    init() {
      let units =
        ((this.$store || { state: {} }).state.common || {}).units || [];
      if (units.length == 0) {
        console.error(
          "unit单位列表未配置，需要在store.common.units中配置unit列表"
        );
        return;
      }
      this.units = units;
      this.unitMap = {};
      for (let o of units) {
        this.unitMap[o.id] = o;
      }

      let dicts =
        ((this.$store || { state: {} }).state.common || {}).dicts || [];
      if (dicts.length == 0) {
        console.error(
          "dicts数据字典列表未配置，需要在store.common.dicts中配置dict列表"
        );
        return;
      }
      this.dicts = dicts;
      this.dictMap = {};
      for (let o of dicts) {
        this.dictMap[o.id] = o;
      }
    },
    timeFormat(time, fmStr) {
      const weekCN = "一二三四五六日";
      const weekEN = [
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday",
        "Sunday"
      ];

      let year = time.getFullYear();
      let month = time.getMonth() + 1;
      let day = time.getDate();
      let hours = time.getHours();
      let minutes = time.getMinutes();
      let seconds = time.getSeconds();
      let milliSeconds = time.getMilliseconds();
      let week = time.getDay();

      month = month >= 10 ? month : "0" + month;
      day = day >= 10 ? day : "0" + day;
      hours = hours >= 10 ? hours : "0" + hours;
      minutes = minutes >= 10 ? minutes : "0" + minutes;
      seconds = seconds >= 10 ? seconds : "0" + seconds;

      if (fmStr.indexOf("yyyy") !== -1) {
        fmStr = fmStr.replace("yyyy", year);
      } else {
        fmStr = fmStr.replace("yy", (year + "").slice(2));
      }
      fmStr = fmStr.replace("MM", month);
      fmStr = fmStr.replace("dd", day);
      fmStr = fmStr.replace("hh", hours);
      fmStr = fmStr.replace("mm", minutes);
      fmStr = fmStr.replace("ss", seconds);
      fmStr = fmStr.replace("SSS", milliSeconds);
      fmStr = fmStr.replace("W", weekCN[week - 1]);
      fmStr = fmStr.replace("ww", weekEN[week - 1]);
      fmStr = fmStr.replace("w", week);

      return fmStr;
    }
  },
  created() {
    this.init();
  },
  mounted() {
    if (this.filters.length > 0) {
      this.selectData = this.filters[0];
      this.current = this.selectData.field;

      this.filterMap = {};
      for (let o of this.filters) {
        this.filterMap[o.field] = o;
      }
    }
  }
};
</script>
<style lang="less" scoped>
.x-filter {
  * {
    line-height: normal;
  }
  .body {
    display: flex;
    align-items: stretch;
    .left {
      display: flex;
      border-top: 1px solid #ccc;
      border-left: 1px solid #ccc;
      border-bottom: 1px solid #ccc;
      align-items: center;
      background-color: #fff;
      .ivu-dropdown-rel {
        a {
          display: flex;
          width: 30px;
          height: 100%;
          font-size: 16px;
          line-height: 32px;
          justify-content: center;
          i {
            color: #999;
          }
        }
        a:hover {
          i {
            color: #333;
          }
        }
      }
    }
    .content {
      width: 220px;
      border-top: 1px solid #ccc;
      border-bottom: 1px solid #ccc;
      /deep/ input {
        border: none;
      }
      /deep/ input:focus {
        box-shadow: none;
      }
      /deep/ .ivu-select-selection {
        border: none;
        display: flex;
        align-items: center;
      }
      /deep/ .ivu-select-selection:focus {
        box-shadow: none;
      }
    }
    .right {
      width: 64px;
      .ivu-btn {
        border-top-left-radius: 0px !important;
        border-bottom-left-radius: 0px !important;
        border: none;
        background: #19be6b;
        color: #fff;
      }
    }
  }
}
.x-filter-list {
  display: flex;
  align-items: center;
  padding: 8px 0 2px;
  &__name {
    color: #666;
    line-height: normal;
  }
  &__items {
    flex: 1;
    a {
      float: left;
      color: #999;
      margin-top: 3px;
      line-height: normal;
      &:hover {
        color: #333;
      }
    }
    span {
      padding: 2px 8px;
      border-radius: 4px;
      border: 1px solid #ddd;
      background: #f3f3f3;
      font-size: 12px;
      margin-right: 8px;
      color: #333333;
      float: left;
      line-height: normal;
      i {
        font-size: 14px;
        vertical-align: text-top;
        margin-left: 5px;
        cursor: pointer;
      }
    }
  }
}
</style>
