<template>
  <div class="app-container">
    <!-- 搜索表单 -->
    <el-form
      v-show="showSearch"
      ref="queryForm"
      :inline="true"
      :model="queryParams"
      label-width="100px"
    >
      <el-form-item label="通话UUID" prop="uuid">
        <el-input
          v-model="queryParams.uuid"
          clearable
          placeholder="请输入通话UUID"
          size="small"
          style="width: 200px"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="主叫号码" prop="caller">
        <el-input
          v-model="queryParams.caller"
          clearable
          placeholder="请输入主叫号码"
          size="small"
          style="width: 200px"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="接听分机号" prop="extnum">
        <el-input
          v-model="queryParams.extnum"
          clearable
          placeholder="请输入接听分机号"
          size="small"
          style="width: 200px"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="通话时长(秒)">
        <el-input-number
          v-model="queryParams.params.timeLenStart"
          :min="0"
          size="small"
          style="width: 120px"
          placeholder="最小值"
          controls-position="right"
        />
        <span class="range-separator">-</span>
        <el-input-number
          v-model="queryParams.params.timeLenEnd"
          :min="0"
          size="small"
          style="width: 120px"
          placeholder="最大值"
          controls-position="right"
        />
      </el-form-item>
      <el-form-item label="呼入时间">
        <el-date-picker
          v-model="inboundTimeRange"
          type="datetimerange"
          size="small"
          style="width: 340px"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          value-format="yyyy-MM-dd HH:mm:ss"
        />
      </el-form-item>
      <el-form-item label="接听时间">
        <el-date-picker
          v-model="answeredTimeRange"
          type="datetimerange"
          size="small"
          style="width: 340px"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          value-format="yyyy-MM-dd HH:mm:ss"
        />
      </el-form-item>
      <el-form-item label="挂机时间">
        <el-date-picker
          v-model="hangupTimeRange"
          type="datetimerange"
          size="small"
          style="width: 340px"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          value-format="yyyy-MM-dd HH:mm:ss"
        />
      </el-form-item>
      <el-form-item>
        <el-button icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 工具栏 -->
    <el-row :gutter="10" class="mb8">
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
    </el-row>

    <!-- 数据表格 -->
    <el-table
      v-loading="loading"
      :data="tableData"
      border
      style="width: 100%"
    >
      <el-table-column align="center" label="UUID" prop="uuid" min-width="120" show-overflow-tooltip />
      <el-table-column align="center" label="主叫号码" prop="caller" min-width="110" show-overflow-tooltip />
       <el-table-column align="center" label="被叫号码" prop="callee" min-width="110" show-overflow-tooltip />
      <el-table-column align="center" label="录音文件" min-width="80">
        <template slot-scope="scope">
          <el-tag v-if="getMediaType(scope.row.wavFile) === 'audio'" type="primary" size="small">音频</el-tag>
          <el-tag v-else-if="getMediaType(scope.row.wavFile) === 'video'" type="success" size="small">视频</el-tag>
          <span v-else>无</span>
        </template>
      </el-table-column>
      <el-table-column align="center" label="呼入时间" min-width="150">
        <template slot-scope="scope">{{ formatTimestamp(scope.row.inboundTime) }}</template>
      </el-table-column>
      <el-table-column align="center" label="接听时间" min-width="150">
        <template slot-scope="scope">{{ formatTimestamp(scope.row.answeredTime) }}</template>
      </el-table-column>
      <el-table-column align="center" label="接听分机" prop="extnum" min-width="90" />
      <el-table-column align="center" label="接听坐席" prop="opnum" min-width="90" />
      <el-table-column align="center" label="挂机时间" min-width="150">
        <template slot-scope="scope">{{ formatTimestamp(scope.row.hangupTime) }}</template>
      </el-table-column>
      <el-table-column align="center" label="业务组" prop="groupName" min-width="100" show-overflow-tooltip />
      <el-table-column align="center" label="通话时长" min-width="90">
        <template slot-scope="scope">{{ formatDuration(scope.row.timeLen) }}</template>
      </el-table-column>
      <!-- <el-table-column align="center" label="挂机原因" min-width="120" show-overflow-tooltip>
        <template slot-scope="scope">
          <span
            class="hangup-cause-cell"
            :title="scope.row.hangupCause"
            @dblclick="copyText(formatHangupCause(scope.row.hangupCause))"
          >{{ formatHangupCause(scope.row.hangupCause) }}</span>
        </template>
      </el-table-column> -->
      <el-table-column
        align="center"
        class-name="small-padding fixed-width"
        label="操作"
        width="160"
      >
        <template slot-scope="scope">
          <el-button
            v-if="scope.row.wavFileUrl"
            size="mini"
            type="text"
            icon="el-icon-video-play"
            @click="handlePlay(scope.row)"
          >播放</el-button>
          <el-button
            v-if="scope.row.wavFileUrl"
            size="mini"
            type="text"
            icon="el-icon-download"
            @click="handleDownload(scope.row)"
          >下载</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <pagination
      v-show="total > 0"
      :limit.sync="queryParams.pageSize"
      :page.sync="queryParams.pageNum"
      :total="total"
      @pagination="getList"
    />

    <!-- 播放弹窗 -->
    <el-dialog
      title="录音播放"
      :visible.sync="playDialogVisible"
      width="700px"
      append-to-body
      @close="handlePlayDialogClose"
    >
      <!-- 音频/视频播放器 -->
      <div v-if="currentMediaType === 'audio'" class="player-wrapper">
        <audio
          ref="audioPlayer"
          :src="currentWavFileUrl"
          controls
          style="width: 100%"
        />
      </div>
      <div v-else-if="currentMediaType === 'video'" class="player-wrapper">
        <video
          ref="videoPlayer"
          :src="currentWavFileUrl"
          controls
          style="width: 100%"
        />
      </div>

      <!-- AI对话内容 -->
      <div v-if="chatDialogList.length > 0" class="chat-container">
        <div class="chat-title">AI对话内容</div>
        <div class="chat-list">
          <div
            v-for="(item, index) in chatDialogList"
            :key="index"
            class="dialog-item"
            :class="item.role"
          >
            <!-- 左侧角色（assistant / agent / kb） -->
            <template v-if="item.role !== 'user'">
              <span class="role-icon">
                <i :class="getRoleIcon(item.role)" />
              </span>
              <span class="role-label">{{ getRoleLabel(item.role) }}</span>
              <div class="bubble">
                <span class="content-text">
                  {{ item.expanded ? item.content : getTruncatedContent(item.content) }}
                  <span
                    v-if="item.content.length > 200"
                    class="more-text"
                    @click="toggleExpand(index)"
                  >{{ item.expanded ? '[收起]' : '[更多]' }}</span>
                </span>
                <el-tag v-if="item.isKb" size="mini" type="warning" class="kb-tag">知识库来源</el-tag>
              </div>
            </template>
            <!-- 右侧角色（user） -->
            <template v-else>
              <div class="bubble">
                <span class="content-text">
                  {{ item.expanded ? item.content : getTruncatedContent(item.content) }}
                  <span
                    v-if="item.content.length > 200"
                    class="more-text"
                    @click="toggleExpand(index)"
                  >{{ item.expanded ? '[收起]' : '[更多]' }}</span>
                </span>
              </div>
              <span class="role-icon">
                <i class="el-icon-user" />
              </span>
              <span class="role-label">客户</span>
            </template>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listInboundCdr } from '@/api/company/inboundCallManage'

export default {
  name: 'InboundCallRecord',
  data() {
    return {
      // 遮罩层
      loading: false,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 表格数据
      tableData: [],
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        uuid: undefined,
        caller: undefined,
        extnum: undefined,
        params: {
          timeLenStart: undefined,
          timeLenEnd: undefined,
          inboundTimeStart: undefined,
          inboundTimeEnd: undefined,
          answeredTimeStart: undefined,
          answeredTimeEnd: undefined,
          hangupTimeStart: undefined,
          hangupTimeEnd: undefined
        }
      },
      // 时间范围
      inboundTimeRange: [],
      answeredTimeRange: [],
      hangupTimeRange: [],
      // 播放弹窗
      playDialogVisible: false,
      currentWavFileUrl: '',
      currentMediaType: '',
      // AI对话列表
      chatDialogList: []
    }
  },
  created() {
    this.getList()
  },
  methods: {
    /** 查询列表 */
    getList() {
      this.loading = true
      // 处理时间范围参数（转为epoch毫秒时间戳，与后端Long类型字段匹配）
      if (this.inboundTimeRange && this.inboundTimeRange.length === 2) {
        this.queryParams.params.inboundTimeStart = new Date(this.inboundTimeRange[0]).getTime()
        this.queryParams.params.inboundTimeEnd = new Date(this.inboundTimeRange[1]).getTime()
      } else {
        this.queryParams.params.inboundTimeStart = undefined
        this.queryParams.params.inboundTimeEnd = undefined
      }
      if (this.answeredTimeRange && this.answeredTimeRange.length === 2) {
        this.queryParams.params.answeredTimeStart = new Date(this.answeredTimeRange[0]).getTime()
        this.queryParams.params.answeredTimeEnd = new Date(this.answeredTimeRange[1]).getTime()
      } else {
        this.queryParams.params.answeredTimeStart = undefined
        this.queryParams.params.answeredTimeEnd = undefined
      }
      if (this.hangupTimeRange && this.hangupTimeRange.length === 2) {
        this.queryParams.params.hangupTimeStart = new Date(this.hangupTimeRange[0]).getTime()
        this.queryParams.params.hangupTimeEnd = new Date(this.hangupTimeRange[1]).getTime()
      } else {
        this.queryParams.params.hangupTimeStart = undefined
        this.queryParams.params.hangupTimeEnd = undefined
      }
      // 通话时长：前端输入秒，数据库存毫秒，显示用Math.ceil(ms/1000)
      // Math.ceil(v/1000)==N 等价于 (N-1)*1000 < v <= N*1000，即 v∈[(N-1)*1000+1, N*1000]
      const params = { ...this.queryParams }
      params.params = { ...this.queryParams.params }
      if (params.params.timeLenStart != null && params.params.timeLenStart !== undefined) {
        const n = params.params.timeLenStart
        params.params.timeLenStart = n > 0 ? (n - 1) * 1000 + 1 : 0
      }
      if (params.params.timeLenEnd != null && params.params.timeLenEnd !== undefined) {
        params.params.timeLenEnd = params.params.timeLenEnd * 1000
      }
      listInboundCdr(params).then(response => {
        this.tableData = response.rows || []
        this.total = response.total || 0
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.inboundTimeRange = []
      this.answeredTimeRange = []
      this.hangupTimeRange = []
      this.resetForm('queryForm')
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        uuid: undefined,
        caller: undefined,
        extnum: undefined,
        params: {
          timeLenStart: undefined,
          timeLenEnd: undefined,
          inboundTimeStart: undefined,
          inboundTimeEnd: undefined,
          answeredTimeStart: undefined,
          answeredTimeEnd: undefined,
          hangupTimeStart: undefined,
          hangupTimeEnd: undefined
        }
      }
      this.handleQuery()
    },
    /** 格式化时间戳 - 毫秒级时间戳转 yyyy-MM-dd HH:mm:ss */
    formatTimestamp(value) {
      if (!value || value <= 0) return '-'
      const date = new Date(Number(value))
      const year = date.getFullYear()
      const month = (date.getMonth() + 1).toString().padStart(2, '0')
      const day = date.getDate().toString().padStart(2, '0')
      const hour = date.getHours().toString().padStart(2, '0')
      const minute = date.getMinutes().toString().padStart(2, '0')
      const second = date.getSeconds().toString().padStart(2, '0')
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`
    },
    /** 格式化通话时长 - 毫秒转 mm分ss秒 */
    formatDuration(value) {
      if (!value || value <= 0) return '0秒'
      const totalSeconds = Math.ceil(value / 1000)
      const minutes = Math.floor(totalSeconds / 60)
      const seconds = totalSeconds % 60
      if (minutes > 0) {
        return `${minutes}分${seconds.toString().padStart(2, '0')}秒`
      }
      return `${seconds}秒`
    },
    /** 判断媒体类型 */
    getMediaType(wavFile) {
      if (!wavFile) return 'none'
      const ext = wavFile.split('.').pop().toLowerCase()
      if (['wav', 'mp3', 'aac'].includes(ext)) return 'audio'
      if (['mp4', 'avi', 'mov'].includes(ext)) return 'video'
      return 'none'
    },
    /** 格式化挂机原因 */
    formatHangupCause(value) {
      if (!value) return '-'
      try {
        const obj = JSON.parse(value)
        if (obj && obj.code !== undefined) {
          return `${obj.code}: ${obj.details || ''}`
        }
        return value
      } catch (e) {
        return value
      }
    },
    /** 双击复制文本 */
    copyText(text) {
      if (!text || text === '-') return
      if (navigator.clipboard && window.isSecureContext) {
        navigator.clipboard.writeText(text).then(() => {
          this.$message.success('复制成功')
        }).catch(() => {
          this.fallbackCopy(text)
        })
      } else {
        this.fallbackCopy(text)
      }
    },
    /** 降级复制方案 */
    fallbackCopy(text) {
      const textArea = document.createElement('textarea')
      textArea.value = text
      textArea.style.position = 'fixed'
      textArea.style.left = '-9999px'
      document.body.appendChild(textArea)
      textArea.focus()
      textArea.select()
      try {
        document.execCommand('copy')
        this.$message.success('复制成功')
      } catch (err) {
        this.$message.error('复制失败')
      }
      document.body.removeChild(textArea)
    },
    /** 播放按钮操作 */
    handlePlay(row) {
      this.currentWavFileUrl = row.wavFileUrl
      this.currentMediaType = this.getMediaType(row.wavFileUrl || row.wavFile)
      // 解析AI对话内容
      this.chatDialogList = this.parseChatContent(row.chatContent)
      this.playDialogVisible = true
    },
    /** 解析聊天内容 */
    parseChatContent(chatContent) {
      if (!chatContent) return []
      try {
        let items = chatContent
        // 如果是字符串，尝试解析
        if (typeof items === 'string') {
          items = JSON.parse(items)
        }
        // 可能是双重JSON字符串
        if (typeof items === 'string') {
          items = JSON.parse(items)
        }
        if (!Array.isArray(items)) return []
        return items.filter(item => ['user', 'assistant', 'agent'].includes(item.role)).map(item => {
          let content = item.content || ''
          let isKb = false
          // 检查是否包含JSON（知识库返回结果）
          if (this.containsJson(content)) {
            isKb = true
            // 移除JSON部分
            let cleaned = content
            while (this.containsJson(cleaned)) {
              cleaned = cleaned.replace(/\{[^{}]*\}/s, '').trim()
            }
            content = cleaned || content
          }
          return {
            role: isKb ? 'kb' : item.role,
            content: content,
            isKb: isKb,
            expanded: false
          }
        }).filter(item => item.content)
      } catch (e) {
        return []
      }
    },
    /** 检查字符串是否包含JSON */
    containsJson(input) {
      if (!input) return false
      return /\{.*?\}/s.test(input)
    },
    /** 获取截断内容 */
    getTruncatedContent(content) {
      if (!content || content.length <= 200) return content
      return content.substring(0, 200) + '...'
    },
    /** 切换展开/收起 */
    toggleExpand(index) {
      this.$set(this.chatDialogList[index], 'expanded', !this.chatDialogList[index].expanded)
    },
    /** 获取角色图标 */
    getRoleIcon(role) {
      const iconMap = {
        assistant: 'el-icon-monitor',
        agent: 'el-icon-phone-outline',
        kb: 'el-icon-folder-opened',
        user: 'el-icon-user'
      }
      return iconMap[role] || 'el-icon-user'
    },
    /** 获取角色标签 */
    getRoleLabel(role) {
      const labelMap = {
        assistant: 'AI',
        agent: '坐席',
        kb: '知识库',
        user: '客户'
      }
      return labelMap[role] || role
    },
    /** 下载按钮操作 */
    handleDownload(row) {
      if (row.wavFileUrl) {
        const link = document.createElement('a')
        link.href = row.wavFileUrl
        link.target = '_blank'
        link.download = ''
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
      }
    },
    /** 播放弹窗关闭 */
    handlePlayDialogClose() {
      // 停止音频/视频播放
      if (this.$refs.audioPlayer) {
        this.$refs.audioPlayer.pause()
        this.$refs.audioPlayer.currentTime = 0
      }
      if (this.$refs.videoPlayer) {
        this.$refs.videoPlayer.pause()
        this.$refs.videoPlayer.currentTime = 0
      }
      this.currentWavFileUrl = ''
      this.currentMediaType = ''
      this.chatDialogList = []
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 20px;
}
.range-separator {
  padding: 0 5px;
}
.player-wrapper {
  margin-bottom: 16px;
}
/* 对话容器 */
.chat-container {
  margin-top: 16px;
  border-top: 1px solid #ebeef5;
  padding-top: 12px;
}
.chat-title {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 12px;
  color: #303133;
}
.chat-list {
  max-height: 400px;
  overflow-y: auto;
  padding-right: 6px;
}
/* 对话气泡 */
.dialog-item {
  display: flex;
  align-items: flex-start;
  margin-bottom: 12px;
}
.dialog-item.user {
  justify-content: flex-end;
}
.dialog-item.assistant,
.dialog-item.agent,
.dialog-item.kb {
  justify-content: flex-start;
}
.bubble {
  display: inline-block;
  max-width: 70%;
  padding: 10px 14px;
  border-radius: 12px;
  word-break: break-word;
  line-height: 1.6;
  font-size: 14px;
  color: #263238;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dialog-item.user .bubble {
  background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
  text-align: right;
}
.dialog-item.assistant .bubble {
  background: linear-gradient(135deg, #f5f5f5 0%, #eeeeee 100%);
}
.dialog-item.agent .bubble {
  background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%);
}
.dialog-item.kb .bubble {
  background: linear-gradient(135deg, #fff8e1 0%, #ffecb3 100%);
}
.role-icon {
  display: flex;
  align-items: center;
  padding: 0 8px;
  font-size: 18px;
  color: #606266;
}
.role-label {
  font-size: 12px;
  color: #909399;
  white-space: nowrap;
  padding: 0 4px;
  line-height: 32px;
}
.content-text {
  word-break: break-word;
}
.more-text {
  color: #1976d2;
  cursor: pointer;
  font-size: 13px;
  margin-left: 4px;
  white-space: nowrap;
}
.more-text:hover {
  text-decoration: underline;
}
.kb-tag {
  margin-top: 6px;
  display: inline-block;
}
.hangup-cause-cell {
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  display: inline-block;
}
</style>
