<template>
  <div id="detail">
    <detail-frame :title="mainTitle" returns="/plan/index">
      <el-row :gutter="10" type="flex">
        <el-col :span="12">
          <el-card header="全年计划信息">
            <el-form ref="planForm" :model="info" :rules="rules" :isNew="isNew" label-width="60px" size="small" @submit.native.prevent>
              <el-form-item label="年份" required>
                {{ info.year }}
              </el-form-item>
              <el-form-item label="标题" prop="title" required>
                <el-input v-model="info.title"></el-input>
              </el-form-item>

              <el-collapse v-model="collapse" accordion>
                <el-collapse-item title="计划简表" name="1">
                  <data-table :fields="fields" :data="selectList" :opera="opera" @edit="toEdit" @delete="toDelete" :height="heights"></data-table>
                </el-collapse-item>
              </el-collapse>
              <el-form-item>
                <el-row type="flex" align="middle" justify="space-around" style="margin-top:20px">
                  <el-col :span="6">
                    <el-button type="primary" @click="toSavePlan">保存全年计划</el-button>
                  </el-col>
                </el-row>
              </el-form-item>
            </el-form>
          </el-card>
        </el-col>
        <el-col :span="16" :style="`width:${widths}px`">
          <el-card ref="card">
            <calendar :selfBtn="selfBtn" @draft="selectDate" @eventClick="eventClick" :events="events"></calendar>
          </el-card>
        </el-col>
      </el-row>
    </detail-frame>
    <el-drawer :visible.sync="drawer" direction="rtl" title="安排计划" @close="toClose">
      <event :vacation="vacation" :year="info.year" :data="form" :isNew="formIsNew" :predefineColors="predefineColors" @save="saveForm"></event>
    </el-drawer>
    <el-dialog title="设置假期" :visible.sync="dialog">
      <vacation-form :list="vacation" @update="setVacation"></vacation-form>
    </el-dialog>
  </div>
</template>

<script>
import detailFrame from '@frame/layout/admin/detail-frame';
import calendar from '@frame/components/calendar';
import dataTable from '@frame/components/data-table';
import vacationForm from './parts/vacation';
import event from './parts/event';
import _ from 'lodash';
import { createNamespacedHelpers } from 'vuex';
const { mapActions } = createNamespacedHelpers('trainplan');
export default {
  metaInfo: { title: '计划详情' },
  name: 'detail',
  props: {},
  components: { detailFrame, calendar, dataTable, vacationForm, event },
  data() {
    return {
      info: {
        year: '',
        termnum: {
          batchnum: [],
        },
      },
      form: { color: '#409EFF' },
      formIsNew: 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: '请选择班级类型' }],
      },
      drawer: false,
      dialog: false,
      events: [],
      predefineColors: ['#409EFF'],
      collapse: '',
      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,
        },
      ],
      heights: 250,
      selfBtn: {
        vacation: {
          text: '设置假期',
          //设置假期
          click: () => (this.dialog = true),
          position: 'left',
        },
      },
      selectList: [],
      vacation: [],
    };
  },
  created() {
    if (this.isNew) this.$set(this.info, `year`, new Date().getFullYear());
  },
  mounted() {},
  methods: {
    ...mapActions(['fetch', 'create', 'update']),
    //查询计划
    async search() {
      const res = await this.fetch(this.id);
      if (this.$checkRes(res)) 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 => {
            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, delete i.name;
            return i;
          });
          return item.batchnum;
        })
      );
      //这个events不完整,真正的events还需要将假期的数据整合至一起
      //计划+假期=所有事件 当前events=selectList 计划事件
      //TODO,服务端修改后,整理假期事件并整合
      console.log(events);
      this.$set(this, `selectList`, JSON.parse(JSON.stringify(events)));
      this.$set(this, `events`, events);
    },
    //拖拽选择事件
    selectDate(object) {
      let start = JSON.parse(JSON.stringify(object.startStr));
      let end = JSON.parse(JSON.stringify(object.endStr));
      let res = this.inVacation(start, end);
      if (!res) {
        this.$message.error(`不能在假期中安排计划`);
        return;
      }
      this.$set(this.form, `start`, start);
      this.$set(this.form, `end`, end);
      this.drawer = true;
      this.formIsNew = true;
    },
    //日历事件点击事件 缺少删除
    eventClick({ event }) {
      let arr = this.events.filter(fil => fil.id == event.id);
      if (arr.length > 0) {
        if (_.get(arr[0], 'editable', true)) {
          this.form = arr[0];
          this.drawer = true;
          this.formIsNew = false;
        } else this.$message.warning('请在设置假期中修改假期信息');
      } else {
        console.warn(`无对应id事件`);
        return;
      }
    },
    //列表编辑事件
    toEdit({ data, index }) {
      this.$set(this, `form`, JSON.parse(JSON.stringify(data)));
      this.drawer = true;
      this.formIsNew = false;
    },
    //列表删除事件
    toDelete({ data, index }) {
      this.selectList.splice(index, 1);
      let newEvents = this.events.filter(fil => fil.id !== data.id);
      this.$set(this, `events`, newEvents);
    },
    //全年计划保存验证
    toSavePlan() {
      this.$refs['planForm'].validate(valid => {
        if (valid) {
          this.savePlan();
        } else {
          console.warn('form validate error!!!');
        }
      });
    },
    //保存计划事件
    savePlan() {
      //全年计划内容
      let data = JSON.parse(JSON.stringify(this.info));
      data.year = this.info.year;
      let termnum = [];
      //1,获取所有期数
      //2,按期数将selectList内数据分组
      termnum = _.uniq(this.selectList.map(item => item.term)).map(i => {
        let object = { term: i };
        object.batchnum = this.selectList
          .filter(fil => fil.term === i)
          .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;
      //3 设置假期
      let vacation = JSON.parse(JSON.stringify(this.vacation));
      vacation = vacation.map(i => {
        let object = { begindate: i.start, finishdate: i.end, name: i.title };
        return object;
      });
      data.festivals = vacation;
      let res;
      let msg;
      if (this.isNew) {
        res = this.create(data);
        msg = `${this.keyWord}添加成功`;
      } else {
        res = this.update(data);
        msg = `${this.keyWord}修改成功`;
      }
      if (this.$checkRes(res, msg)) this.$router.push({ path: '/plan/index' });
    },
    //保存表单函数
    saveForm(events) {
      this.setEvent(events);
    },
    //添加/修改函数
    setEvent({ data: form, isNew }) {
      //TODO 需要根据班级类型把数据分开
      let data = JSON.parse(JSON.stringify(form));
      let { start, end, term, type, number, color, id } = data;
      let object = {};
      if (data.type === '0') {
        // 正常班级
        let { batch, class: classes } = data;
        object = { start, end, term, type, number, color, batch, class: classes };
        object.title = `第${JSON.parse(JSON.stringify(term))}期第${JSON.parse(JSON.stringify(batch))}批次`;
      } else {
        let { name } = data;
        object = { start, end, term, type, number, color, name, title: name };
      }
      if (isNew) {
        object.id = `eve${new Date().getTime()}`;
        this.events.push(object);
        this.selectList.push(object);
      } else {
        object.id = id;
        this.$set(
          this.events,
          _.findIndex(this.events, item => item.id == object.id),
          object
        );
        this.$set(
          this.selectList,
          _.findIndex(this.selectList, item => item.id == object.id),
          object
        );
        this.drawer = false;
      }
      if (_.findIndex(this.predefineColors, item => item == data.color) < 0) this.predefineColors.push(data.color);
      this.toClose();
    },
    //关闭抽屉函数
    toClose() {
      this.drawer = false;
      this.form = { color: '#409EFF' };
      this.formIsNew = true;
      this.setHeight();
    },
    setHeight() {
      let heights = this.$refs.card.$el.clientHeight * 0.63;
      this.$set(this, `heights`, heights);
    },
    //更新假期列表
    setVacation({ data, type }) {
      this.$set(this, `vacation`, data);
      let arr = [];
      if (type === 'add') {
        arr = data.map(i => {
          i.color = `red`;
          i.editable = false;
          i.id ? '' : (i.id = `vac${new Date().getTime()}`);
          return i;
        });
        this.$set(this, `events`, this.selectList.concat(arr));
      } else if (type === 'edit') {
        for (const i of data) {
          this.$set(
            this.events,
            _.findIndex(this.events, item => item.id == i.id),
            i
          );
        }
      } else if (type === 'delete') {
        this.$set(this, `events`, this.selectList.concat(data));
      }
    },
    //判断是否在假期中
    inVacation(start, end) {
      let startTime = new Date(start).getTime();
      let endTime = new Date(end).getTime();
      let res = true;
      for (const vac of this.vacation) {
        let vacS = new Date(vac.start).getTime();
        let vacE = new Date(vac.end).getTime();
        //case1 事件开始时间<假期开始时间 => 事件结束时间 > 假期开始时间 ? 事件碰到假期了.不行了 : 事件没碰到假期,没事
        //case2 事件开始时间>=假期开始时间 => 事件开始时间 < 假期结束时间 ? GG return false: return true;
        if (startTime >= vacS) {
          if (startTime < vacE) {
            res = false;
            console.warn(`case2`);
            break;
          }
        } else {
          if (endTime > vacS) {
            res = false;
            console.warn(`case1`);
            break;
          }
        }
      }
      //比较选择的时间在不在假期中,然后返回结果
      return res;
    },
  },
  watch: {
    isNew: {
      immediate: true,
      handler(val) {
        if (val) this.loading = false;
        else this.search();
      },
    },
  },
  computed: {
    widths() {
      let width = (document.body.clientWidth - 200) * 0.5;
      return width > 400 ? width : 400;
    },
    id() {
      return this.$route.query.id;
    },
    isNew() {
      return this.$route.query.id ? false : true; //false : true;
    },
    mainTitle() {
      let meta = this.$route.meta;
      let main = meta.title || '';
      let sub = meta.sub || '';
      return `${main}${sub}`;
    },
    keyWord() {
      let meta = this.$route.meta;
      let main = meta.title || '';
      return main;
    },
  },
};
</script>

<style lang="less" scoped>
/deep/.el-divider--horizontal {
  margin: 5px 0;
}
</style>
