<template>
  <div class="plm-recv-page app-container">
    <section class="page-hero">
      <div class="page-hero__main">
        <div class="page-hero__icon">
          <i class="el-icon-document-checked"></i>
        </div>
        <div>
          <h1 class="page-hero__title">PLM 工艺 / 总装 BOM 接收留痕</h1>
          <p class="page-hero__desc">记录 PLM 推送的完整报文，防先删后插后扯皮；可按令号、类型、状态追溯。</p>
        </div>
      </div>
      <div class="page-hero__stats">
        <div class="stat-chip">
          <span class="stat-chip__label">当前页</span>
          <span class="stat-chip__value">{{ logList.length }}</span>
        </div>
        <div class="stat-chip stat-chip--accent">
          <span class="stat-chip__label">累计</span>
          <span class="stat-chip__value">{{ total }}</span>
        </div>
        <div class="stat-chip">
          <span class="stat-chip__label">本页成功</span>
          <span class="stat-chip__value">{{ pageSuccessCount }}</span>
        </div>
      </div>
    </section>

    <el-card shadow="never" class="search-card">
      <el-form
        :model="queryParams"
        ref="queryForm"
        size="small"
        :inline="true"
        v-show="showSearch"
        label-width="88px"
        class="search-form"
      >
        <el-form-item label="生产令号" prop="productionOrderNo">
          <el-input
            v-model="queryParams.productionOrderNo"
            placeholder="模糊匹配生产令号"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="业务类型" prop="bizType">
          <el-select v-model="queryParams.bizType" clearable placeholder="全部" style="width: 160px">
            <el-option label="总装配 BOM" value="ASSEMBLY_BOM" />
            <el-option label="工艺路线" value="PROCESS_ROUTE" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="queryParams.status" clearable placeholder="全部" style="width: 120px">
            <el-option label="成功" value="SUCCESS" />
            <el-option label="失败" value="FAIL" />
          </el-select>
        </el-form-item>
        <el-form-item label="接收时间">
          <el-date-picker
            v-model="dateRange"
            type="datetimerange"
            value-format="yyyy-MM-dd HH:mm:ss"
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            :default-time="['00:00:00', '23:59:59']"
            style="width: 360px"
          />
        </el-form-item>
        <el-form-item>
          <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-card>

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

    <el-card shadow="never" class="table-card">
      <el-table
        v-loading="loading"
        :data="logList"
        :header-cell-style="headerCellStyle"
        stripe
      >
        <el-table-column type="index" label="#" width="52" align="center" />
        <el-table-column label="生产令号" min-width="160" show-overflow-tooltip>
          <template slot-scope="scope">
            <span class="order-no">{{ scope.row.productionOrderNo || '-' }}</span>
          </template>
        </el-table-column>
        <el-table-column label="类型" width="120" align="center">
          <template slot-scope="scope">
            <el-tag size="mini" :type="scope.row.bizType === 'ASSEMBLY_BOM' ? '' : 'warning'" effect="plain">
              {{ bizTypeLabel(scope.row.bizType) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="状态" width="88" align="center">
          <template slot-scope="scope">
            <el-tag size="mini" :type="scope.row.status === 'SUCCESS' ? 'success' : 'danger'">
              {{ scope.row.status === 'SUCCESS' ? '成功' : '失败' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="行数" width="72" align="center" prop="lineCount" />
        <el-table-column label="入库数" width="80" align="center" prop="savedCount" />
        <el-table-column label="覆盖" width="72" align="center">
          <template slot-scope="scope">
            <span>{{ scope.row.replaced === true ? '是' : (scope.row.replaced === false ? '否' : '-') }}</span>
          </template>
        </el-table-column>
        <el-table-column label="报文大小" width="100" align="center">
          <template slot-scope="scope">
            {{ formatSize(scope.row.payloadSize) }}
          </template>
        </el-table-column>
        <el-table-column label="客户端IP" width="120" align="center" show-overflow-tooltip prop="clientIp" />
        <el-table-column label="接收时间" width="168" align="center">
          <template slot-scope="scope">
            {{ parseTime(scope.row.receiveTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
          </template>
        </el-table-column>
        <el-table-column label="失败原因" min-width="160" show-overflow-tooltip prop="errorMsg" />
        <el-table-column label="操作" width="210" align="center" fixed="right">
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-view"
              @click="handleDetail(scope.row)"
              v-hasPermi="['system:plmReceiveLog:query']"
            >详情</el-button>
            <el-button
              size="mini"
              type="text"
              icon="el-icon-upload2"
              :disabled="!scope.row.productionOrderNo"
              @click="handleSyncBomDetails(scope.row)"
              v-hasPermi="['system:plmReceiveLog:syncBomDetails']"
            >写入BOM明细</el-button>
          </template>
        </el-table-column>
      </el-table>

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

    <el-drawer
      :title="detailTitle"
      :visible.sync="detailOpen"
      direction="rtl"
      size="780px"
      append-to-body
      custom-class="plm-recv-drawer"
      @closed="resetDetail"
    >
      <div v-loading="detailLoading" class="detail-body">
        <template v-if="detail">
          <div class="detail-summary">
            <div class="detail-summary__item">
              <span class="detail-summary__label">生产令号</span>
              <span class="detail-summary__value">{{ detail.productionOrderNo || '-' }}</span>
            </div>
            <div class="detail-summary__item">
              <span class="detail-summary__label">业务类型</span>
              <span class="detail-summary__value">{{ bizTypeLabel(detail.bizType) }}</span>
            </div>
            <div class="detail-summary__item">
              <span class="detail-summary__label">状态</span>
              <el-tag size="mini" :type="detail.status === 'SUCCESS' ? 'success' : 'danger'">
                {{ detail.status === 'SUCCESS' ? '成功' : '失败' }}
              </el-tag>
            </div>
            <div class="detail-summary__item">
              <span class="detail-summary__label">接口</span>
              <code class="path-text">{{ detail.apiPath || '-' }}</code>
            </div>
            <div class="detail-summary__item">
              <span class="detail-summary__label">行数 / 入库</span>
              <span class="detail-summary__value">{{ detail.lineCount != null ? detail.lineCount : '-' }} / {{ detail.savedCount != null ? detail.savedCount : '-' }}</span>
            </div>
            <div class="detail-summary__item">
              <span class="detail-summary__label">报文大小</span>
              <span class="detail-summary__value">{{ formatSize(detail.payloadSize) }}</span>
            </div>
            <div class="detail-summary__item detail-summary__item--wide">
              <span class="detail-summary__label">SHA-256</span>
              <code class="path-text">{{ detail.payloadSha256 || '-' }}</code>
            </div>
            <div class="detail-summary__item">
              <span class="detail-summary__label">接收时间</span>
              <span class="detail-summary__value">{{ parseTime(detail.receiveTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
            </div>
            <div class="detail-summary__item" v-if="detail.errorMsg">
              <span class="detail-summary__label">失败原因</span>
              <span class="detail-summary__value error-text">{{ detail.errorMsg }}</span>
            </div>
          </div>

          <div class="detail-actions" v-hasPermi="['system:plmReceiveLog:syncBomDetails']">
            <el-button
              size="mini"
              type="primary"
              plain
              icon="el-icon-upload2"
              :disabled="!detail.productionOrderNo"
              :loading="syncLoading"
              @click="handleSyncBomDetails(detail)"
            >写入 BOM 明细</el-button>
            <span class="detail-actions__hint">从 production_order 同步总装行到 bom_details（覆盖 bomType=0）</span>
          </div>

          <el-tabs v-model="detailTab" class="detail-tabs">
            <el-tab-pane label="请求报文 JSON" name="payload">
              <div class="json-toolbar">
                <el-button size="mini" type="primary" plain icon="el-icon-document-copy" @click="copyJson(formattedPayload)">复制报文</el-button>
              </div>
              <pre class="json-block">{{ formattedPayload }}</pre>
            </el-tab-pane>
            <el-tab-pane label="摘要 JSON" name="summary">
              <div class="json-toolbar">
                <el-button size="mini" type="primary" plain icon="el-icon-document-copy" @click="copyJson(formattedSummary)">复制摘要</el-button>
              </div>
              <pre class="json-block">{{ formattedSummary }}</pre>
            </el-tab-pane>
          </el-tabs>
        </template>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import { listPlmReceiveLog, getPlmReceiveLog, syncPlmReceiveLogBomDetails } from '@/api/system/plmReceiveLog'

export default {
  name: 'PlmReceiveLog',
  data() {
    return {
      loading: false,
      showSearch: true,
      total: 0,
      logList: [],
      dateRange: [],
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        productionOrderNo: undefined,
        bizType: undefined,
        status: undefined
      },
      detailOpen: false,
      detailLoading: false,
      syncLoading: false,
      detail: null,
      detailTab: 'payload'
    }
  },
  computed: {
    pageSuccessCount() {
      return this.logList.filter(r => r.status === 'SUCCESS').length
    },
    detailTitle() {
      if (!this.detail) return '接收记录详情'
      const orderNo = this.detail.productionOrderNo || ''
      return orderNo ? `接收详情 · ${orderNo}` : '接收记录详情'
    },
    formattedPayload() {
      return this.prettyJson(this.detail && this.detail.payloadJson)
    },
    formattedSummary() {
      return this.prettyJson(this.detail && this.detail.summaryJson)
    }
  },
  created() {
    this.getList()
  },
  methods: {
    headerCellStyle() {
      return {
        background: '#f0f5f4',
        color: '#1a3a36',
        fontWeight: '600',
        fontSize: '13px'
      }
    },
    bizTypeLabel(type) {
      if (type === 'ASSEMBLY_BOM') return '总装配 BOM'
      if (type === 'PROCESS_ROUTE') return '工艺路线'
      return type || '-'
    },
    formatSize(size) {
      if (size == null) return '-'
      if (size < 1024) return size + ' B'
      if (size < 1024 * 1024) return (size / 1024).toFixed(1) + ' KB'
      return (size / 1024 / 1024).toFixed(2) + ' MB'
    },
    prettyJson(raw) {
      if (!raw) return '—'
      try {
        return JSON.stringify(JSON.parse(raw), null, 2)
      } catch (e) {
        return raw
      }
    },
    buildQueryParams() {
      let params = { ...this.queryParams }
      params = this.addDateRange(params, this.dateRange, 'ReceiveTime')
      return params
    },
    getList() {
      this.loading = true
      listPlmReceiveLog(this.buildQueryParams())
        .then(response => {
          this.logList = response.rows || []
          this.total = Number(response.total) || 0
        })
        .finally(() => {
          this.loading = false
        })
    },
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    resetQuery() {
      this.dateRange = []
      this.resetForm('queryForm')
      this.handleQuery()
    },
    handleDetail(row) {
      if (!row || row.id == null) return
      this.detailOpen = true
      this.detailLoading = true
      this.detailTab = 'payload'
      getPlmReceiveLog(row.id)
        .then(response => {
          this.detail = response.data || null
        })
        .finally(() => {
          this.detailLoading = false
        })
    },
    handleSyncBomDetails(row) {
      if (!row || row.id == null) return
      const orderNo = row.productionOrderNo || ''
      if (!orderNo) {
        this.$modal.msgWarning('该记录无生产令号')
        return
      }
      this.$modal.confirm(
        '确认将令号「' + orderNo + '」在 production_order 中的总装行同步到 bom_details？\n（覆盖同令号旧总装行 bomType=0，保留材料 BOM）'
      ).then(() => {
        this.syncLoading = true
        return syncPlmReceiveLogBomDetails(row.id)
      }).then(res => {
        const count = res && res.data ? res.data.savedCount : null
        const msg = res && res.msg
          ? res.msg
          : ('同步成功' + (count != null ? '，共 ' + count + ' 条' : ''))
        this.$modal.msgSuccess(msg)
      }).catch(() => {}).finally(() => {
        this.syncLoading = false
      })
    },
    resetDetail() {
      this.detail = null
      this.detailTab = 'payload'
    },
    copyJson(text) {
      if (!text || text === '—') {
        this.$modal.msgWarning('暂无可复制内容')
        return
      }
      const textarea = document.createElement('textarea')
      textarea.value = text
      textarea.style.position = 'fixed'
      textarea.style.opacity = '0'
      document.body.appendChild(textarea)
      textarea.select()
      try {
        document.execCommand('copy')
        this.$modal.msgSuccess('已复制到剪贴板')
      } catch (e) {
        this.$modal.msgError('复制失败')
      }
      document.body.removeChild(textarea)
    }
  }
}
</script>

<style lang="scss" scoped>
.plm-recv-page {
  --plm-teal: #00b4ad;
  --plm-slate: #1a3a36;
  --plm-bg: #f4f8f7;
  background:
    linear-gradient(180deg, rgba(0, 180, 173, 0.04) 0%, transparent 280px),
    var(--plm-bg);
  min-height: calc(100vh - 84px);
}

.page-hero {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 18px;
  padding: 22px 24px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--plm-slate) 0%, #24524c 55%, #2d6a62 100%);
  box-shadow: 0 8px 24px rgba(26, 58, 54, 0.18);
}

.page-hero__main {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.page-hero__icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: rgba(0, 180, 173, 0.2);
  border: 1px solid rgba(0, 180, 173, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #7fe7e1;
  font-size: 22px;
}

.page-hero__title {
  margin: 0 0 6px;
  font-size: 20px;
  color: #fff;
  font-weight: 600;
}

.page-hero__desc {
  margin: 0;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.72);
  line-height: 1.5;
}

.page-hero__stats {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.stat-chip {
  min-width: 88px;
  padding: 10px 14px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  text-align: center;

  &--accent {
    background: rgba(0, 180, 173, 0.22);
    border-color: rgba(0, 180, 173, 0.35);
  }
}

.stat-chip__label {
  display: block;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.65);
  margin-bottom: 4px;
}

.stat-chip__value {
  display: block;
  font-size: 20px;
  font-weight: 700;
  color: #fff;
}

.search-card,
.table-card {
  border: 1px solid #d8e8e5;
  border-radius: 10px;
  margin-bottom: 14px;
}

.toolbar-row {
  margin-bottom: 8px;
}

.order-no {
  font-weight: 600;
  color: #1a3a36;
}

.path-text {
  font-family: Consolas, Monaco, monospace;
  font-size: 12px;
  color: #456;
  word-break: break-all;
}

.error-text {
  color: #c45656;
}

.detail-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  padding: 10px 12px;
  border-radius: 8px;
  background: #eef8f6;
  border: 1px solid #cfe8e3;
}

.detail-actions__hint {
  font-size: 12px;
  color: #6a8682;
}

.detail-body {
  padding: 0 20px 24px;
}

.detail-summary {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 16px;
  padding: 14px;
  border-radius: 10px;
  background: #f4f8f7;
  border: 1px solid #d8e8e5;
}

.detail-summary__item--wide {
  grid-column: 1 / -1;
}

.detail-summary__label {
  display: block;
  font-size: 12px;
  color: #6a8682;
  margin-bottom: 4px;
}

.detail-summary__value {
  font-size: 14px;
  color: #1a3a36;
  font-weight: 500;
}

.json-toolbar {
  margin-bottom: 8px;
}

.json-block {
  margin: 0;
  max-height: 52vh;
  overflow: auto;
  padding: 12px;
  border-radius: 8px;
  background: #1e2a28;
  color: #d7f3ef;
  font-size: 12px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}
</style>
