<template>
  <div class="app-container ai-sip-outbound-cdr">
    <el-form
      :model="queryParams"
      ref="queryForm"
      :inline="true"
      v-show="showSearch"
      label-width="86px"
      class="search-form"
    >
      <el-form-item label="销售公司" prop="companyId">
        <el-select
          v-model="queryParams.companyId"
          placeholder="请选择销售公司"
          clearable
          filterable
          allow-create
          default-first-option
          size="small"
          class="filter-control"
          @change="handleQuery"
        >
          <el-option
            v-for="company in companyList"
            :key="company.companyId"
            :label="company.companyName"
            :value="company.companyId"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="工号" prop="opnum">
        <el-input
          v-model="queryParams.opnum"
          placeholder="请输入工号"
          clearable
          size="small"
          class="filter-control"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="外呼来源" prop="sourceType">
        <el-select
          v-model="queryParams.sourceType"
          placeholder="外呼类型"
          clearable
          size="small"
          class="filter-control"
        >
          <el-option label="销售" value="0" />
          <el-option label="总后台" value="1" />
          <el-option label="医生" value="2" />
        </el-select>
      </el-form-item>
      <el-form-item label="通话分钟">
        <div class="time-range">
          <el-input-number
            v-model="queryParams.timeLenStart"
            :min="0"
            placeholder="最小值"
            size="small"
            controls-position="right"
            class="minute-input"
          />
          <span class="range-separator">至</span>
          <el-input-number
            v-model="queryParams.timeLenEnd"
            :min="0"
            placeholder="最大值"
            size="small"
            controls-position="right"
            class="minute-input"
          />
        </div>
      </el-form-item>
      <el-form-item label="外呼时间">
        <el-date-picker
          v-model="outboundTimeRange"
          type="datetimerange"
          size="small"
          class="outbound-time-picker"
          value-format="yyyy-MM-dd HH:mm:ss"
          format="yyyy-MM-dd HH:mm"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          :default-time="['00:00:00', '23:59:59']"
          :picker-options="outboundPickerOptions"
          @change="handleOutboundTimeChange"
        />
      </el-form-item>
      <el-form-item class="search-actions">
        <el-button type="primary" 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 toolbar-row">
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['his:aiSipCall:outboundCdr:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table
      border
      stripe
      v-loading="loading"
      :data="outboundCdrList"
      class="cdr-table"
      :header-cell-style="headerCellStyle"
    >
      <el-table-column label="销售公司" align="center" prop="companyName" min-width="120" show-overflow-tooltip />
      <el-table-column label="外呼来源" align="center" width="100">
        <template slot-scope="scope">
          <el-tag
            size="mini"
            effect="plain"
            :type="sourceTagType(scope.row)"
          >{{ formatSourceType(scope.row) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="主叫用户" align="center" min-width="120" show-overflow-tooltip>
        <template slot-scope="scope">
          <span class="caller-name">{{ formatCallerName(scope.row) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="工号" align="center" prop="opnum" min-width="100" />
      <el-table-column label="被叫号码" align="center" prop="callee" min-width="120" show-overflow-tooltip />
      <el-table-column label="外呼时间" align="center" prop="startTimeStr" min-width="160" />
      <el-table-column label="通话时长" align="center" prop="timeLenSec" width="100" />
      <el-table-column label="纯通时长" align="center" prop="timeLenValidStr" width="100" />
      <el-table-column label="挂断原因" align="center" prop="hangupCause" min-width="120" show-overflow-tooltip />
      <el-table-column label="操作" align="center" width="168" fixed="right" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <div v-if="canPlayVoice(scope.row)" class="op-actions">
            <button
              type="button"
              class="op-chip op-chip--play"
              v-hasPermi="['his:aiSipCall:phone:downloadVoice']"
              @click="openPlayDialog(scope.row)"
            >
              <i class="el-icon-video-play"></i>
              <span>播放</span>
            </button>
            <button
              type="button"
              class="op-chip op-chip--download"
              v-hasPermi="['his:aiSipCall:phone:downloadVoice']"
              :disabled="downloadLoading && downloadTarget === scope.row.wavfile"
              @click="downloadVoice(scope.row)"
            >
              <i :class="downloadLoading && downloadTarget === scope.row.wavfile ? 'el-icon-loading' : 'el-icon-download'"></i>
              <span>下载</span>
            </button>
          </div>
          <span v-else class="op-empty">—</span>
        </template>
      </el-table-column>
    </el-table>

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

    <sip-recording-play-dialog
      ref="playDialog"
      :visible.sync="playDialogVisible"
      :title="playDialogTitle"
      :subtitle="playMeta.subtitle"
      :audio-url="playAudioUrl"
      :audio-loading="audioLoading"
      :messages="visibleChatMessages"
      :total-count="chatMessages.length"
      :page-size="chatPageSize"
      :has-more="hasMoreChat"
      :can-collapse="canCollapseChat"
      @close="closePlayDialog"
      @load-more="loadMoreChat"
      @collapse="collapseChat"
    />
  </div>
</template>

<script>
import { listOutboundCdr, exportOutboundCdr } from "@/api/aiSipCall/aiSipCallOutboundCdr";
import { listCompany } from '../../api/company/company'
import sipRecordingPlayback from "./mixins/sipRecordingPlayback";
import SipRecordingPlayDialog from "./components/SipRecordingPlayDialog";

export default {
  name: "OutboundCdr",
  components: { SipRecordingPlayDialog },
  mixins: [sipRecordingPlayback],
  data() {
    const todayStart = this.getTodayStart();
    const todayEnd = this.getTodayEnd();
    return {
      loading: true,
      exportLoading: false,
      showSearch: true,
      total: 0,
      outboundCdrList: [],
      companyList: [],
      outboundTimeRange: [todayStart, todayEnd],
      headerCellStyle: {
        background: '#f7f9fc',
        color: '#303133',
        fontWeight: 600
      },
      outboundPickerOptions: {
        shortcuts: [
          {
            text: '今天',
            onClick(picker) {
              const start = new Date();
              start.setHours(0, 0, 0, 0);
              const end = new Date();
              end.setHours(23, 59, 59, 999);
              picker.$emit('pick', [start, end]);
            }
          },
          {
            text: '最近3天',
            onClick(picker) {
              const end = new Date();
              end.setHours(23, 59, 59, 999);
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 2);
              start.setHours(0, 0, 0, 0);
              picker.$emit('pick', [start, end]);
            }
          },
          {
            text: '最近7天',
            onClick(picker) {
              const end = new Date();
              end.setHours(23, 59, 59, 999);
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
              start.setHours(0, 0, 0, 0);
              picker.$emit('pick', [start, end]);
            }
          }
        ]
      },
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        timeLenStart: undefined,
        timeLenEnd: undefined,
        opnum: null,
        startTimeStart: todayStart,
        startTimeEnd: todayEnd,
        callee: null,
        companyId: null,
        sourceType: '1',
        status: 0
      },
    };
  },
  created() {
    listCompany().then(response => {
      this.companyList = response.rows;
      this.queryParams.companyId = undefined;
      this.getList();
    })
  },
  methods: {
    getTodayStart() {
      const now = new Date();
      return now.getFullYear() + '-' +
             String(now.getMonth() + 1).padStart(2, '0') + '-' +
             String(now.getDate()).padStart(2, '0') + ' 00:00:00';
    },
    getTodayEnd() {
      const now = new Date();
      return now.getFullYear() + '-' +
        String(now.getMonth() + 1).padStart(2, '0') + '-' +
        String(now.getDate()).padStart(2, '0') + ' 23:59:59';
    },
    syncOutboundTimeToQuery() {
      if (this.outboundTimeRange && this.outboundTimeRange.length === 2) {
        this.queryParams.startTimeStart = this.outboundTimeRange[0];
        this.queryParams.startTimeEnd = this.outboundTimeRange[1];
      } else {
        this.queryParams.startTimeStart = null;
        this.queryParams.startTimeEnd = null;
      }
    },
    handleOutboundTimeChange() {
      this.syncOutboundTimeToQuery();
    },
    canPlayVoice(row) {
      return !!(row && row.wavfile && row.timeLenValid && row.timeLenValid != 0);
    },
    getList() {
      this.loading = true;
      this.syncOutboundTimeToQuery();
      listOutboundCdr(this.queryParams).then(response => {
        this.outboundCdrList = response.rows || [];
        this.total = response.total || 0;
        this.loading = false;
      }).catch(() => {
        this.loading = false;
      });
    },
    /** 外呼来源：0销售 1总后台 2医生 */
    getSourceTypeValue(row) {
      const val = row && row.sourceType;
      return val == null || val === '' ? '' : String(val)
    },
    formatSourceType(row) {
      const map = { '0': '销售', '1': '总后台', '2': '医生' }
      return map[this.getSourceTypeValue(row)] || '-'
    },
    sourceTagType(row) {
      const map = { '0': 'warning', '1': 'info', '2': 'success' }
      return map[this.getSourceTypeValue(row)] || 'info'
    },
    /** 主叫用户：0公司用户 1系统用户 2医生 */
    formatCallerName(row) {
      if (!row) return '-'
      const type = this.getSourceTypeValue(row)
      if (type === '0') return row.companyUserName || '-'
      if (type === '1') return row.sysUserName || '-'
      if (type === '2') return row.doctorName || '-'
      return row.companyUserName || row.sysUserName || row.doctorName || '-'
    },
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    resetQuery() {
      const todayStart = this.getTodayStart();
      const todayEnd = this.getTodayEnd();
      this.outboundTimeRange = [todayStart, todayEnd];
      this.queryParams.startTimeStart = todayStart;
      this.queryParams.startTimeEnd = todayEnd;
      this.queryParams.timeLenStart = undefined;
      this.queryParams.timeLenEnd = undefined;
      this.queryParams.companyId = null;
      this.queryParams.callee = null;
      this.queryParams.opnum = null;
      this.queryParams.sourceType = null;
      this.handleQuery();
    },
    handleExport() {
      this.syncOutboundTimeToQuery();
      const queryParams = { ...this.queryParams };
      delete queryParams.pageNum;
      delete queryParams.pageSize;
      this.$confirm('是否确认导出所有aiSIP手动外呼通话记录数据项?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.exportLoading = true;
        return exportOutboundCdr(queryParams);
      }).then(response => {
        this.download(response.msg);
        this.exportLoading = false;
      }).catch(() => {
        this.exportLoading = false;
      });
    },
  }
};
</script>

<style scoped>
.ai-sip-outbound-cdr .search-form {
  margin-bottom: 12px;
  padding: 14px 16px 4px;
  background: #fafbfc;
  border: 1px solid #eef0f3;
  border-radius: 8px;
}

.ai-sip-outbound-cdr .filter-control {
  width: 160px;
}

.ai-sip-outbound-cdr .time-range {
  display: inline-flex;
  align-items: center;
}

.ai-sip-outbound-cdr .minute-input {
  width: 120px;
}

.ai-sip-outbound-cdr .range-separator {
  margin: 0 8px;
  color: #909399;
  font-size: 12px;
}

.ai-sip-outbound-cdr .outbound-time-picker {
  width: 360px;
}

.ai-sip-outbound-cdr .search-actions {
  margin-left: 4px;
}

.ai-sip-outbound-cdr .toolbar-row {
  margin-top: 4px;
}

.ai-sip-outbound-cdr .cdr-table {
  border-radius: 6px;
  overflow: hidden;
}

.ai-sip-outbound-cdr .caller-name {
  color: #303133;
}

.ai-sip-outbound-cdr .op-actions {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.ai-sip-outbound-cdr .op-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 28px;
  padding: 0 10px;
  border: 1px solid transparent;
  border-radius: 14px;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  transition: all 0.2s ease;
  outline: none;
  background: transparent;
}

.ai-sip-outbound-cdr .op-chip i {
  font-size: 13px;
}

.ai-sip-outbound-cdr .op-chip--play {
  color: #2f6fed;
  background: #edf4ff;
  border-color: #d6e6ff;
}

.ai-sip-outbound-cdr .op-chip--play:hover {
  color: #fff;
  background: #409eff;
  border-color: #409eff;
  box-shadow: 0 4px 10px rgba(64, 158, 255, 0.28);
}

.ai-sip-outbound-cdr .op-chip--download {
  color: #2f9b57;
  background: #eefaf2;
  border-color: #d4f0de;
}

.ai-sip-outbound-cdr .op-chip--download:hover {
  color: #fff;
  background: #67c23a;
  border-color: #67c23a;
  box-shadow: 0 4px 10px rgba(103, 194, 58, 0.28);
}

.ai-sip-outbound-cdr .op-chip:disabled,
.ai-sip-outbound-cdr .op-chip:disabled:hover {
  color: #a8abb2;
  background: #f4f4f5;
  border-color: #e9e9eb;
  box-shadow: none;
  cursor: not-allowed;
}

.ai-sip-outbound-cdr .op-empty {
  color: #c0c4cc;
  font-size: 12px;
}
</style>
