<template>
  <el-dialog
    title="腾讯文档推送监控"
    :visible="visible"
    @update:visible="handleVisibleChange"
    :width="isMobile ? '100%' : '1200px'"
    :close-on-click-modal="false"
    @close="handleClose"
    :top="isMobile ? '0' : '5vh'"
    :fullscreen="isMobile"
    :custom-class="isMobile ? 'mobile-push-monitor-dialog' : ''"
    :modal-append-to-body="true"
    :append-to-body="true"
  >
    <div class="push-monitor">
      <!-- 倒计时和状态卡片 -->
      <el-card class="countdown-card" shadow="hover">
        <div class="countdown-header">
          <div class="header-left">
            <i class="el-icon-timer"></i>
            <span class="title">自动推送倒计时</span>
          </div>
          <div class="header-right">
            <el-tag v-if="pushStatus.isScheduled" type="warning" size="medium">
              <i class="el-icon-loading"></i> 等待推送中
            </el-tag>
            <el-tag v-else type="info" size="medium">
              <i class="el-icon-circle-check"></i> 无待推送任务
            </el-tag>
          </div>
        </div>

        <div class="countdown-content">
          <div class="countdown-display" :class="{active: pushStatus.isScheduled}">
            <div class="time-box">
              <span class="time-value">{{ countdownDisplay.minutes }}</span>
              <span class="time-label">分</span>
            </div>
            <span class="time-separator">:</span>
            <div class="time-box">
              <span class="time-value">{{ countdownDisplay.seconds }}</span>
              <span class="time-label">秒</span>
            </div>
          </div>

          <div class="countdown-info">
            <div v-if="pushStatus.scheduledTime" class="info-item">
              <i class="el-icon-time"></i>
              <span>预计推送时间：{{ formatDateTime(pushStatus.scheduledTime) }}</span>
            </div>
            <div v-if="pushStatus.lastSuccessRecord" class="info-item">
              <i class="el-icon-success"></i>
              <span>上次推送：{{ formatDateTime(pushStatus.lastSuccessRecord.endTime) }}</span>
              <el-tag size="mini" type="success" style="margin-left: 10px;">
                成功 {{ pushStatus.lastSuccessRecord.successCount }} 条
              </el-tag>
            </div>
          </div>

          <div class="countdown-actions">
            <el-button 
              type="primary" 
              icon="el-icon-upload2" 
              :loading="pushing"
              :size="isMobile ? 'small' : 'default'"
              @click="handleTriggerPushNow"
            >
              立即推送
            </el-button>
            <el-button 
              type="warning" 
              icon="el-icon-close" 
              :disabled="!pushStatus.isScheduled"
              :size="isMobile ? 'small' : 'default'"
              @click="handleCancelPush"
            >
              取消推送
            </el-button>
            <el-button 
              icon="el-icon-refresh" 
              :size="isMobile ? 'small' : 'default'"
              @click="loadPushStatus"
            >
              刷新状态
            </el-button>
          </div>
        </div>
      </el-card>

      <!-- 推送记录列表 -->
      <el-card class="records-card" shadow="hover">
        <div slot="header" class="records-header">
          <div class="header-left">
            <i class="el-icon-document-copy"></i>
            <span class="title">推送记录</span>
            <el-tag size="mini" type="info" style="margin-left: 10px;">
              共 {{ batchRecords.length }} 条
            </el-tag>
          </div>
          <div class="header-right">
            <el-button type="text" icon="el-icon-refresh" @click="loadBatchRecords">刷新</el-button>
          </div>
        </div>

        <el-timeline v-if="batchRecords.length > 0">
          <el-timeline-item
            v-for="record in batchRecords"
            :key="record.batchId"
            :timestamp="formatDateTime(record.createTime)"
            placement="top"
            :type="getRecordType(record.status)"
            :icon="getRecordIcon(record.status)"
          >
            <el-card class="record-item" shadow="hover">
              <div class="record-summary" @click="toggleRecordDetail(record.batchId)">
                <div class="summary-left">
                  <el-tag :type="getStatusTagType(record.status)" size="small">
                    {{ getStatusText(record.status) }}
                  </el-tag>
                  <span class="trigger-source">
                    {{ getTriggerSourceText(record.triggerSource) }}
                  </span>
                  <span class="record-stats">
                    <i class="el-icon-check" style="color: #67c23a;"></i> {{ record.successCount }}
                    <i class="el-icon-remove-outline" style="color: #e6a23c; margin-left: 10px;"></i> {{ record.skipCount }}
                    <i class="el-icon-close" style="color: #f56c6c; margin-left: 10px;"></i> {{ record.errorCount }}
                  </span>
                </div>
                <div class="summary-right">
                  <span class="record-range">行 {{ record.startRow }} - {{ record.endRow }}</span>
                  <span v-if="record.durationMs" class="record-duration">
                    耗时 {{ formatDuration(record.durationMs) }}
                  </span>
                  <i :class="expandedRecords.includes(record.batchId) ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
                </div>
              </div>

              <!-- 详情展开区域 -->
              <el-collapse-transition>
                <div v-if="expandedRecords.includes(record.batchId)" class="record-detail">
                  <el-divider></el-divider>
                  
                  <!-- 加载状态 -->
                  <div v-if="record.loadingDetail" class="loading-detail" v-loading="true" element-loading-text="正在加载详情...">
                    <div style="height: 100px;"></div>
                  </div>

                  <template v-else>
                    <div v-if="record.resultMessage" class="detail-message">
                      <div class="message-label">结果消息：</div>
                      <div class="message-content">{{ record.resultMessage }}</div>
                    </div>

                    <div v-if="record.errorMessage" class="detail-error">
                      <div class="error-label">错误信息：</div>
                      <div class="error-content">{{ record.errorMessage }}</div>
                    </div>

                    <!-- 操作日志列表 -->
                    <div v-if="record.operationLogs && record.operationLogs.length > 0" class="operation-logs">
                    <div class="logs-header">
                      <i class="el-icon-document"></i>
                      <span>操作日志（{{ record.operationLogs.length }} 条）</span>
                    </div>
                    <el-table
                      :data="record.operationLogs"
                      size="mini"
                      max-height="300"
                      stripe
                    >
                      <el-table-column prop="orderNo" label="订单号" width="150" />
                      <el-table-column prop="operationType" label="操作类型" width="100" />
                      <el-table-column prop="targetRow" label="目标行" width="80" />
                      <el-table-column prop="logisticsLink" label="物流链接" min-width="150" show-overflow-tooltip />
                      <el-table-column prop="operationStatus" label="状态" width="80">
                        <template slot-scope="scope">
                          <el-tag :type="scope.row.operationStatus === 'SUCCESS' ? 'success' : 'danger'" size="mini">
                            {{ scope.row.operationStatus }}
                          </el-tag>
                        </template>
                      </el-table-column>
                      <el-table-column prop="errorMessage" label="错误信息" min-width="150" show-overflow-tooltip />
                    </el-table>
                  </div>

                    <!-- 暂无操作日志 -->
                    <div v-else class="no-logs">
                      <i class="el-icon-info"></i>
                      <span>暂无操作日志</span>
                    </div>
                  </template>
                </div>
              </el-collapse-transition>
            </el-card>
          </el-timeline-item>
        </el-timeline>

        <el-empty v-else description="暂无推送记录"></el-empty>
      </el-card>
    </div>
  </el-dialog>
</template>

<script>
import {
  getPushStatus,
  getBatchPushRecords,
  getBatchPushRecordDetail,
  triggerPushNow,
  cancelPendingPush
} from '@/api/jarvis/tendoc'

export default {
  name: 'TencentDocPushMonitor',
  props: {
    value: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      visible: false,
      pushing: false,
      pushStatus: {
        isScheduled: false,
        scheduledTime: null,
        remainingSeconds: 0,
        remainingMs: 0,
        countdownText: '无定时任务',
        lastSuccessRecord: null
      },
      countdownDisplay: {
        minutes: '00',
        seconds: '00'
      },
      batchRecords: [],
      expandedRecords: [],
      countdownTimer: null,
      refreshTimer: null
    }
  },
  computed: {
    isMobile() {
      if (this.$store?.getters?.device === 'mobile') {
        return true
      }
      if (typeof window !== 'undefined' && window.innerWidth < 768) {
        return true
      }
      return false
    }
  },
  watch: {
    value(val) {
      if (this.visible !== val) {
        this.visible = val
        if (val) {
          this.init()
        } else {
          this.destroy()
        }
      }
    }
  },
  methods: {
    async init() {
      await this.loadPushStatus()
      await this.loadBatchRecords()
      this.startCountdown()
      this.startAutoRefresh()
    },

    destroy() {
      this.stopCountdown()
      this.stopAutoRefresh()
    },

    async loadPushStatus() {
      try {
        const res = await getPushStatus()
        console.log('=== 推送状态响应 ===', res)
        if (res.code === 200) {
          console.log('推送状态数据:', res.data)
          console.log('isScheduled:', res.data.isScheduled)
          console.log('remainingSeconds:', res.data.remainingSeconds)
          console.log('scheduledTime:', res.data.scheduledTime)
          
          // 重要：使用解构赋值，确保 remainingSeconds 被正确赋值
          this.pushStatus = {
            ...res.data,
            remainingSeconds: parseInt(res.data.remainingSeconds) || 0
          }
          
          this.updateCountdownDisplay()
          console.log('倒计时显示:', this.countdownDisplay)
          console.log('pushStatus.remainingSeconds 已更新为:', this.pushStatus.remainingSeconds)
        } else {
          console.error('API返回错误:', res)
        }
      } catch (e) {
        console.error('加载推送状态失败', e)
      }
    },

    async loadBatchRecords() {
      try {
        const res = await getBatchPushRecords({ limit: 20 })
        console.log('加载推送记录响应:', res)
        if (res.code === 200) {
          const records = res.data || []
          // 确保每条记录都有 operationLogs 字段（即使为空数组）
          records.forEach(record => {
            if (!record.hasOwnProperty('operationLogs')) {
              this.$set(record, 'operationLogs', [])
            }
            // 重置详情加载标记，允许重新加载
            this.$set(record, 'detailLoaded', false)
          })
          this.batchRecords = records
          console.log('推送记录数量:', records.length)
          records.forEach(r => {
            console.log(`记录 ${r.batchId}: operationLogs数量=${r.operationLogs ? r.operationLogs.length : 'undefined'}`)
          })
        }
      } catch (e) {
        console.error('加载推送记录失败', e)
      }
    },

    async handleTriggerPushNow() {
      try {
        await this.$confirm('确定要立即执行推送吗？', '提示', {
          type: 'warning'
        })

        this.pushing = true
        const res = await triggerPushNow()

        if (res.code === 200) {
          this.$message.success('推送已触发')
          setTimeout(() => {
            this.loadPushStatus()
            this.loadBatchRecords()
          }, 2000)
        } else {
          this.$message.error(res.msg || '触发推送失败')
        }
      } catch (e) {
        if (e !== 'cancel') {
          this.$message.error('触发推送失败: ' + (e.message || '未知错误'))
        }
      } finally {
        this.pushing = false
      }
    },

    async handleCancelPush() {
      try {
        await this.$confirm('确定要取消待推送任务吗？', '提示', {
          type: 'warning'
        })

        const res = await cancelPendingPush()

        if (res.code === 200) {
          this.$message.success('已取消待推送任务')
          this.loadPushStatus()
        } else {
          this.$message.error(res.msg || '取消失败')
        }
      } catch (e) {
        if (e !== 'cancel') {
          this.$message.error('取消失败: ' + (e.message || '未知错误'))
        }
      }
    },

    async toggleRecordDetail(batchId) {
      const index = this.expandedRecords.indexOf(batchId)
      if (index > -1) {
        // 收起
        this.expandedRecords.splice(index, 1)
      } else {
        // 展开 - 加载详情
        this.expandedRecords.push(batchId)
        await this.loadRecordDetail(batchId)
      }
    },

    async loadRecordDetail(batchId) {
      try {
        const record = this.batchRecords.find(r => r.batchId === batchId)
        if (!record) return

        // 如果已经明确加载过详情（有 loadingDetail 标记且已完成），则不再重复加载
        // 注意：即使 operationLogs 为空数组，也可能是数据确实为空，需要重新加载确认
        if (record.detailLoaded) {
          return
        }

        // 显示加载状态
        this.$set(record, 'loadingDetail', true)

        const res = await getBatchPushRecordDetail(batchId)
        console.log('加载推送详情响应:', res)
        console.log('响应数据:', JSON.stringify(res.data, null, 2))
        if (res.code === 200 && res.data) {
          // 更新记录的详细信息
          const operationLogs = res.data.operationLogs || []
          console.log('操作日志数量:', operationLogs.length, 'batchId:', batchId)
          console.log('操作日志详情:', operationLogs)
          this.$set(record, 'operationLogs', operationLogs)
          this.$set(record, 'errorMessage', res.data.errorMessage)
          // 使用 resultMessage 字段，如果没有则使用 remark
          this.$set(record, 'resultMessage', res.data.resultMessage || res.data.remark)
          // 标记已加载详情
          this.$set(record, 'detailLoaded', true)
          
          // 如果操作日志为空，输出警告信息用于调试
          if (operationLogs.length === 0) {
            console.warn('操作日志为空 - batchId:', batchId, '记录数据:', res.data)
          }
        } else {
          this.$message.warning('加载详情失败: ' + (res.msg || '未知错误'))
        }
      } catch (e) {
        console.error('加载推送详情失败', e)
        this.$message.error('加载详情失败: ' + (e.message || '未知错误'))
      } finally {
        const record = this.batchRecords.find(r => r.batchId === batchId)
        if (record) {
          this.$set(record, 'loadingDetail', false)
        }
      }
    },

    startCountdown() {
      this.stopCountdown()
      
      // 立即更新一次显示
      this.updateCountdownDisplay()
      
      this.countdownTimer = setInterval(() => {
        if (this.pushStatus.remainingSeconds > 0) {
          this.pushStatus.remainingSeconds--
          this.pushStatus.remainingMs = this.pushStatus.remainingSeconds * 1000
          this.updateCountdownDisplay()
        } else if (this.pushStatus.isScheduled) {
          // 倒计时结束，刷新状态
          this.loadPushStatus()
          this.loadBatchRecords()
        }
      }, 1000)
    },

    stopCountdown() {
      if (this.countdownTimer) {
        clearInterval(this.countdownTimer)
        this.countdownTimer = null
      }
    },

    startAutoRefresh() {
      this.stopAutoRefresh()
      // 每30秒自动刷新一次状态
      this.refreshTimer = setInterval(() => {
        this.loadPushStatus()
        this.loadBatchRecords()
      }, 30000)
    },

    stopAutoRefresh() {
      if (this.refreshTimer) {
        clearInterval(this.refreshTimer)
        this.refreshTimer = null
      }
    },

    updateCountdownDisplay() {
      const seconds = this.pushStatus.remainingSeconds || 0
      console.log('更新倒计时显示 - remainingSeconds:', seconds)
      const minutes = Math.floor(seconds / 60)
      const secs = seconds % 60
      this.countdownDisplay.minutes = String(minutes).padStart(2, '0')
      this.countdownDisplay.seconds = String(secs).padStart(2, '0')
      console.log('倒计时显示更新为:', this.countdownDisplay.minutes + ':' + this.countdownDisplay.seconds)
    },

    formatDateTime(dateTime) {
      if (!dateTime) return '-'
      try {
        // 处理多种时间格式
        const date = new Date(dateTime)
        if (isNaN(date.getTime())) return dateTime
        
        const year = date.getFullYear()
        const month = String(date.getMonth() + 1).padStart(2, '0')
        const day = String(date.getDate()).padStart(2, '0')
        const hours = String(date.getHours()).padStart(2, '0')
        const minutes = String(date.getMinutes()).padStart(2, '0')
        const seconds = String(date.getSeconds()).padStart(2, '0')
        
        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
      } catch (e) {
        console.error('格式化时间失败:', e, dateTime)
        return dateTime
      }
    },

    formatDuration(ms) {
      if (!ms) return '-'
      const seconds = Math.floor(ms / 1000)
      const minutes = Math.floor(seconds / 60)
      const secs = seconds % 60
      return minutes > 0 ? `${minutes}分${secs}秒` : `${secs}秒`
    },

    getStatusText(status) {
      const statusMap = {
        'RUNNING': '执行中',
        'SUCCESS': '成功',
        'PARTIAL': '部分成功',
        'FAILED': '失败'
      }
      return statusMap[status] || status
    },

    getStatusTagType(status) {
      const typeMap = {
        'RUNNING': 'warning',
        'SUCCESS': 'success',
        'PARTIAL': 'warning',
        'FAILED': 'danger'
      }
      return typeMap[status] || 'info'
    },

    getRecordType(status) {
      const typeMap = {
        'SUCCESS': 'success',
        'PARTIAL': 'warning',
        'FAILED': 'danger',
        'RUNNING': 'primary'
      }
      return typeMap[status] || 'info'
    },

    getRecordIcon(status) {
      const iconMap = {
        'SUCCESS': 'el-icon-success',
        'PARTIAL': 'el-icon-warning',
        'FAILED': 'el-icon-error',
        'RUNNING': 'el-icon-loading'
      }
      return iconMap[status] || 'el-icon-info'
    },

    getTriggerSourceText(source) {
      const sourceMap = {
        'DELAYED_TIMER': '延迟定时器',
        'USER': '用户手动',
        'SYSTEM': '系统'
      }
      return sourceMap[source] || source
    },

    handleClose() {
      this.visible = false
      this.expandedRecords = []
      this.$emit('input', false)
    },
    
    handleVisibleChange(val) {
      this.visible = val
      this.$emit('input', val)
      if (!val) {
        this.expandedRecords = []
      }
    }
  },
  beforeDestroy() {
    this.destroy()
  }
}
</script>

<style scoped>
.push-monitor {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* 倒计时卡片 */
.countdown-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.countdown-card >>> .el-card__body {
  padding: 0;
}

.countdown-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}

.countdown-header .header-left {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 18px;
  font-weight: 500;
}

.countdown-header .header-left i {
  font-size: 24px;
}

.countdown-content {
  padding: 30px 20px 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.countdown-display {
  display: flex;
  align-items: center;
  gap: 15px;
  font-size: 48px;
  font-weight: bold;
  opacity: 0.5;
  transition: all 0.3s;
}

.countdown-display.active {
  opacity: 1;
  animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

.time-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 80px;
  padding: 10px 20px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 10px;
}

.time-value {
  font-size: 48px;
  line-height: 1;
}

.time-label {
  font-size: 14px;
  margin-top: 5px;
  opacity: 0.8;
}

.time-separator {
  font-size: 36px;
  opacity: 0.6;
}

.countdown-info {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  max-width: 600px;
}

.info-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  padding: 8px 15px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 6px;
}

.info-item i {
  font-size: 16px;
}

.countdown-actions {
  display: flex;
  gap: 10px;
}

/* 推送记录卡片 */
.records-card {
  flex: 1;
}

.records-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.records-header .header-left {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 500;
}

.records-header .header-left i {
  font-size: 20px;
  color: #409eff;
}

.record-item {
  cursor: pointer;
  transition: all 0.3s;
}

.record-item:hover {
  transform: translateY(-2px);
}

.record-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.summary-left,
.summary-right {
  display: flex;
  align-items: center;
  gap: 15px;
}

.trigger-source {
  color: #909399;
  font-size: 13px;
}

.record-stats {
  display: flex;
  align-items: center;
  font-size: 14px;
  font-weight: 500;
}

.record-range,
.record-duration {
  color: #606266;
  font-size: 13px;
}

.record-detail {
  margin-top: 15px;
}

.detail-message,
.detail-error {
  margin-bottom: 15px;
}

.message-label,
.error-label {
  font-weight: 500;
  margin-bottom: 5px;
  color: #606266;
}

.message-content {
  padding: 10px;
  background: #f0f9ff;
  border-left: 3px solid #409eff;
  border-radius: 4px;
  font-size: 13px;
}

.error-content {
  padding: 10px;
  background: #fef0f0;
  border-left: 3px solid #f56c6c;
  border-radius: 4px;
  font-size: 13px;
  color: #f56c6c;
}

.operation-logs {
  margin-top: 15px;
}

.logs-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
  margin-bottom: 10px;
  color: #606266;
}

.logs-header i {
  color: #409eff;
}

.loading-detail {
  text-align: center;
  padding: 20px;
  color: #909399;
}

.no-logs {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 30px;
  color: #909399;
  font-size: 14px;
}

.no-logs i {
  font-size: 18px;
}

/* 移动端适配 */
@media (max-width: 768px) {
  .push-monitor {
    gap: 12px;
  }

  .countdown-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 12px;
  }

  .countdown-header .header-left {
    font-size: 16px;
  }

  .countdown-header .header-left i {
    font-size: 20px;
  }

  .countdown-content {
    padding: 20px 12px 12px;
    gap: 15px;
  }

  .countdown-display {
    font-size: 32px;
    gap: 10px;
  }

  .time-box {
    min-width: 60px;
    padding: 8px 12px;
  }

  .time-value {
    font-size: 32px;
  }

  .time-separator {
    font-size: 24px;
  }

  .countdown-info {
    gap: 8px;
  }

  .info-item {
    font-size: 12px;
    padding: 6px 12px;
    flex-wrap: wrap;
  }

  .countdown-actions {
    flex-direction: column;
    width: 100%;
    gap: 8px;
  }

  .countdown-actions .el-button {
    width: 100%;
    margin: 0;
  }

  .records-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .records-header .header-left {
    font-size: 14px;
  }

  .record-summary {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .summary-left,
  .summary-right {
    width: 100%;
    flex-wrap: wrap;
    gap: 8px;
  }

  .record-stats {
    font-size: 12px;
  }

  .trigger-source,
  .record-range,
  .record-duration {
    font-size: 12px;
  }
}

/* 移动端全屏弹窗样式 */
::v-deep .mobile-push-monitor-dialog {
  margin: 0 !important;
  width: 100% !important;
  height: 100% !important;
  max-width: 100% !important;
  max-height: 100% !important;
}

::v-deep .mobile-push-monitor-dialog .el-dialog {
  margin: 0 !important;
  width: 100% !important;
  height: 100% !important;
  max-width: 100% !important;
  max-height: 100% !important;
  border-radius: 0 !important;
  display: flex;
  flex-direction: column;
}

::v-deep .mobile-push-monitor-dialog .el-dialog__body {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
  -webkit-overflow-scrolling: touch;
}

::v-deep .mobile-push-monitor-dialog .el-dialog__header {
  padding: 12px 16px;
  border-bottom: 1px solid #e4e7ed;
  flex-shrink: 0;
}

::v-deep .mobile-push-monitor-dialog .el-dialog__title {
  font-size: 16px;
}
</style>

