<template>
  <div class="table-page">
    <!--  四级路由切换  -->
    <page-route-tab />
    <div class="table-page-content">
      <div class="left-tree">
        <tree-side
          ref="treeSide"
          :dataLoading="treeLoading"
          :default-expand-all="false"
          :defaultProps="defaultProps"
          :tabList="['行政维度']"
          :treeData="treeData"
          isDeselect
          @currentChange="currentChange"
        ></tree-side>
      </div>
      <div class="right-table">
        <div class="full-page bg">
          <div class="search-box">
            <div class="search-box-combination">
              <div class="search-box-label">来电时间：</div>
              <div>
                <el-date-picker
                  v-model="dateRange"
                  end-placeholder="来电时间"
                  range-separator="至"
                  start-placeholder="来电时间"
                  style="width: 360px"
                  type="datetimerange"
                  format="yyyy-MM-dd HH:mm:ss"
                  value-format="yyyy-MM-dd HH:mm:ss"
                  :default-time="['00:00:00', '23:59:59']"
                  :clearable="false"
                  @change="datePickerChange"
                >
                </el-date-picker>
              </div>
              <SearchCommon :optionList="optionList" @search="handleSearch" />
            </div>
          </div>
          <div class="main-table-container">
            <div class="table-container" style="padding: 20px">
              <div ref="btnPanel" class="btn-box">
                <el-button
                  :disabled="isAddDisabled"
                  class="btn btn-plus"
                  icon="el-icon-plus"
                  size="small"
                  type="primary"
                  @click="AddData"
                >
                  添加
                </el-button>
                <el-button
                  :disabled="!currentDataDel.length"
                  :loading="btnLoading"
                  class="btn btn-delete"
                  icon="el-icon-delete"
                  plain
                  size="small"
                  type="danger"
                  @click="handleDelete()"
                >
                  删除
                </el-button>
                <el-button
                  :disabled="!hasChanges"
                  :loading="saveLoading"
                  class="btn btn-plus"
                  icon="el-icon-document-checked"
                  size="small"
                  type="primary"
                  @click="handleSave"
                >
                  保存
                </el-button>
                <el-button
                  :disabled="!tableData.length"
                  :loading="downloadLoading"
                  class="btn btn-delete"
                  icon="el-icon-download"
                  size="small"
                  type="warning"
                  @click="handleExport"
                >
                  导出
                </el-button>
              </div>
              <div ref="tableRef" class="table-content">
                <el-table
                  ref="multipleSelection"
                  v-loading="tableLoading"
                  :data="tableData"
                  :default-sort="getSorterDirection(params, true)"
                  :max-height="tableMaxHeight"
                  border
                  class="table-list"
                  element-loading-background="rgba(10 ,38 ,61, 0.9)"
                  row-key="id"
                  stripe
                  @select="handleSelection"
                  @selection-change="handleSelectionChange"
                >
                  <el-table-column align="center" type="selection" width="50" />
                  <el-table-column
                    align="center"
                    label="序号"
                    type="index"
                    width="60"
                  />
                  <!-- 动态列 -->
                  <el-table-column
                    v-for="col in currentColumns"
                    :key="col.prop"
                    :min-width="col.minWidth"
                    :prop="col.prop"
                    :show-overflow-tooltip="col.showOverflowTooltip"
                    :sortable="col.sortable"
                    align="center"
                  >
                    <template #header>
                      <span class="header-content">
                        <span
                          v-if="isFieldRequired(col.prop, true)"
                          class="required-asterisk"
                          >*</span
                        >
                        {{ col.title }}
                        <el-tooltip
                          v-if="isFieldRequired(col.prop)"
                          :content="getRuleConent(col.prop)"
                          placement="top"
                        >
                          <i class="el-icon-question"></i>
                        </el-tooltip>
                      </span>
                    </template>
                    <template v-slot="{row}">
                      <div :class="{'error-cell': isFieldError(row, col.prop)}">
                        <!-- 日期时间选择器 -->
                        <el-date-picker
                          v-if="
                            isEditing(row.id, col.prop) && col.type === 'date'
                          "
                          v-model="row[col.prop]"
                          :format="col.dateProps.format"
                          :value-format="col.dateProps['value-format']"
                          :type="col.dateProps.type"
                          placeholder="请选择"
                          style="width: 100%"
                          size="small"
                          :data-edit="`${row.id}-${col.prop}`"
                          @change="handleEditChange(row, col.prop, col.type)"
                          @blur="exitEdit"
                        />
                        <!-- 时间选择器 -->
                        <el-time-picker
                          v-else-if="
                            isEditing(row.id, col.prop) && col.type === 'time'
                          "
                          v-model="row[col.prop]"
                          :value-format="
                            col.timeProps['value-format'] || 'HH:mm:ss'
                          "
                          placeholder="请选择时间"
                          style="width: 100%"
                          size="small"
                          :data-edit="`${row.id}-${col.prop}`"
                          @change="handleEditChange(row, col.prop, col.type)"
                          @blur="exitEdit"
                        />
                        <!-- 其他输入组件 -->
                        <component
                          v-else-if="isEditing(row.id, col.prop) && col.type!=='text'"
                          :is="getEditComponent(col.type)"
                          v-model="row[col.prop]"
                          v-bind="getEditProps(col)"
                          :data-edit="`${row.id}-${col.prop}`"
                          @blur="exitEdit"
                          @keyup.enter="exitEdit"
                          @keyup.esc="exitEdit"
                          @change="handleEditChange(row, col.prop, col.type)"
                        />
                        <!-- 显示状态 -->
                        <template v-else>
                          <span
                            :class="[
                              'cell-content',
                              getStatusStyle(col.prop, row[col.prop], col)
                            ]"
                            :style="{
                              cursor: col.type && col.type!=='text' ? 'pointer' : 'default'
                            }"
                            @click="
                              col.type && startEdit(row, row.id, col.prop)
                            "
                          >
                            {{ formatCellValue(row, col) }}
                          </span>
                        </template>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column
                    align="center"
                    label="操作"
                    min-width="80"
                    fixed="right"
                    show-overflow-tooltip
                  >
                    <template v-slot="{row}">
                      <el-link
                        :disabled="btnLoading"
                        :underline="false"
                        type="danger"
                        @click="handleDelete(row)"
                      >
                        删除
                      </el-link>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import PageRouteTab from '@/components/PageRouteTab/index.vue'
import {TableMixin} from '@/mixins/tableMixin'
import SearchCommon from '@/components/SearchCommon/index.vue'
import PubSub from 'pubsub-js'
import {
  getSorterDirection,
  refineRequestBody,
  setQueryValue
} from '@/utils/requestWrappers'
import {dictionaryEscape} from '@/utils/dictionary'
import {
  tableData,
  tableSave,
  tableDelete,
  exportData
} from '@/api/patrolAndRescue/commandDispatch/reportManagement/callInquiryRecords.js'
import treeSide from '@/components/treeSide/index.vue'
import {getTree} from '@/api/tree'
import moment from 'moment'

export default {
  name: 'TablePage',
  components: {
    PageRouteTab,
    treeSide,
    SearchCommon
  },
  mixins: [TableMixin],
  data() {
    return {
      pubSub: null,
      tableMaxHeight: '600px',
      tableLoading: true,
      btnLoading: false,
      treeLoading: true,
      downloadLoading: false,
      treeItem: {},
      treeData: [], //左边树
      dateRange: [
        moment()
          .subtract(7, 'days')
          .startOf('day')
          .format('YYYY-MM-DD HH:mm:ss'),
        moment()
          .endOf('day')
          .format('YYYY-MM-DD HH:mm:ss')
      ],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      // 编辑状态管理
      editingCell: null,
      hasChanges: false,
      saveLoading: false,
      tableData: [],
      optionList: [
        {title: '来电单位/个人', prop: 'caller', type: 'input', default: true},
        {title: '来电号码', prop: 'callerNumber', type: 'input'},
        {title: '咨询事项', prop: 'consultationContent', type: 'input'},
        {title: '答复情况', prop: 'replyContent', type: 'input'},
        {title: '记录人', prop: 'recorder', type: 'input'}
      ],
      params: {
        pageBean: {pageSize: -1, page: 1, total: 0},
        querys: [
          {operation: 'IN', property: 'roadSegmentId'},
          {operation: 'BETWEEN', property: 'recordDateTime'},
          {operation: 'LIKE', property: 'caller'},
          {operation: 'LIKE', property: 'callerNumber'},
          {operation: 'LIKE', property: 'recorder'},
          {operation: 'LIKE', property: 'consultationContent'},
          {operation: 'LIKE', property: 'replyContent'}
        ],
        sorter: [
          {direction: 'DESC', property: 'recordDateTime'},
          {direction: 'DESC', property: 'createTime'}
        ]
      },
      isAddDisabled: true,
      // 列配置
      currentColumns: [
        {
          prop: 'roadSegmentName',
          title: '路段名称',
          minWidth: 120,
          type: 'text',
        },
        {
          prop: 'recordDateTime',
          title: '来电时间',
          minWidth: 160,
          type: 'date',
          dateProps: {
            type: 'datetime',
            format: 'yyyy-MM-dd HH:mm:ss',
            'value-format': 'yyyy-MM-dd HH:mm:ss'
          }
        },
        {
          prop: 'caller',
          title: '来电单位/个人',
          minWidth: 160,
          type: 'input',
          showOverflowTooltip: false
        },
        {
          prop: 'callerNumber',
          title: '来电号码',
          minWidth: 120,
          type: 'input',
          showOverflowTooltip: false
        },
        {
          prop: 'consultationContent',
          title: '咨询事项',
          minWidth: 160,
          type: 'textarea',
          showOverflowTooltip: false
        },
        {
          prop: 'replyContent',
          title: '答复情况',
          minWidth: 160,
          type: 'textarea',
          showOverflowTooltip: false
        },
        {
          prop: 'recorder',
          title: '记录人',
          minWidth: 120,
          type: 'input',
          min: 0,
          showOverflowTooltip: false
        },
        {
          prop: 'remark',
          title: '备注',
          type: 'textarea',
          minWidth: 100,
          min: 0,
          showOverflowTooltip: false
        }
      ],
      fieldRules: {
        recordDateTime: [
          {required: true, message: '请选择来电时间', trigger: 'blur'}
        ],
        caller: [
          {required: true, message: '请输入来电单位/个人', trigger: 'blur'}
        ],
        callerNumber: [
          {
            validate: (rule, value, callback) => {
              if (value && !/^(1[3-9]\d{9}|(\d{3,4}-)?\d{7,8})$/.test(value)) {
                callback(new Error('请输入正确的手机号或座机号'))
              } else {
                callback()
              }
            },
            message: '请输入正确的手机号或座机号',
            trigger: 'blur'
          }
        ],
        consultationContent: [
          {required: true, message: '请输入咨询事项', trigger: 'blur'}
        ],
        replyContent: [
          {required: true, message: '请输入答复情况', trigger: 'blur'}
        ],
        recorder: [{required: true, message: '请输入记录人', trigger: 'blur'}]
      }
    }
  },
  created() {
    // 获取树形目录
    this.getOrgTreeData(treeData => {
      // 回调中默认选中第一项并将其id作为参数请求表格
      this.treeItem = treeData[0] || {}
      let array = []
      if (this.treeItem.children.length > 0) {
        array = this.extractIds(this.treeItem)
      }
      this.$nextTick(_ => {
        this.$refs.treeSide?.setCurrentKey(treeData[0]?.id)
        this.$refs.treeSide?.expandHandle(true, 2)
      })
      setQueryValue(this.params, 'roadSegmentId', array)
      setQueryValue(this.params, 'recordDateTime', this.dateRange)
      this.loadData()
    })
  },
  mounted() {
    this.pubSub = PubSub.subscribe('TablePage', (_, data) => {
      switch (data.type) {
        case 'add':
          this.handleCurrentChange(1)
          break
        case 'edit':
          this.loadData()
          break
      }
    })
  },
  methods: {
    // 时间范围切换
    datePickerChange(val) {
      if (!val || val.length === 0) {
        setQueryValue(this.params, 'recordDateTime', '')
      } else {
        setQueryValue(this.params, 'recordDateTime', val)
      }
      this.params.pageBean.page = 1
      this.loadData()
    },
    // 判断单元格是否处于编辑状态
    isEditing(rowId, field) {
      return (
        this.editingCell?.rowId === rowId && this.editingCell?.field === field
      )
    },

    // 开始编辑
    startEdit(row, rowId, field) {
      this.editingCell = {rowId, field}
      this.$nextTick(() => {
        const editInput =
          this.$el.querySelector(
            `[data-edit="${rowId}-${field}"] .el-input__inner`
          ) || this.$el.querySelector(`[data-edit="${rowId}-${field}"]`)
        if (editInput) {
          editInput.focus()
        }
      })
    },

    // 退出编辑
    exitEdit() {
      this.editingCell = null
    },

    // 获取编辑组件类型
    getEditComponent(type) {
      const componentMap = {
        input: 'el-input',
        number: 'el-input-number',
        select: 'el-select',
        textarea: 'el-input',
        time: 'el-time-picker'
      }
      return componentMap[type] || 'el-input'
    },

    // 获取编辑组件属性
    getEditProps(col) {
      const props = {
        size: 'small',
        placeholder: `请输入${col.title}`
      }

      if (col.type === 'number') {
        props.min = col.min || 0
        props.max = col.max
        props.precision = col.precision
      }

      if (col.type === 'textarea') {
        props.type = 'textarea'
        props.rows = 8
      }

      if (col.type === 'select' && col.options) {
        props.options = col.options
      }

      if (col.type === 'time') {
        props.placeholder = '请选择时间'
      }

      return props
    },

    // 处理编辑值变化
    handleEditChange(row, field, type) {
      // 标记有变化
      this.hasChanges = true
    },

    // 字段验证
    validateField(row, field) {
      const rules = this.fieldRules[field]
      if (!rules) return true

      const value = row[field]
      for (const rule of rules) {
        if (rule.required && (!value || value.toString().trim() === '')) {
          return false
        }
      }
      return true
    },

    // 保存数据
    async handleSave() {
      try {
        this.saveLoading = true

        // 校验所有数据
        let errorCount = 0
        let firstError = ''

        for (const row of this.tableData) {
          for (const field in this.fieldRules) {
            const rules = this.fieldRules[field]
            const value = row[field]
            
            // 处理必填字段校验
            if (
              rules &&
              rules[0].required &&
              (!value || value.toString().trim() === '')
            ) {
              errorCount++
              if (!firstError) {
                firstError = `第${this.tableData.indexOf(row) + 1}行: ${
                  rules[0].message
                }`
              }
            }
            
            // 处理自定义校验规则（如callerNumber）
            if (rules && rules[0].validate && value) {
              try {
                rules[0].validate(null, value, (error) => {
                  if (error) {
                    errorCount++
                    if (!firstError) {
                      firstError = `第${this.tableData.indexOf(row) + 1}行: ${error.message}`
                    }
                  }
                })
              } catch (e) {
                // 如果校验函数抛出异常，也认为校验失败
                errorCount++
                if (!firstError) {
                  firstError = `第${this.tableData.indexOf(row) + 1}行: ${rules[0].message}`
                }
              }
            }
          }
        }

        if (errorCount > 0) {
          const message =
            errorCount > 1 ? `${firstError}等${errorCount}个错误` : firstError
          this.$message.error(`数据校验失败：${message}`)
          return
        }

        // 处理新增数据，删除临时id字段
        const saveData = this.tableData.map(row => {
          if (row._id) {
            // 新增数据，删除id和_id字段
            const {id, _id, ...newRow} = row
            return newRow
          }
          return row
        })

        // 这里可以调用保存API
        const {state, message = ''} = await tableSave(saveData)
        if (state) {
          this.$message.success('保存成功')
          this.hasChanges = false
          this.loadData()
        } else {
          this.$message.warning(message || '保存失败')
        }
      } catch (error) {
        this.$message.error(error.message || '保存失败')
      } finally {
        this.saveLoading = false
      }
    },

    async handleExport() {
      try {
        this.downloadLoading = true
        await exportData(refineRequestBody(this.params))
      } catch (error) {
        this.$message.error(error.message || '导出失败')
      } finally {
        this.downloadLoading = false
      }
    },

    // 添加数据
    AddData() {
      if (!this.treeItem.id) {
        this.$message.error('请选择路段')
        return
      }
      // 创建新的空行数据
      const newRow = {
        id: Date.now(), // 使用时间戳作为临时ID
        _id: Date.now(),
        recordDateTime: moment().format('YYYY-MM-DD HH:mm:ss'),
        caller: '',
        consultationContent: '',
        replyContent: '',
        recorder: '',
        remark: '',
        roadSegmentId: this.treeItem.id || '',
        roadSegmentName: this.treeItem.name || '',
        companyId: this.treeItem.companyId || '',
        companyIds: this.treeItem.companyIds || '',
        companyName: this.treeItem.companyName || ''
      }
      this.tableData.unshift(newRow)
      this.hasChanges = true
    },

    // 格式化单元格显示值
    formatCellValue(row, col) {
      const value = row[col.prop]
      if (value === null || value === undefined || value === '') {
        return '-'
      }

      // 根据列类型格式化显示
      if (col.type === 'date' && value) {
        return value
      }

      return value
    },

    // 获取状态样式
    getStatusStyle(prop, value, col) {
      // 可以根据字段和值返回不同的样式类
      if (col.type === 'textarea' && value) {
        return 'pre-row'
      } else {
        return ''
      }
    },

    // 判断字段是否有错误
    isFieldError(row, field) {
      if (!this.isFieldRequired(field)) return false
      const rules = this.fieldRules[field]
      const value = row[field]
      
      // 处理必填字段校验
      if (rules && rules[0].required && (!value || value.toString().trim() === '')) {
        return true
      }
      
      // 处理自定义校验规则（如callerNumber）
      if (rules && rules[0].validate && value) {
        let hasError = false
        try {
          rules[0].validate(null, value, (error) => {
            if (error) {
              hasError = true
            }
          })
        } catch (e) {
          hasError = true
        }
        return hasError
      }
      
      return false
    },
    isFieldRequired(field, required = false) {
      if (required) {
        return (
          Object.keys(this.fieldRules).includes(field) &&
          this.fieldRules[field][0].required
        )
      } else {
        return Object.keys(this.fieldRules).includes(field)
      }
    },
    getRuleConent(field) {
      return this.fieldRules[field]?.[0]?.message || ''
    },
    dictionaryEscape,
    getSorterDirection,
    extractIds(node) {
      let ids = []
      // 如果当前节点有 children，则递归提取
      if (node.children) {
        ids = node.children.map(child => child.id) // 提取当前节点的 id
        // 递归提取子节点的 id
        node.children.forEach(child => {
          ids = ids.concat(this.extractIds(child))
        })
      }
      return ids
    },
    // 获取路段树
    async getOrgTreeData(callback) {
      try {
        this.treeLoading = true
        let {value} = await getTree()
        this.treeData = [value]
      } finally {
        this.treeLoading = false
        callback && callback(this.treeData)
      }
    },
    //左边树节点
    currentChange(nodeItem) {
      if (nodeItem.id === '1766017468444450816') {
        this.isAddDisabled = true
        setQueryValue(this.params, 'roadSegmentId', this.extractIds(nodeItem))
      } else if (nodeItem.children && nodeItem.children.length > 0) {
        this.isAddDisabled = true
        const array = nodeItem.children.map(item => item.id)
        setQueryValue(this.params, 'roadSegmentId', array)
      } else {
        this.isAddDisabled = false
        setQueryValue(this.params, 'roadSegmentId', [nodeItem?.id] || [])
      }

      this.params.pageBean.page = 1
      this.calcTableHeight(500)
      this.treeItem = nodeItem || {}
      this.loadData()
    },

    //获取数据
    async loadData() {
      try {
        this.tableLoading = true
        const {total = 0, rows = []} = await tableData(
          refineRequestBody(this.params)
        )
        this.params.pageBean.total = total
        this.tableData = rows.map(i => ({
          ...i
        }))
        this.hasChanges = false
        // 让表格回到顶部
        this.$nextTick(() => {
          const tableEl = this.$el.querySelector('.el-table__body-wrapper')
          if (tableEl) {
            tableEl.scrollTop = 0
          }
        })
      } finally {
        this.tableLoading = false
      }
    },

    // 删除
    handleDelete(row) {
      this.clickTimer = true
      setTimeout(_ => (this.clickTimer = false))
      this.$confirm('确定删除选中的来电咨询记录吗？', '提示', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
          this.btnLoading = true
          let ids = row ? row.id : this.currentDataDel.join()
          try {
            const {state} = await tableDelete(ids)
            if (state) {
              this.$message.success(`来电咨询记录删除成功`)
              const {page, pageSize, total} = this.params.pageBean
              const totalPages = Math.ceil(total / pageSize) // 计算总页数
              if (totalPages > 1 && page === totalPages) {
                if (this.tableData.length === 1) {
                  // 当前页只有一条数据
                  this.params.pageBean.page -= 1 // 返回前一页
                }
              }
              await this.loadData()
            }
          } finally {
            this.btnLoading = false
          }
        })
        .catch(_ => _)
    }
  },
  beforeDestroy() {
    // 在组件销毁之前 清除订阅消息
    PubSub.unsubscribe(this.pubSub)
  }
}
</script>

<style lang="scss" scoped>
.table-page {
  .basis {
    min-width: 240px !important;
  }
}

.cell-content {
  display: inline-block;
  width: 100%;
  min-height: 20px;
  font-size: 14px;
}

.pre-row.cell-content {
  white-space: pre-line;
  text-align: left;
  margin-top: -20px;
}

.error-cell {
  border: 1px solid #f56c6c !important;
  border-radius: 4px;
  padding: 2px;
  background-color: transparent;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;

  .el-input,
  .el-input-number,
  .el-date-picker,
  .el-time-picker {
    width: 100%;
  }
}

.header-content {
  .required-asterisk {
    color: #f56c6c;
    margin-right: 4px;
  }

  .el-icon-question {
    margin-left: 4px;
    font-size: 14px;
    color: #e6a23c;
    cursor: help;
  }
}
</style>
