<template>
  <div id="arrange">
    <!-- <detail-frame :title="pageTitle" :returns="returns"> -->
    <el-row type="flex" justify="center" v-if="view == 'plan'">
      <el-col :span="24" :style="`overflow:auto`">
        <el-card ref="card" v-if="info.year" height="800px">
          <calendar
            :year="`${info.year || '2020'}`"
            :selfBtn="selfBtn"
            @draft="selectDate"
            @eventClick="eventClick"
            :vacation="vacation"
            :events="events"
          ></calendar>
        </el-card>
      </el-col>
    </el-row>
    <el-drawer :visible.sync="drawer" direction="rtl" title="安排计划" @close="toClose">
      <event
        :data="form"
        :year="info.year"
        :vacation="vacation"
        :isNew="formIsNew"
        :predefineColors="template.color"
        @save="setEvent"
        @delete="toDelete"
      ></event>
    </el-drawer>
    <el-dialog :visible.sync="dialog" title="模板计划" width="30%" :close-on-click-modal="false">
      <el-form>
        <el-form-item label="请输入您要生成的期数">
          <el-input v-model="input.term"></el-input>
        </el-form-item>
        <el-form-item label="请输入开始的期数">
          <el-tooltip content="第X期 此处为填写X" placement="right">
            <el-input-number v-model="input.termnum"></el-input-number>
          </el-tooltip>
        </el-form-item>
        <el-form-item label="请选择开始日期">
          <el-date-picker
            :picker-options="pickerOptions"
            v-model="input.start"
            type="date"
            placeholder="请选择开始日期"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
          >
          </el-date-picker>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-row :gutter="20" type="flex" justify="center" align="middle">
          <el-col :span="4">
            <el-button @click="dialog = false">取消</el-button>
          </el-col>
          <el-col :span="4">
            <el-button type="primary" @click="setDefaultPlan">确定</el-button>
          </el-col>
        </el-row>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import _ from 'lodash';
var moment = require('moment');
import detailFrame from '@frame/layout/admin/detail-frame';
import calendar from '@frame/components/calendar';
import dataTable from '@frame/components/data-table';
import event from '../parts/event';
import { mapState, createNamespacedHelpers } from 'vuex';
const { mapActions } = createNamespacedHelpers('trainplan');
const { mapActions: trainTemplate } = createNamespacedHelpers('trainTemplate');
const { mapActions: schPlan } = createNamespacedHelpers('schPlan');
const { mapActions: util } = createNamespacedHelpers('util');
export default {
  name: 'arrange',
  props: {},
  components: {
    // detailFrame,
    calendar,
    // dataTable,
    event,
  },
  data: function() {
    var that = this;
    return {
      view: 'plan',
      template: {},
      info: {
        year: '2020',
      },
      form: {},
      selectList: [],
      events: [],
      vacation: [],
      fields: [
        { label: '开始时间', prop: 'start' },
        { label: '结束时间', prop: 'end' },
        { label: '期数', prop: 'term' },
        { label: '班级类型', prop: 'type', format: item => (item === '0' ? '正常班级' : '特殊班级') },
      ],
      opera: [
        {
          label: '编辑',
          icon: 'el-icon-edit',
          method: 'edit',
        },
        {
          label: '删除',
          icon: 'el-icon-delete',
          method: 'delete',
          confirm: true,
        },
      ],
      rules: {
        title: [{ required: true, message: '请输入标题' }],
      },
      formRules: {
        start: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
        end: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
        term: [{ required: true, message: '请输入期数' }],
        number: [{ required: true, message: '请输入每班人数' }],
        type: [{ required: true, message: '请选择班级类型' }],
      },
      dialog: false,
      selfBtn: {
        term: {
          text: '生成模板计划',
          click: () => (that.dialog = true),
          position: 'left',
        },
        plan: {
          text: '保存培训计划',
          click: () => that.savePlan(),
          position: 'right',
        },
      },
      input: {
        term: 0,
      },
      pickerOptions: {
        disabledDate: time => that.checkDate(time),
      },
      heights: 250,
      collapse: '',
      drawer: false,
      formIsNew: true,
    };
  },
  created() {
    this.search();
  },
  methods: {
    ...mapActions(['fetch', 'update']),
    ...trainTemplate({ trainTemplate: 'query' }),
    ...schPlan({ setSchPlan: 'schArrange' }),
    ...util({ modelFetch: 'fetch' }),
    async search() {
      let planid = _.get(this.defaultOption, 'planid');
      if (!planid) return;
      const res = await this.fetch(planid);
      if (this.$checkRes(res)) {
        let fest = _.get(res.data, 'festivals', []);
        let vac = fest.map(i => {
          let object = {};
          object.id = i._id;
          object.start = i.begindate;
          object.end = i.finishdate;
          object.title = i.name;
          object.rendering = 'background';
          object.color = 'red';
          object.editable = false;
          return object;
        });
        this.$set(this, `vacation`, vac);
        this.$set(this, `info`, res.data);
        let midArr = JSON.parse(JSON.stringify(res.data));
        let events = [];
        events = _.flatten(
          midArr.termnum.map(item => {
            item.batchnum.map((i, index) => {
              i.termid = item._id;
              i.term = item.term;
              i.id = i._id;
              i.start = JSON.parse(JSON.stringify(i.startdate));
              i.end = JSON.parse(JSON.stringify(i.enddate));
              i.title = JSON.parse(JSON.stringify(i.name));
              delete i.startdate, delete i.enddate;
              return i;
            });
            return item.batchnum;
          })
        );
        events = events.map((i, index) => {
          i.index = index;
          return i;
        });
        this.$set(this, `events`, events);
        this.$set(this, `selectList`, events);
      }
      this.searchTemplate();
    },
    //模板事件开始
    //生成默认模板
    setDefaultPlan() {
      this.$set(this, `events`, []);
      this.$set(this, `selectList`, []);
      this.dialog = false;
      let { term, start, termnum } = this.input;
      let { day, batchnum, classnum } = this.template;
      let event = []; //处理成功事件的存储
      //第一次正常安排
      //qb:剩余没有满足之前的批数 qt:剩余没有满足之前的期数
      let { list, qb, start: rstart } = this.arrange(term, start);
      event = list;
      start = rstart;
      event = this.otherArrange(qb, start, event);
      //最后赋值回去
      event.map((i, index) => {
        i.index = index;
        return i;
      });
      //整理期数为输入的期数,将班级
      event = this.nameTerm(event, termnum);
      this.$set(this, `events`, event);
      this.$set(this, `selectList`, event);
    },
    //默认安排事件
    arrange(t, start, part) {
      let qt = 0;
      let qb = 0;
      let { day, batchnum, classnum, stunum } = this.template;
      if (!part) part = batchnum;
      let list = [];
      for (let it = 1; it <= t; it++) {
        for (let ib = 1; ib <= part; ib++) {
          let end = this.$plusDay(start, day - 1);
          let res = this.$checkDate(start, end, this.vacation);
          if (res == true) {
            let batch = {
              term: it - qt,
              batch: ib,
              class: classnum,
              start,
              end,
              type: '0',
              number: stunum,
              title: `第${it - qt}期第${ib}批次`,
              color: this.getColor(it, ib),
            };
            start = this.$plusDay(start);
            list.push(batch);
          } else {
            if (ib == 1) qt += 1;
            qb += batchnum - ib + 1;
            start = this.$plusDay(res.end);
            break;
          }
        }
      }
      return { list, qb, start };
    },
    //默认处理未安排的事件
    otherArrange(qb, start, event) {
      let { day, batchnum, classnum } = this.template;
      //将剩余的批数转换成局部变量,然后赋0重置qb,为了在arrange中重新计算是否有接触假期
      let tta = Math.ceil(qb / batchnum);
      let part = qb % batchnum;
      qb = 0;
      let { list, qb: rqb, start: rstart } = this.arrange(tta, start, part);
      start = rstart;
      let last = _.last(event);
      let arr = [];
      if (last) arr = this.sortOtherData(last, list);
      else arr = list;
      event = event.concat(arr);
      //判断是否还有剩余的批次,期;有的话还需要处理
      if (rqb > 0) {
        return this.otherArrange(rqb, start, event);
      } else {
        return event;
      }
    },
    //默认事件排序
    sortOtherData(last, data) {
      let arr = _.chunk(data, 3).map((i, index) => {
        i.map(ii => {
          ii.term = last.term + index + 1;
          ii.title = `第${ii.term}期第${ii.batch}批次`;
          return ii;
        });
        return i;
      });
      return _.flatten(arr);
    },
    //模板事件结束
    //将期数改为手动输入的
    nameTerm(events, start) {
      let duplicate = _.cloneDeep(events);
      duplicate = duplicate.map(i => {
        i.term = start * 1 + i.term - 1;
        i.title = `第${i.term}期第${i.batch}批次`;
        return i;
      });
      return duplicate;
    },
    //手动操作事件开始
    setEvent({ data, isNew }) {
      data = JSON.parse(JSON.stringify(data));
      if (data.type == 0) {
        data.title = `第${data.term}期第${data.batch}批次`;
      } else {
        let { name } = data;
        data = { ...data, title: name };
      }
      this.$set(this.events, data.index, data);
      this.$set(this.selectList, data.index, data);
      this.toClose();
    },

    //列表编辑事件
    toEdit({ data, index }) {
      this.$set(this, `form`, JSON.parse(JSON.stringify(data)));
      this.formIsNew = false;
      this.drawer = true;
    },
    //列表删除事件
    toDelete({ data, index }) {
      this.$set(
        this,
        `events`,
        this.events.filter(f => f.index !== data.index)
      );
      this.selectList.splice(index, 1);
      this.toClose();
    },
    //计划保存
    savePlan() {
      let data = JSON.parse(JSON.stringify(this.info));
      let plan = JSON.parse(JSON.stringify(this.selectList));
      let termnum = [];
      termnum = _.uniqBy(
        plan.map(item => {
          let obj = { term: item.term };
          if (item.termid) obj._id = item.termid;
          return obj;
        }),
        'term'
      ).map(i => {
        let object = _.cloneDeep(i);
        object.batchnum = plan
          .filter(fil => fil.term === i.term)
          .map(b => {
            b = _.pickBy(b, (val, key) => key !== 'term');
            b.startdate = JSON.parse(JSON.stringify(b.start));
            b.enddate = JSON.parse(JSON.stringify(b.end));
            b.name ? b.name : (b.name = JSON.parse(JSON.stringify(b.title)));
            delete b.start, delete b.end;
            if (_.startsWith(b.id, 'eve') || _.startsWith(b.id, 'vac')) delete b.id;
            return b;
          });
        object.classnum = object.batchnum.reduce((pre, cur) => {
          if (cur.type === '0') return pre + parseInt(cur.class);
          else return pre + 1;
        }, 0);
        return object;
      });
      data.termnum = termnum;
      let res;
      let msg;
      res = this.update(data);
      msg = `计划保存成功`;
      this.$checkRes(res, msg);
    },
    //选择时间的事件
    selectDate(object) {
      let start = JSON.parse(JSON.stringify(object.startStr));
      let end = JSON.parse(JSON.stringify(object.endStr));
      this.$set(this.form, `start`, start);
      this.$set(this.form, `end`, end);
      this.$set(this.form, `index`, this.events.length);
      this.drawer = true;
      this.formIsNew = true;
    },
    //
    eventClick({ event }) {
      let obj = _.get(event, `extendedProps`);
      if (!obj) {
        console.warn(`无对应事件`);
        return;
      }
      let e = this.events.find(f => f.index == obj.index);
      if (e) this.$set(this, `form`, e);
      this.drawer = true;
      this.formIsNew = false;
    },
    //
    async searchTemplate() {
      let planid = _.get(this.defaultOption, 'planid');
      let planyearid = _.get(this.defaultOption, 'planyearid');
      let res = await this.modelFetch({ model: 'trainmodel', planyearid, planid });
      if (this.$checkRes(res)) {
        if (res.data !== null) {
          this.$set(this, `template`, res.data);
        }
      }
    },
    //其他事件(无关紧要)
    //关闭抽屉函数
    toClose() {
      this.drawer = false;
      this.formIsNew = true;
      this.setHeight();
    },
    setHeight() {
      let heights = this.$refs.card.$el.clientHeight * 0.63;
      this.$set(this, `heights`, heights);
    },
    //设置事件颜色
    getColor(it, ib) {
      let { color, batchnum } = this.template;
      if (color.length > 0) {
        // let num = ((it - 1) * batchnum + ib) % color.length;
        let num = (it - 1) % color.length;
        return color[num];
      } else return '#004499';
    },

    checkDate(date) {
      let year = JSON.parse(JSON.stringify(this.info.year));
      let res = moment(date).isBetween(`${year}-01-01`, `${year}-12-31`, null, '[]');
      return !res;
    },
    // returns() {
    //   if (this.view == 'plan') this.$router.push({ path: './index' });
    //   else if (this.view == 'school') this.view = 'plan';
    //   else this.view = 'school';
    // },
    // changeView() {
    //   this.savePlan();
    //   this.view = 'school';
    // },
    async toSave(schPlan) {
      const res = await this.setSchPlan(schPlan);
      if (this.$checkRes(res)) {
        this.savePlan();
      }
    },
    toDirector() {
      this.view = 'director';
    },
  },
  watch: {
    defaultOption: {
      handler(val) {
        this.search();
      },
      deep: true,
    },
  },
  computed: {
    ...mapState(['user', 'defaultOption']),
    id() {
      return this.$route.query.id;
    },
    isNew() {
      return this.$route.query.id ? false : true; //false : true;
    },
    pageTitle() {
      return `${this.$route.meta.title}`;
    },
    widths() {
      let width = (document.body.clientWidth - 200) * 0.65;
      return width > 400 ? width : 400;
    },
  },
  metaInfo() {
    return { title: this.$route.meta.title };
  },
};
</script>

<style lang="less" scoped>
/deep/.el-card__body {
  overflow: auto;
  padding: 10px;
}
</style>
