<template>
  <div id="test">
    <el-row type="flex" :gutter="10">
      <el-col :span="this.user && this.user.role_id === '-1' ? 3 : 0" class="left" v-if="this.user && this.user.role_id === '-1'">
        <dept :deptList="deptList" @select="toSelectDept" />
      </el-col>
      <el-col :span="this.user && this.user.role_id === '-1' ? 21 : 24" class="right">
        <calendar v-model="viewDate" :dept="selectDept" :list="collectDateList" :recordList="recordList" @select="selectDate" @add="toAdd" @delete="toDelete" />
      </el-col>
    </el-row>
    <el-dialog title="编辑安排" center :destroy-on-close="false" :visible.sync="dialog">
      <add v-if="editView === 'add'" @save="addSave" :dept="selectDept" />
      <edit v-else v-model="form" :editDate="editDate" @save="editSave" @delete="toDelete" :dept="selectDept"></edit>
    </el-dialog>
  </div>
</template>

<script>
import jwt from 'jsonwebtoken';
const _ = require('lodash');
const axios = require('axios');
const moment = require('moment');
import add from './parts/add.vue';
import edit from './parts/edit.vue';
import dept from './parts/dept.vue';
import calendar from './parts/calendar.vue';
import { mapGetters, createNamespacedHelpers } from 'vuex';
const { mapActions: police_department } = createNamespacedHelpers('police_department');
const { mapActions: reserve_collect } = createNamespacedHelpers('reserve_collect');
const { mapActions: reserve_record } = createNamespacedHelpers('reserve_record');
const { mapActions } = createNamespacedHelpers('system_account');
export default {
  name: 'index',
  props: {},
  components: { dept, calendar, add, edit },
  data: function () {
    return {
      // 分局列表
      deptList: [],
      // 选择的分局
      selectDept: {},
      dialog: false,
      form: {},
      collectDateList: [],
      recordList: [],
      viewDate: new Date(),
      editView: 'add',
      editDate: undefined,
      user: {},
    };
  },
  async created() {
    await this.getDept();
    await this.init();
  },
  methods: {
    ...police_department({ deptQuery: 'query' }),
    ...reserve_collect(['query', 'create', 'update', 'delete']),
    ...reserve_record({ getRecordList: 'query' }),
    ...mapActions({ getUser: 'fetch' }),
    async init() {
      const token = localStorage.getItem('token');
      if (!token) return;
      const tokenInfo = jwt.decode(token);
      if (!_.get(tokenInfo, 'id')) return;
      const res = await this.getUser({ id: tokenInfo.id });
      if (this.$checkRes(res)) {
        let data = _.cloneDeep(res.data);
        this.$set(this, `user`, data);
        if (!(this.user && this.user.role_id === '-1')) {
          // 需要查到该分局id,然后再进入选择分局,相当于手选分局
          const dept = this.deptList.find((f) => f.num === data.department_code);
          if (dept) this.toSelectDept({ id: dept.id, name: dept.name });
        }
      }
    },
    /**
     * 获取分局列表
     */
    async getDept() {
      const res = await this.deptQuery({ type: '2' });
      if (this.$checkRes(res)) {
        this.$set(this, 'deptList', res.data);
      }
    },
    /**
     * 选择分局
     */
    async toSelectDept(data, date = this.viewDate) {
      const dateRange = this.getDateRange(date);
      const query = { dept_id: data.id, ...dateRange };
      // 查预约安排
      await this.getCollectArrange(query);
      // TODO 查已预约记录
      await this.getRecord(query);
      this.$set(this, `selectDept`, data);
    },
    /**
     * 查询预约安排
     */
    async getCollectArrange(condition = {}) {
      const res = await this.query(condition);
      if (this.$checkRes(res)) {
        let data = _.cloneDeep(res.data);
        data = _.orderBy(data, ['collect_date'], ['asc']);
        this.$set(this, `collectDateList`, data);
      }
    },
    /**
     * 获取已预约的记录
     */
    async getRecord(condition = {}) {
      const res = await this.getRecordList(condition);
      if (this.$checkRes(res)) {
        this.$set(this, 'recordList', res.data);
      }
    },
    /**
     * 添加安排
     */
    toAdd() {
      this.formInit();
      this.dialog = true;
      this.editView = 'add';
    },
    /**
     * 选择安排进行修改
     */
    selectDate(data) {
      let dup = _.cloneDeep(data);
      const head = _.head(dup);
      if (head && _.get(head, 'collect_date')) this.$set(this, `editDate`, _.get(head, 'collect_date'));
      for (const i of dup) {
        i.time = [i.collect_time_start, i.collect_time_end];
      }
      dup = _.orderBy(dup, ['collect_date', 'collect_time_start'], 'asc');
      this.$set(this, 'form', dup);
      this.dialog = true;
      this.editView = 'edit';
    },
    /**
     * 添加保存
     */
    async addSave(data) {
      let result = true;
      const errorList = [];
      for (const i of data) {
        try {
          if (_.get(this.selectDept, 'id')) i.dept_id = _.get(this.selectDept, 'id');
          let r = await this.create(i);
          if (!this.$checkRes(r)) {
            result = false;
          }
        } catch (error) {
          const word = `${i.collect_date} ${i.collect_time_start}-${i.collect_time_end} 添加失败`;
          errorList.push(word);
          console.error(word);
          continue;
        }
      }
      if (result) {
        this.$message.success('保存成功');
        this.toSelectDept(this.selectDept);
        this.dialog = false;
        this.editView = 'add';
        this.formInit();
      } else {
        for (const e of errorList) {
          this.$message.error(e);
        }
      }
    },
    /**
     * 编辑保存
     */
    async editSave(data) {
      let result = true;
      const errorList = [];
      // 先处理每条数据的time,
      for (const i of data) {
        try {
          const { time, id } = i;
          if (_.head(time)) i.collect_time_start = _.head(time);
          if (_.last(time)) i.collect_time_end = _.last(time);
          if (time) delete i.time;
          let r;
          if (!id) {
            // create
            if (_.get(this.selectDept, 'id')) i.dept_id = _.get(this.selectDept, 'id');
            r = await this.create(i);
          } else {
            // update
            r = await this.update(i);
          }
          if (!this.$checkRes(r)) {
            result = false;
          }
        } catch (error) {
          const word = `${i.collect_date} ${i.collect_time_start}-${i.collect_time_end} ${i.id ? '修改' : '添加'}失败`;
          errorList.push(word);
          console.error(word);
          continue;
        }
      }
      if (result) {
        this.$message.success('操作成功');
        this.toSelectDept(this.selectDept);
        this.dialog = false;
        this.editView = 'add';
        this.formInit();
      } else {
        for (const e of errorList) {
          this.$message.error(e);
        }
      }
    },
    /**
     * 删除
     */
    async toDelete(data, notClose) {
      // 要查询是否已经有人报了名,如果有人报名,就不允许删除和修改了
      const checkCanOpera = this.checkCanEditOrDelete(data.collect_date);
      if (checkCanOpera) {
        this.$message.warning(`${data.collect_date} 已有预约,不能删除`);
        return;
      }
      if (!_.isArray(data)) {
        const res = await this.delete(data);
        if (this.$checkRes(res, '删除成功', '删除失败')) {
          this.toSelectDept(this.selectDept);
          if (notClose !== true) {
            this.dialog = false;
            this.formInit();
          }
        }
      } else {
        // 数组,批量删除
        const arr = data.map((i) => this.delete({ id: i }));
        const res = await axios.all(arr);
        let errorNumber = 0;
        for (const r of res) if (r.errcode !== 0) errorNumber++;
        if (errorNumber !== 0 && errorNumber < arr.length) this.$message.error('部分删除发生错误,请尝试单独删除未被删除的数据并告知开发人员');
        else if (errorNumber === arr.length) this.$message.error('删除发生错误,请联系开发人员进行检查');
        else if (errorNumber === 0) {
          this.$message.success('删除成功');
          this.toSelectDept(this.selectDept);
          if (notClose !== true) {
            this.dialog = false;
            this.formInit();
          }
        }
      }
    },
    /**
     * 检查是否有安排
     */
    checkCanEditOrDelete(date) {
      const r = this.recordList.find((f) => f.collect_date === date);
      if (r) return true;
      return false;
    },
    /**
     * 初始化表单
     */
    formInit() {
      if (this.editView === 'add') this.form = { arrange: [] };
    },

    // 获取某月的范围
    getDateRange(date = moment().format('YYYY-MM-DD')) {
      const key = 'collect_date';
      const start = moment(date).format('YYYY-MM-01');
      const end = moment(start).add(1, 'M').subtract(1, 'd').format('YYYY-MM-DD');
      return { [`${key}@start`]: start, [`${key}@end`]: end };
    },
  },
  computed: {
    ...mapGetters(['tokenInfo']),
  },
  watch: {
    viewDate: {
      handler(val, oval) {
        const n = moment(val).format('YYYY-MM-01');
        const o = moment(oval).format('YYYY-MM-01');
        if (_.get(this.selectDept, 'id') && n !== o) this.toSelectDept(this.selectDept, val);
      },
    },
  },
};
</script>

<style lang="less" scoped>
.left {
  overflow-y: auto;
  height: 80vh;
}
.right {
  /deep/.el-card__body {
    padding: 10px;
    height: 70vh;
  }
}
</style>
