<template>
  <div class="plm-push-page app-container">
    <section class="page-hero">
      <div class="page-hero__main">
        <div class="page-hero__icon">
          <i class="el-icon-folder-opened"></i>
        </div>
        <div>
          <h1 class="page-hero__title">PLM 图纸推送接收记录</h1>
          <p class="page-hero__desc">追踪 PLM 系统推送的 PDF/DWG 接收情况，查看归档目录与图纸明细。</p>
        </div>
      </div>
      <div class="page-hero__stats">
        <div class="stat-chip">
          <span class="stat-chip__label">当前页记录</span>
          <span class="stat-chip__value">{{ pushList.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">{{ pageItemCount }}</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="archiveName">
          <el-input
            v-model="queryParams.archiveName"
            placeholder="模糊匹配压缩包名"
            clearable
            style="width: 220px"
            @keyup.enter.native="handleQuery"
          />
        </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="pushList"
        :header-cell-style="headerCellStyle"
        :row-class-name="tableRowClassName"
        stripe
      >
        <el-table-column type="index" label="#" width="52" align="center" />
        <el-table-column label="生产令号" min-width="168" show-overflow-tooltip>
          <template slot-scope="scope">
            <span class="order-no">{{ scope.row.productionOrderNo || '-' }}</span>
          </template>
        </el-table-column>
        <el-table-column label="压缩包" min-width="200" show-overflow-tooltip>
          <template slot-scope="scope">
            <div class="archive-cell">
              <i class="el-icon-document archive-cell__icon"></i>
              <span>{{ scope.row.archiveName || '-' }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="明细数量" width="96" align="center">
          <template slot-scope="scope">
            <el-tag size="mini" effect="plain" type="info">{{ scope.row.itemCount != null ? scope.row.itemCount : 0 }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="保存目录" min-width="260" show-overflow-tooltip>
          <template slot-scope="scope">
            <code class="path-text">{{ scope.row.savedDir || '-' }}</code>
          </template>
        </el-table-column>
        <el-table-column label="接收时间" width="168" align="center">
          <template slot-scope="scope">
            <span class="time-text">{{ parseTime(scope.row.receiveTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="96" 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:plmPdfZipPush:query']"
            >详情</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="720px"
      append-to-body
      custom-class="plm-detail-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">{{ detail.archiveName || '-' }}</span>
            </div>
            <div class="detail-summary__item">
              <span class="detail-summary__label">明细数量</span>
              <span class="detail-summary__value">{{ detail.itemCount != null ? detail.itemCount : 0 }}</span>
            </div>
            <div class="detail-summary__item detail-summary__item--wide">
              <span class="detail-summary__label">保存目录</span>
              <code class="detail-summary__path">{{ detail.savedDir || '-' }}</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>

          <el-tabs v-model="detailTab" class="detail-tabs">
            <el-tab-pane label="图纸明细" name="items">
              <el-table
                :data="detail.items || []"
                size="small"
                border
                max-height="360"
                empty-text="暂无图纸明细"
              >
                <el-table-column type="index" label="#" width="48" align="center" />
                <el-table-column label="物料编码" prop="materialCode" min-width="120" show-overflow-tooltip />
                <el-table-column label="物料名称" prop="materialName" min-width="140" show-overflow-tooltip />
                <el-table-column label="单台数量" prop="unitQty" width="96" align="center" />
                <el-table-column label="本批数量" prop="batchQty" width="96" align="center" />
                <el-table-column label="变更图纸" width="88" align="center">
                  <template slot-scope="scope">
                    <el-tag
                      v-if="scope.row.isDrawingChanged === true || scope.row.isDrawingChanged === 1"
                      size="mini"
                      type="warning"
                    >是</el-tag>
                    <el-tag
                      v-else-if="scope.row.isDrawingChanged === false || scope.row.isDrawingChanged === 0"
                      size="mini"
                      type="info"
                    >否</el-tag>
                    <span v-else>-</span>
                  </template>
                </el-table-column>
                <el-table-column label="PDF文件名" prop="savedFileName" min-width="140" show-overflow-tooltip />
                <el-table-column label="DWG文件名" prop="savedDwgFileName" min-width="140" show-overflow-tooltip />
                <el-table-column label="PDF包内路径" prop="pdfPath" min-width="120" show-overflow-tooltip>
                  <template slot-scope="scope">
                    <code class="path-text path-text--sm">{{ scope.row.pdfPath || '-' }}</code>
                  </template>
                </el-table-column>
                <el-table-column label="DWG包内路径" prop="dwgPath" min-width="120" show-overflow-tooltip>
                  <template slot-scope="scope">
                    <code class="path-text path-text--sm">{{ scope.row.dwgPath || '-' }}</code>
                  </template>
                </el-table-column>
                <el-table-column label="PDF本地路径" prop="savedPath" min-width="180" show-overflow-tooltip>
                  <template slot-scope="scope">
                    <code class="path-text path-text--sm">{{ scope.row.savedPath || '-' }}</code>
                  </template>
                </el-table-column>
                <el-table-column label="DWG本地路径" prop="savedDwgPath" min-width="220" show-overflow-tooltip>
                  <template slot-scope="scope">
                    <div class="dwg-path-cell">
                      <code class="path-text path-text--sm">{{ scope.row.savedDwgPath || '-' }}</code>
                      <el-button
                        v-if="scope.row.savedDwgPath || scope.row.savedDwgFileName"
                        type="text"
                        size="mini"
                        icon="el-icon-download"
                        :loading="downloadingItemId === scope.row.id"
                        @click="downloadDwgItem(scope.row)"
                        v-hasPermi="['system:plmPdfZipPush:query']"
                      >下载</el-button>
                    </div>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="Manifest JSON" name="manifest">
              <div class="manifest-toolbar">
                <el-button size="mini" plain icon="el-icon-document-copy" @click="copyManifest">复制 JSON</el-button>
              </div>
              <pre class="manifest-block">{{ formattedManifest }}</pre>
            </el-tab-pane>
          </el-tabs>
        </template>
        <el-empty v-else-if="!detailLoading" description="暂无详情数据" />
      </div>
    </el-drawer>
  </div>
</template>

<script>
import { listPlmPdfZipPush, getPlmPdfZipPush, downloadPlmDwgItem } from '@/api/system/plmPdfZipPush'

export default {
  name: 'PlmPdfZipPush',
  data() {
    return {
      loading: false,
      showSearch: true,
      total: 0,
      pushList: [],
      dateRange: [],
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        productionOrderNo: undefined,
        archiveName: undefined
      },
      detailOpen: false,
      detailLoading: false,
      detail: null,
      detailTab: 'items',
      downloadingItemId: null
    }
  },
  computed: {
    pageItemCount() {
      return this.pushList.reduce((sum, row) => sum + (Number(row.itemCount) || 0), 0)
    },
    detailTitle() {
      if (!this.detail) return '推送记录详情'
      const orderNo = this.detail.productionOrderNo || ''
      return orderNo ? `推送详情 · ${orderNo}` : '推送记录详情'
    },
    formattedManifest() {
      if (!this.detail || !this.detail.manifestJson) return '—'
      try {
        return JSON.stringify(JSON.parse(this.detail.manifestJson), null, 2)
      } catch (e) {
        return this.detail.manifestJson
      }
    }
  },
  created() {
    this.getList()
  },
  methods: {
    headerCellStyle() {
      return {
        background: '#f0f5f4',
        color: '#1a3a36',
        fontWeight: '600',
        fontSize: '13px'
      }
    },
    tableRowClassName({ rowIndex }) {
      return rowIndex % 2 === 0 ? 'row-even' : 'row-odd'
    },
    buildQueryParams() {
      let params = { ...this.queryParams }
      params = this.addDateRange(params, this.dateRange, 'ReceiveTime')
      return params
    },
    getList() {
      this.loading = true
      listPlmPdfZipPush(this.buildQueryParams())
        .then(response => {
          this.pushList = 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 = 'items'
      getPlmPdfZipPush(row.id)
        .then(response => {
          this.detail = response.data || null
        })
        .finally(() => {
          this.detailLoading = false
        })
    },
    resetDetail() {
      this.detail = null
      this.detailTab = 'items'
    },
    copyManifest() {
      if (!this.formattedManifest || this.formattedManifest === '—') {
        this.$modal.msgWarning('暂无可复制的 JSON')
        return
      }
      const textarea = document.createElement('textarea')
      textarea.value = this.formattedManifest
      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)
    },
    async downloadDwgItem(row) {
      if (!row || row.id == null) return
      this.downloadingItemId = row.id
      try {
        const response = await downloadPlmDwgItem(row.id)
        if (!(response instanceof Blob)) {
          this.$modal.msgError('下载失败：服务器返回异常')
          return
        }
        const contentType = (response.type || '').toLowerCase()
        if (contentType.includes('application/json')) {
          const text = await response.text()
          try {
            const json = JSON.parse(text)
            this.$modal.msgError(json.msg || '下载失败')
          } catch (_) {
            this.$modal.msgError(text || '下载失败')
          }
          return
        }
        if (response.size === 0) {
          this.$modal.msgError('下载失败：文件为空')
          return
        }
        const filename = row.savedDwgFileName || `${row.materialCode || 'drawing'}.dwg`
        const blob = new Blob([response], { type: 'application/octet-stream' })
        const url = window.URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = url
        link.download = filename
        link.click()
        window.URL.revokeObjectURL(url)
        this.$modal.msgSuccess('DWG下载成功')
      } catch (e) {
        let msg = '下载失败'
        try {
          const data = e && e.response && e.response.data
          if (data instanceof Blob) {
            const text = await data.text()
            const json = JSON.parse(text)
            msg = json.msg || msg
          } else if (e && e.message) {
            msg = e.message
          }
        } catch (_) {
          // ignore
        }
        this.$modal.msgError(msg)
      } finally {
        this.downloadingItemId = null
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.plm-push-page {
  --plm-teal: #00b4ad;
  --plm-teal-dark: #008f89;
  --plm-slate: #1a3a36;
  --plm-bg: #f4f8f7;
  --plm-border: #d8e8e5;
  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);
  position: relative;
  overflow: hidden;

  &::after {
    content: '';
    position: absolute;
    right: -40px;
    top: -40px;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(0, 180, 173, 0.25) 0%, transparent 70%);
    pointer-events: none;
  }
}

.page-hero__main {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  position: relative;
  z-index: 1;
}

.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: #7ee8e3;
  font-size: 24px;
  flex-shrink: 0;
}

.page-hero__title {
  margin: 0 0 6px;
  font-size: 22px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.02em;
}

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

.page-hero__stats {
  display: flex;
  gap: 12px;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}

.stat-chip {
  min-width: 96px;
  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.18);
    border-color: rgba(0, 180, 173, 0.35);
  }
}

.stat-chip__label {
  display: block;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.6);
  margin-bottom: 4px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.stat-chip__value {
  display: block;
  font-size: 22px;
  font-weight: 700;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.search-card,
.table-card {
  border-radius: 10px;
  border: 1px solid var(--plm-border);
  margin-bottom: 12px;

  ::v-deep .el-card__body {
    padding: 16px 18px;
  }
}

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

.search-form {
  margin-bottom: 0;
}

.order-no {
  font-weight: 600;
  color: var(--plm-slate);
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 13px;
}

.archive-cell {
  display: flex;
  align-items: center;
  gap: 8px;
}

.archive-cell__icon {
  color: var(--plm-teal);
  font-size: 16px;
}

.path-text {
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 12px;
  color: #5a6b68;
  background: #eef5f4;
  padding: 2px 6px;
  border-radius: 4px;

  &--sm {
    font-size: 11px;
    padding: 1px 4px;
    background: transparent;
  }
}

.dwg-path-cell {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;

  .path-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.time-text {
  font-size: 13px;
  color: #606266;
  font-variant-numeric: tabular-nums;
}

.detail-body {
  min-height: 200px;
  padding: 0 4px;
}

.detail-summary {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin-bottom: 18px;
  padding: 16px;
  border-radius: 10px;
  background: #f0f7f6;
  border: 1px solid var(--plm-border);
}

.detail-summary__item {
  display: flex;
  flex-direction: column;
  gap: 4px;

  &--wide {
    grid-column: 1 / -1;
  }
}

.detail-summary__label {
  font-size: 11px;
  color: #8a9a97;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.detail-summary__value {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
}

.detail-summary__path {
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 12px;
  color: #5a6b68;
  word-break: break-all;
}

.detail-tabs {
  ::v-deep .el-tabs__header {
    margin-bottom: 12px;
  }

  ::v-deep .el-tabs__item.is-active {
    color: var(--plm-teal-dark);
  }

  ::v-deep .el-tabs__active-bar {
    background-color: var(--plm-teal);
  }
}

.manifest-toolbar {
  margin-bottom: 10px;
}

.manifest-block {
  margin: 0;
  padding: 14px 16px;
  max-height: 420px;
  overflow: auto;
  border-radius: 8px;
  background: #1e2d2b;
  color: #a8e6cf;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 12px;
  line-height: 1.65;
  white-space: pre-wrap;
  word-break: break-all;
  border: 1px solid #2d4a46;
}

::v-deep .plm-detail-drawer .el-drawer__header {
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--plm-border);
  font-weight: 700;
  color: var(--plm-slate);
}

::v-deep .row-even td {
  background: #fafcfb !important;
}
</style>
