<template>
  <div v-if="pattern == 'schedule'">
    <a-table
      :columns="columns"
      :data-source="data"
      :rowSelection="rowSelection"
      :scroll="{ y: configData.height == null? '70%' : configData.height }">
      <span slot="time" class="time-title">
        <span v-for="(item, index) in configData.timePeriod" :key="index">{{ item }}</span>
      </span>
      <div v-for="(item, index) in weekDays" :key="index" :slot="item.key" class="week_last_next_btn">
        <a-button slot="lastWeek" icon="left" size="large" @click="handleLastWeek" v-if="item.title == '周一'" />
        <div class="time-title">
          <span>{{ item.title }}</span>
          <span>{{ currentWeekDates[index].toLocaleDateString() }}</span>
        </div>
        <a-button slot="nextWeek" icon="right" size="large" @click="handleNextWeek" v-if="item.title == '周日'"/>
      </div>
      <template :slot="day.key" slot-scope="text, record" v-for="day in shiftTable">
        <div class="time-title" :key="day.key">
          <a-button v-for="(item, index) in record[day.key]" :key="index" @click="handleShiftChange(day.key, index, record)">{{ item === 1 || item === '1' ? '坐诊' : '休息' }}</a-button>
        </div>
      </template>
      <template slot="sk_limit" slot-scope="text, record">
        <a-input-number id="inputNumber" v-model="record.sk_limit" :min="configData.sk_limitMin" :max="configData.sk_limitMax" />
      </template>
    </a-table>
  </div>
  <div v-else-if="pattern == 'form'">
    <a-table :columns="columns" :data-source="data" :row-selection="rowSelection" bordered :scroll="{ y: configData.height == null? '70%' : configData.height }">
      <template v-for="(n, i) in inputColumns" :slot="n.dataIndex" slot-scope="text, record">
        <div class="a-div" :key="i">
          <a-input
            v-for="(item, index) in (Array.isArray(n.row) ? n.row : Array(Number(n.row) || 1).fill(1))"
            :key="index"
            placeholder=""
            class="ant-input"
            v-model="record[n.dataIndex][index + 1]"
            @input="handleInputChange(record, n.dataIndex, index + 1, $event.target.value)"
            :disabled="!isRowSelected(record.key)"/>
        </div>
      </template>
      <div class="a-div" v-for="(n, i) in numberColumns" :slot="n.dataIndex" :key="i">
        <div v-for="(item, index) in n.row" :key="index" class="number">{{ item }}</div>
      </div>
    </a-table>
  </div>
</template>
<script>
import { getConfigByName, runLogic } from '@vue2-client/services/api/common'

export default {
  data () {
    return {
      // 高度
      height: '70%',
      // 输入框数据
      inputData: [],
      // 模式
      pattern: 'schedule',
      data: [],
      // 列配置
      columns: [],
      // 列名
      columnNames: [],
      // 选中的行键值集合
      selectedRows: [],
      // 选中的行信息集合
      selectedRowKeys: [],
      // 原始数据备份
      originalData: [],
      // 配置参数
      configData: {},
      // 当前显示的周次日期
      currentWeekDates: [],
      weekDays: [...['周一', '周二', '周三', '周四', '周五', '周六', '周日'].map((title, index) => {
        const key = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'][index]
        return { title, key }
      })],
      // 排班时间表
      shiftTable: [...['周一', '周二', '周三', '周四', '周五', '周六', '周日'].map((title, index) => {
          const key = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'][index]
          return {
            key, dataIndex: key, scopedSlots: { customRender: key }, slots: { title: key }, align: 'center', width: key === 'Monday' || key === 'Sunday' ? 170 : 120
          }
        }),
        {
          title: '排班数',
          key: 'sk_limit',
          dataIndex: 'sk_limit',
          scopedSlots: { customRender: 'sk_limit' },
          align: 'center'
        }
      ]
    }
  },
  props: {
    // 配置名
    queryParamsName: {
      type: String,
      default: ''
    },
    // 服务名
    serviceName: {
      type: String,
      default: 'af-his'
    }
  },
  computed: {
    rowSelection () {
      return {
        selectedRowKeys: this.selectedRowKeys,
        onChange: (selectedRowKeys, selectedRows) => {
          this.onSelectChange(selectedRowKeys, selectedRows)
        }
      }
    },
    inputColumns () {
      return this.columns.filter(col => col.type === 'input')
    },
    numberColumns () {
      return this.columns.filter(col => col.type === 'number')
    }
  },
  mounted () {
    this.initWeekDates()
  },
  methods: {
    handleShiftChange (day, index, record) {
      // 找到当前记录在data中的索引
      const dataIndex = this.data.findIndex(item => item.id === record.id)
      if (dataIndex === -1) return
      // 获取当前状态
      const currentValue = record[day][index]
      const newValue = currentValue === 1 || currentValue === '1' ? 0 : 1
      // 更新按钮显示
      this.$set(record[day], index, newValue)
      // 同步更新data中的数据
      this.$set(this.data[dataIndex][day], index, newValue)
    },
    onSelectChange (selectedRowKeys, selectedRows) {
      this.selectedRowKeys = selectedRowKeys
      this.selectedRows = selectedRows
    },
    // 处理输入框数据变化
    handleInputChange (record, field, index, value) {
      // 更新数据
      this.$set(record[field], index, value)
    },
    // 获取选中的行数据
    getSelectedRowData () {
      if (this.pattern === 'form') {
        // 在form模式下，返回包含输入框数据的完整信息
        return this.selectedRows.map(row => {
          const result = { ...row }
          // 将对象格式的输入框数据转换为数组格式
          this.inputColumns.forEach(col => {
            if (row[col.dataIndex] && typeof row[col.dataIndex] === 'object') {
              const fieldData = row[col.dataIndex]
              const arrayData = []
              // 将对象转换为数组，保持键的顺序
              Object.keys(fieldData).forEach(key => {
                arrayData.push(fieldData[key])
              })
              result[col.dataIndex] = arrayData
            }
          })
          return result
        })
      }
      return this.selectedRows
    },
    // 获取全部数据
    getAllTable () {
      return this.data
    },
    // 初始化数据
    async init (queryParamsName, parameter) {
      // 重置选中行
      this.selectedRows = []
      // 重置数据
      this.data = []
      getConfigByName(queryParamsName, this.serviceName, result => {
        this.configData = result
        runLogic(result.dataSource, parameter, this.serviceName).then(res => {
          this.columns = []
          this.columns = JSON.parse(JSON.stringify(this.configData.columns))
          this.pattern = result.pattern
          if (this.pattern == 'schedule') {
            for (let i = 0; i < this.shiftTable.length; i++) {
              this.columns.push(this.shiftTable[i])
            }
            if (res && Array.isArray(res)) {
              const weekDays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
              const shifts = ['am', 'pm', 'evening']
              let key = 0
              this.data = res.map(item => {
                const scheduleData = {
                  key: key++
                }
                this.configData.columnsName.forEach(columnName => { scheduleData[columnName] = item[columnName] })
                weekDays.forEach(day => {
                  scheduleData[day.charAt(0).toUpperCase() + day.slice(1)] = shifts.map(shift => item[`f_${day}_${shift}`] === '1' ? 1 : 0)
                })
                return scheduleData
              })
              // 保存原始数据
              this.originalData = JSON.parse(JSON.stringify(this.data))
            }
          } else if (this.pattern == 'form') {
            const inputFields = this.configData.columns.filter(col => col.type === 'input').map(col => col.dataIndex)

            // 处理项目数据，将参数数据关联到对应的项目
            this.data = res.project.map((projectItem, index) => {
              const newItem = {
                ...projectItem,
                key: projectItem.id || `form_row_${index}_${Date.now()}` // 确保每行有唯一的key
              }

              // 查找当前项目对应的参数数据
              const projectParameters = res.parameter.filter(param => param.id === projectItem.id)
              const parameterByMaterialId = new Map(projectParameters.map(p => [p.material_id, p]))

              inputFields.forEach(field => {
                const column = this.configData.columns.find(col => col.dataIndex === field)
                if (column && column.type === 'input' && column.row) {
                  const rowCount = Array.isArray(column.row) ? column.row.length : Number(column.row) || 1 // 支持数字或数组
                  // 创建对象格式的数据，键为1,2,3...，值为空字符串
                  const fieldData = {}
                  for (let i = 1; i <= rowCount; i++) {
                    const matchedParam = parameterByMaterialId.get(i)
                    // 如果有对应的参数数据，则填充对应的值
                    if (matchedParam) {
                      // 根据字段名映射到参数数据中的对应字段
                      let paramValue = ''
                      switch (field) {
                        case 'targetValue':
                          paramValue = matchedParam.target_value || ''
                          break
                        case 'SD':
                          paramValue = matchedParam.sd || ''
                          break
                        case 'reagent':
                          paramValue = matchedParam.reagent || ''
                          break
                        case 'wavelength':
                          paramValue = matchedParam.wavelength || ''
                          break
                        case 'method':
                          paramValue = matchedParam.method || ''
                          break
                        case 'batchNumber':
                          paramValue = matchedParam.lot_number || ''
                          break
                        default:
                          paramValue = matchedParam[field] || ''
                      }
                      fieldData[i] = paramValue
                    } else fieldData[i] = ''
                  }
                  newItem[field] = fieldData
                } else {
                  newItem[field] = projectItem[field] || ''
                }
              })
              return newItem
            })
            // 备份原始数据以便筛选/重置使用
            this.originalData = JSON.parse(JSON.stringify(this.data))
          }
        })
      })
    },
    // 查询数据函数
    filterTableData (filters) {
      if (!filters || Object.keys(filters).length === 0) {
        // 如果没有过滤条件，恢复原始数据
        this.data = JSON.parse(JSON.stringify(this.originalData))
        return
      }
      // 从原始数据开始过滤
      this.data = this.originalData.filter(item => {
        // 检查每一项是否满足所有过滤条件
        return Object.entries(filters).every(([key, value]) => {
          // 如果过滤值是字符串，进行模糊匹配
          if (typeof value === 'string') {
            return item[key] && item[key].toString().toLowerCase().includes(value.toLowerCase())
          }
          // 如果过滤值是数字，进行精确匹配
          return item[key] === value
        })
      }).map((item, index) => ({
        ...item,
        key: item.key || item.id || `filtered_row_${index}_${Date.now()}` // 确保过滤后的数据也有唯一key
      }))
    },
    // 初始化周次日期
    initWeekDates () {
      const today = new Date()
      const currentDay = today.getDay() || 7 // 将周日的0转换为7
      const monday = new Date(today)
      monday.setDate(today.getDate() - currentDay + 1) // 设置为本周一
      this.currentWeekDates = Array.from({ length: 7 }, (_, index) => {
        const date = new Date(monday)
        date.setDate(monday.getDate() + index)
        return date
      })
    },
    // 切换到上一周
    handleLastWeek () {
      const monday = new Date(this.currentWeekDates[0])
      monday.setDate(monday.getDate() - 7)
      this.updateWeekDates(monday)
    },
    // 切换到下一周
    handleNextWeek () {
      const monday = new Date(this.currentWeekDates[0])
      monday.setDate(monday.getDate() + 7)
      this.updateWeekDates(monday)
    },
         // 更新周次日期
     updateWeekDates (monday) {
       this.currentWeekDates = Array.from({ length: 7 }, (_, index) => {
         const date = new Date(monday)
         date.setDate(monday.getDate() + index)
         return date
       })
     },
     // 判断某行是否被选中
     isRowSelected (rowKey) {
       return this.selectedRowKeys.includes(rowKey)
     }
  },
  watch: {
    queryParamsName: {
      handler (newValue) {
        this.init(newValue)
      },
      deep: true,
      immediate: true
    }
  }
}
</script>

<style scoped>
.time-title {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
}
.week_last_next_btn {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 16px;
}
::v-deep .ant-table-thead > tr > th,
::v-deep .ant-table-tbody > tr > td {
  padding: 8px 16px !important;
  overflow-wrap: break-word;
}
.ant-input {
  width: 100%;
}
.ant-input[disabled] {
  background-color: #f5f5f5;
  color: #999;
  cursor: not-allowed;
}
.a-div{
  display: flex;
  flex-direction: column;
}
.number{
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-variant: tabular-nums;
  list-style: none;
  font-feature-settings: 'tnum';
  position: relative;
  display: inline-block;
  width: 100%;
  height: 32px;
  padding: 4px 11px;
  color: rgba(0, 0, 0, 0.65);
  font-size: 14px;
  line-height: 1.5;
  background-image: none;
  border-radius: 4px;
  transition: all 0.3s;
}
</style>
