<template>
  <div class="app-container">
    <!-- 患者信息卡片-->
    <el-card v-loading="patientInfoLoading" class="card">
      <div slot="header" class="patient-card-header">
        <span>患者信息</span>
      </div>
      <div class="patient-card-body">
        <div class="patient-card-body-item">
          <div class="patient-card-body-item-title">患者姓名:</div>
          <div class="patient-card-body-item-content">{{ patientInfo.patientName }}</div>
        </div>
        <div class="patient-card-body-item">
          <div class="patient-card-body-item-title">性别:</div>
          <div class="patient-card-body-item-content">{{ genderFormat(patientInfo.gender) }}</div>
        </div>
        <div class="patient-card-body-item">
          <div class="patient-card-body-item-title">年龄:</div>
          <div class="patient-card-body-item-content">{{ patientInfo.age }}</div>
        </div>
        <div class="patient-card-body-item">
          <div class="patient-card-body-item-title">病人类型:</div>
          <div class="patient-card-body-item-content">{{ patientInfo.visitTypeName }}</div>
        </div>
        <div class="patient-card-body-item">
          <div class="patient-card-body-item-title">病人标识:</div>
          <div class="patient-card-body-item-content">{{ patientInfo.patientId }}</div>
        </div>
        <div class="patient-card-body-item">
          <div class="patient-card-body-item-title">电话号码:</div>
          <div class="patient-card-body-item-content">{{ patientInfo.phone }}</div>
        </div>
      </div>
    </el-card>
    <div class="body">
      <el-row>
        <el-col :span="10">
          <el-card class="body-left card">
            <div slot="header">
              <span>申请单项目列表</span>
            </div>
            <el-table ref="multipleTable" v-loading="tableLoading" :cell-class-name="cellClassName"
                      :data="applyList" border class="table"
                      default-expand-all height="470"
                      row-key="id" stripe tooltip-effect="light" @row-click="rowClick"
            >
              <el-table-column align="left" fixed="left" label="申请单号" min-width="150" prop="applyNum"
                               show-overflow-tooltip
              />
              <el-table-column align="left" fixed="left" label="项目名称" min-width="130" prop="inExamItemName"
                               show-overflow-tooltip
              />
              <el-table-column :formatter="applyStateFormat" align="center" label="预约状态" prop="applyState"
                               show-overflow-tooltip
                               width="100"
              />
              <el-table-column align="center" label="预约院区" min-width="170" prop="yardName" show-overflow-tooltip/>
              <el-table-column :formatter="reservationDateFormat" align="center" label="预约时间段" prop="reservationDate"
                               width="180"
              />
              <el-table-column align="center" label="预约序号" min-width="160" prop="reservationNum" show-overflow-tooltip/>
              <el-table-column :formatter="isPayFormat" align="center" label="缴费状态" prop="isPay" width="75"/>
            </el-table>
          </el-card>
        </el-col>
        <el-col :span="14">
          <div v-loading="sourceLoading" class="calendar">
            <div v-for="item in sourceList" :class="item.day === checkDate ? 'active-item':'' "
                 class="calendar-item" @click="checkedDate(item.day)"
            >
              <div>
                <span>{{ item.day }} {{ item.week }}</span>
              </div>
              <div class="calendar-item-source" style="min-height: 21px">
                <span v-for="i in getSourceList(item)">
                  {{ i.examTypeName }}
                </span>
              </div>
              <div style="min-height: 21px">
                <span v-if="checkSource&&checkSource.id&&item.day === checkSource.examDate.substring(5)"
                      style="color: #eed200"
                >✔</span>
                <span v-if="isDateMade(item.day)">已约</span>
              </div>
            </div>
          </div>
          <div class="source-list">
            <div v-for="item in checkSourceList" class="source-list-item">
              <div class="item-left">
                {{ item.examTypeName }}
              </div>
              <div class="item-right">
                <div v-for="obj in item.list"
                     :class="{'source-item-active':obj.id === checkSource.id,'source-item-disabled':!isUsed(obj)}"
                     class="source-item" @click="checkedSource(obj)"
                >
                  {{ obj.timeSlot + '  ' + sourceFormat(obj) }}
                  <span v-if="isUsedSource(obj)" style="color: #ecab00;padding-left: 10px;padding-bottom: 5px;"
                  >已约</span>
                </div>
              </div>
            </div>
          </div>
          <div style="padding-left: 30px">
            <el-button :disabled="cancelDisabled()" type="success" @click="cancel">取消预约</el-button>
            <el-button :disabled="appointmentDisabled()" type="success" @click="reservation">预约</el-button>
          </div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
import { getPatientInfo } from '@/api/resource/patient'
import { cancelApply, changeApply, getApply, listByManual, updateApply } from '@/api/resource/apply'
import { sourceListByExamType } from '@/api/resource/sourcePool'

export default {
  name: 'customerAppointment',
  data() {
    return {
      patientInfo: {}, // 患者信息,
      currentRow: {}, // 当前选中的项目信息
      applyList: [], // 申请单列表
      tableLoading: false, // 表格loading
      patientInfoLoading: false, // 患者信息卡片loading
      sourceLoading: false, // 号源刷新loading
      genderOptions: [], // 性别字典
      applyStateOptions: [],// 申请单状态字典
      isPayOptions: [], // 支付状态字典
      timeList: [], // 今天包含后面七天的日期
      sourceList: [], // 按照日期排列的号源
      examList: [], // 检查类型列表
      checkDate: '', // 当前选中的日期
      checkSourceList: [], // 当前选中日期的号源列表
      checkSource: {}  // 当前点击选中的号源
    }
  },
  methods: {
    // 获取字典label
    getDictLabel(dict = [], value) {
      let obj = dict.find(item => item.dictValue + '' === value + '')
      if (obj) {
        return obj.dictLabel
      }
      return value
    },
    // 性别字典翻译
    genderFormat(gender) {
      return this.selectDictLabel(this.genderOptions, gender)
    },
    // 申请单状态字典翻译
    applyStateFormat(row, column) {
      return this.getDictLabel(this.applyStateOptions, row.applyState)
    },
    // 时间段合并
    reservationDateFormat(row) {
      let txt = ''
      if (row.reservationDate) {
        txt += row.reservationDate
      }
      txt += ' '
      if (row.reservationTimeSlot) {
        txt += row.reservationTimeSlot
      }
      return txt
    },
    // 是否交费字典翻译
    isPayFormat(row) {
      return this.getDictLabel(this.isPayOptions, row.isPay)
    },
    // 行选中事件
    rowClick(row) {
      if (!row.children) {
        this.currentRow = row
      }
    },
    // 判断选中行样式
    cellClassName({ row, rowIndex }) {
      if (row.id === this.currentRow.id) {
        return 'cell-active'
      }
    },
    // 初始化患者信息,从传递过来的这一条数据中取出
    initPatientInfo(patientId, applyId) {
      this.patientInfoLoading = true
      getPatientInfo({ patientId, applyId })
        .then(res => {
          this.patientInfo = res.data
        }).finally(_ => {
        this.patientInfoLoading = false
      })
    },
    // 初始化字典
    initDict() {
      this.getDicts('apply_status').then((response) => {
        this.applyStateOptions = response.data
      })
      this.getDicts('sys_user_sex').then((response) => {
        this.genderOptions = response.data
      })
      this.getDicts('pay_status').then((response) => {
        this.isPayOptions = response.data
      })
    },
    // 初始化表格
    initApplyList(patientId, applyId) {
      this.tableLoading = true
      listByManual({
        patientId, applyId
      }).then(res => {
        // 表格数据分组,父id使用applyNum替换,
        let arr = []
        let examTypes = []
        let expansion = null
        const currentIndex = res.data.findIndex(item => item.id === applyId)
        const current = res.data[currentIndex]
        expansion = { id: current.applyNum }
        res.data.splice(currentIndex, 1)
        res.data.unshift(current)
        this.currentRow = current
        res.data.forEach(item => {
          // 选中默认的项目,需要展开
          /*if (applyId === item.id) {
            this.currentRow = item
            expansion = { id: item.applyNum }
          }*/
          // 统计全部的检查类型来查号源
          if (!examTypes.includes(item.examTypeId)) {
            examTypes.push(item.examTypeId)
          }
          let index = arr.findIndex(i => i.applyNum === item.applyNum)
          // 将项目结果封装成父子的形式
          if (index === -1) {
            arr.push({
              id: item.applyNum,
              applyNum: item.applyNum,
              yardName: item.yardName,
              children: [item]
            })
          } else {
            arr[index].children.push(item)
          }
        })
        this.examList = examTypes
        this.applyList = arr
        this.$nextTick(() => {
          this.initSourceList(applyId)
          this.$refs.multipleTable.toggleRowExpansion(expansion, true)
        })
      }).finally(_ => {
        this.tableLoading = false
      })
    },
    formatDate(date) {
      let month = '' + (date.getMonth() + 1)
      let day = '' + date.getDate()
      //let year = date.getFullYear()
      if (month.length < 2) month = '0' + month
      if (day.length < 2) day = '0' + day
      const weeks = '日一二三四五六'
      return {
        day: [month, day].join('-'),
        week: `周${weeks.charAt(date.getDay())}`
      }
    },
    formatDateYmd(date) {
      let month = '' + (date.getMonth() + 1)
      let day = '' + date.getDate()
      let year = date.getFullYear()
      if (month.length < 2) month = '0' + month
      if (day.length < 2) day = '0' + day
      return [year, month, day].join('-')
    },
    // 初始化时间
    initTimeList() {
      let arr = []
      let now = new Date()
      arr.push(this.formatDate(now))
      for (let i = 1; i <= 7; i++) {
        now.setDate(now.getDate() + 1)
        arr.push(this.formatDate(now))
      }
      this.timeList = arr
    },
    // 初始化查询号源
    initSourceList() {
      this.sourceLoading = true
      sourceListByExamType({
        examTypes: this.examList.join(',')
      }).then(res => {
        let arr = this.timeList.map(item => ({
          ...item,
          data: [] // 存号源 { examTypeId,examTypeName,queueId,list:[] }
        }))
        res.data.forEach(item => {
          let timeObj = arr.find(a => a.day === item.examDate.substring(5))
          if (timeObj) {
            let sourceObj = timeObj.data.find(d => d.examTypeId === item.examTypeId)
            if (sourceObj) {
              sourceObj.list.push(item)
            } else {
              timeObj.data.push({
                examTypeId: item.examTypeId,
                examTypeName: item.examTypeName,
                queueId: item.queueId,
                list: [item]
              })
            }
          }
        })
        // 排序一下
        arr.forEach(item => {
          item.data.forEach(d => {
            d.list.sort((x, y) => {
              return new Date(`2022-01-01 ${x.timeSlot.split('-')[0]}`).getTime() - new Date(`2022-01-01 ${y.timeSlot.split('-')[0]}`).getTime()
            })
          })
        })
        this.sourceList = arr
      }).finally(_ => {
        this.sourceLoading = false
      })
    },
    // 选择日期
    checkedDate(date) {
      this.checkDate = date
      this.checkSourceList = this.sourceList.find(item => item.day === date)?.data || []
    },
    // 点击选中号源
    checkedSource(obj) {
      if (this.isUsed(obj)) {
        this.checkSource = obj
      }
    },
    // 号源格式化
    sourceFormat(source) {
      let visitTypeId = ''
      if (this.currentRow && this.currentRow.id) {
        visitTypeId = this.currentRow.visitTypeId
      } else {
        visitTypeId = this.patientInfo.visitTypeId
      }
      if (visitTypeId + '' === '1') { // 门诊
        return `${source['outSourceCount']}/${source['inNumSourceCount']}`
      }
      if (visitTypeId + '' === '2') { // 住院
        return `${source['inSourceCount']}/${source['outNumSourceCount']}`
      }
      if (visitTypeId + '' === '3') { // 体检
        return `${source['phySourceCount']}/${source['phySourceCount']}`
      }
    },
    // 获取总号源与使用的号源
    getUseSource(source) {
      let visitTypeId = ''
      if (this.currentRow && this.currentRow.id) {
        visitTypeId = this.currentRow.visitTypeId
      } else {
        visitTypeId = this.patientInfo.visitTypeId
      }
      if (visitTypeId + '' === '1') { // 门诊
        return {
          use: parseInt(source['outSourceCount']),
          total: parseInt(source['inNumSourceCount'])
        }
      }
      if (visitTypeId + '' === '2') { // 住院
        return {
          use: parseInt(source['inSourceCount']),
          total: parseInt(source['outNumSourceCount'])
        }
      }
      if (visitTypeId + '' === '3') { // 体检
        return {
          use: parseInt(source['phySourceCount']),
          total: parseInt(source['phySourceCount'])
        }
      }
    },
    // 获取当天号源是否可用
    getSourceList(item) {
      let arr = []
      const now = new Date()
      if (item.data && item.data.length > 0) {
        item.data.forEach(item => {
          // 分别计算当天号源
          let temp = { examTypeName: item.examTypeName.charAt(0), flag: false }
          for (let i = 0; i < item.list.length; i++) {
            // 计算时间与号源数量,看是否有号源
            if (new Date(`${item.list[i].examDate} ${item.list[i].timeSlot.split('-')[1]}`).getTime() - now.getTime() > 0) {
              const { use, total } = this.getUseSource(item.list[i])
              if (use < total) {
                temp.flag = true
                break
              }
            }
          }
          arr.push(temp)
        })
      }
      return arr
    },
    // 此时段号源是否可点击
    isUsed(source) {
      const now = new Date()
      if (new Date(`${source.examDate} ${source.timeSlot.split('-')[1]}`).getTime() - now.getTime() > 0) {
        const { use, total } = this.getUseSource(source)
        return use < total
      }
      return false
    },
    isUsedSource(obj) {
      return this.currentRow.sourceId === obj.id + ''
    },
    // 日期是否已约
    isDateMade(date) {
      if (this.currentRow && this.currentRow.id) {
        return this.currentRow.applyState === 1 && this.currentRow.reservationDate.substring(5) === date
      }
      return false
    },
    // 预约按钮的disabled
    appointmentDisabled() {
      console.log(this.currentRow, this.checkSource)
      if (!this.currentRow || !this.currentRow.id) {
        return true
      }
      if (!this.checkSource || !this.checkSource.id) {
        return true
      }
      if (this.currentRow.queueId === null || this.currentRow.queueId === 0) {
        return true
      }
      // 如果当前选中的队列与号源的队列不同也无法预约
      /*if (this.currentRow.queueId !== this.checkSource.queueId) {
        return true
      }*/
      if (this.currentRow.examTypeId !== this.checkSource.examTypeId) {
        return true
      }
      // 判断状态
      return ![0, 1].includes(this.currentRow.applyState)

    },
    // 取消按钮的disabled
    cancelDisabled() {
      if (!this.currentRow || !this.currentRow.id) {
        return true
      }
      if (this.currentRow.queueId === null || this.currentRow.queueId === 0) {
        return true
      }
      return this.currentRow.applyState !== 1
    },
    // 预约
    reservation() {
      const _this = this
      if (this.currentRow.applyState === 0) { // 只有未预约的才预约,else后面是改约
        this.$confirm(`确认是否预约?`, '预约', {
          beforeClose: function(action, instance, done) {
            if (action === 'confirm') {
              let updateModel = {
                isEmpty: _this.currentRow.isEmpty, // 是否空腹
                visitTypeId: _this.currentRow.visitTypeId, // 就诊类型
                queueId: _this.checkSource.queueId,  // 队列ID
                positionCount: _this.currentRow.positionCount, // 部位数
                reservationDate: _this.checkSource.examDate, // 改约日期
                reservationTimeSlot: _this.checkSource.timeSlot,  // 改约日期时间段
                id: _this.currentRow.id,  // 申请单ID
                sourceId: _this.checkSource.id,  // 号源ID,
                timeFrame: _this.checkSource.timeFrame
              }
              instance.confirmButtonLoading = true
              updateApply({
                ...updateModel,
                applyNum: _this.currentRow.applyNum,
                outExamItemName: _this.currentRow.outExamItemName
              }).then(res => {
                if (res.code === 200) {
                  this.$message.success('预约成功')
                  _this.initApplyList(_this.patientInfo.patientId, _this.currentRow.id)
                }
              }).finally(_ => {
                instance.confirmButtonLoading = false
                done()
              })
            } else {
              done()
            }
          }
        })
      } else {
        this.$confirm(`确认是否改约?`, '改约', {
          beforeClose: function(action, instance, done) {
            if (action === 'confirm') {
              let updateModel = {
                useReservationDate: _this.currentRow.reservationDate, // 已预约的号源日期
                useReservationTime: _this.currentRow.reservationTimeSlot, // 已使用的号源时间段
                isEmpty: _this.currentRow.isEmpty, // 是否空腹
                visitTypeId: _this.currentRow.visitTypeId, // 就诊类型
                queueId: _this.checkSource.queueId,  // 队列ID
                positionCount: _this.currentRow.positionCount, // 部位数
                reservationDate: _this.checkSource.examDate, // 改约日期
                reservationTimeSlot: _this.checkSource.timeSlot,  // 改约日期时间段
                id: _this.currentRow.id,  // 申请单ID
                sourceId: _this.checkSource.id,  // 号源ID,
                timeFrame: _this.checkSource.timeFrame
              }
              instance.confirmButtonLoading = true
              changeApply({
                ...updateModel,
                applyNum: _this.currentRow.applyNum,
                outExamItemName: _this.currentRow.outExamItemName,
                primaryDate: _this.currentRow.reservationDate + ' ' + _this.currentRow.reservationTimeSlot
              }).then(res => {
                if (res.code === 200) {
                  this.$message.success('改约成功')
                  _this.initApplyList(_this.patientInfo.patientId, _this.currentRow.id)
                  _this.clearSourceChecked()
                }
              }).finally(_ => {
                instance.confirmButtonLoading = false
                done()
              })
            } else {
              done()
            }
          }
        })
      }
    },
    // 取消预约
    cancel() {
      const _this = this
      this.$confirm(`确认是否取消预约?`, '取消预约', {
        beforeClose: function(action, instance, done) {
          if (action === 'confirm') {
            instance.confirmButtonLoading = true
            cancelApply({
              id: _this.currentRow.id,
              applyNum: _this.currentRow.applyNum,
              outExamItemName: _this.currentRow.outExamItemName,
              reservationDate: _this.currentRow.reservationDate,
              reservationTimeSlot: _this.currentRow.reservationTimeSlot
            })
              .then(res => {
                if (res.code === 200) {
                  this.$message.success('取消预约成功')
                  _this.initApplyList(_this.patientInfo.patientId, _this.currentRow.id)
                  _this.clearSourceChecked()
                }
              }).finally(_ => {
              instance.confirmButtonLoading = false
              done()
            })
          } else {
            done()
          }
        }
      })
    },
    // 清空号源选中逻辑数据
    clearSourceChecked() {
      this.checkDate = ''
      this.checkSourceList = []
      this.checkSource = {}
    }
  },
  created() {
    const { params } = this.$route
    if (!params || !params.from) {
      this.$router.go(-1)
    }
    const { from, patientId, applyIds } = params
    this.initDict()
    this.initPatientInfo(patientId, applyIds[0])
    this.initTimeList()
    this.$nextTick(() => {
      this.initApplyList(patientId, applyIds[0])
    })
  }
}
</script>

<style lang="scss" scoped>
.card {
  ::v-deep .el-card__body {
    padding: 5px;
  }

  ::v-deep .el-card__header {
    padding: 5px 5px 5px 20px;
    display: flex;
    align-items: center;
  }
}

.patient-card-body {
  display: flex;
  flex-wrap: wrap;

  .patient-card-body-item {
    display: flex;
    align-items: center;
    height: 30px;
    margin-right: 20px;

    .patient-card-body-item-title {
      color: silver;
      margin-right: 10px;
      width: 80px;
      font-size: 14px;
      line-height: 1.3;
      justify-content: flex-end;
      display: flex;
      align-items: center;
    }

    .patient-card-body-item-content {
      color: #303133;
      font-size: 16px;
      line-height: 1.3;
      justify-content: flex-start;
      display: flex;
      align-items: center;
    }
  }
}

.body {
  margin-top: 10px;
  //display: flex;

  .body-left {
    //width: 800px;
    margin-right: 10px;

    ::v-deep .cell-active {
      color: #ffffff !important;
      background-color: #409eff !important;
    }

    ::v-deep .el-table__row {
      cursor: pointer;
    }
  }

  .calendar {
    display: flex;
    flex-wrap: wrap;

    .calendar-item {
      min-width: 150px;
      border: 1px #e6ebf5 solid;
      margin: 8px;
      padding: 5px;
      min-height: 80px;
      border-radius: 8px;
      cursor: pointer;
      display: flex;
      flex-direction: column;
      justify-content: space-around;

      .calendar-item-source {
        display: flex;

        span {
          background-color: #00974f;
          border-radius: 50%;
          width: 21px;
          height: 21px;
          display: block;
          text-align: center;
          color: #ffffff;
          margin-right: 3px;
        }
      }

    }

    .active-item {
      background-color: #f2f8fe;
      color: #409eff;
    }

  }

  .source-list {
    .source-list-item {
      padding: 10px;
      display: flex;

      .item-left {
        width: 100px;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .item-right {
        flex: 1;
        display: flex;
        flex-wrap: wrap;

        .source-item {
          width: 230px;
          height: 30px;
          display: flex;
          align-items: center;
          justify-content: center;
          cursor: pointer;
          border: 1px #00964c solid;
          border-radius: 5px;
          margin: 5px;
          color: #00964c;
        }

        .source-item-active {
          background-color: #ecab00;
          color: #FFFFFF;
          border: none;
        }

        .source-item-disabled {
          cursor: not-allowed;
          background-color: #ededed;
          border: none;
          color: #7c7c7c;
        }
      }
    }
  }

}

</style>
