<template>
  <div class="file-page animate-in">
    <div class="page-header">
      <div class="header-left">
        <h3>采购单管理</h3>
        <el-tag type="info" size="small">共 {{ total }} 个</el-tag>
      </div>
      <div class="header-actions">
        <el-button type="primary" :disabled="!selected.length" @click="batchMerge">
          合并选中 ({{ selected.length }})
        </el-button>
        <el-button :disabled="!selected.length" @click="batchDownload">
          批量下载
        </el-button>
        <el-button type="danger" :disabled="!selected.length" @click="batchDelete">
          批量删除
        </el-button>
      </div>
    </div>

    <el-table
      :data="items"
      v-loading="loading"
      @selection-change="onSelect"
      @sort-change="onSortChange"
      stripe
      style="width: 100%"
    >
      <el-table-column type="selection" width="45" />
      <el-table-column label="采购单文件名" min-width="200">
        <template #default="{ row }">
          <span class="file-name primary">{{ row.result_purchase || '--' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="" width="40" align="center">
        <template #default="{ row }">
          <el-icon :color="row.output_exists ? '#52C41A' : '#d1d5db'" :size="16">
            <Right />
          </el-icon>
        </template>
      </el-table-column>
      <el-table-column label="Excel处理文件" min-width="180">
        <template #default="{ row }">
          <span class="file-name secondary">{{ row.output_excel || '--' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="" width="40" align="center">
        <template #default="{ row }">
          <el-icon :color="row.input_exists ? '#52C41A' : '#d1d5db'" :size="16">
            <Right />
          </el-icon>
        </template>
      </el-table-column>
      <el-table-column label="Input图片" min-width="180">
        <template #default="{ row }">
          <span class="file-name secondary">{{ row.input_image || '--' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="状态" width="100" align="center">
        <template #default="{ row }">
          <el-tag :type="statusType(row.status)" size="small">{{ statusText(row.status) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="创建时间" width="170" align="center" sortable="custom" prop="created_at">
        <template #default="{ row }">
          <span class="time-text">{{ fmtTime(row.created_at) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="240" fixed="right">
        <template #default="{ row }">
          <el-button link type="primary" size="small" @click="previewFile(row)">预览</el-button>
          <el-button link type="primary" size="small" @click="showDetail(row)">详情</el-button>
          <el-button link type="primary" size="small" @click="downloadFile(row)">下载</el-button>
          <el-button link type="danger" size="small" @click="deleteFile(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- Preview dialog -->
    <el-dialog v-model="showPreview" title="文件预览" :fullscreen="true" append-to-body :close-on-click-modal="false" class="preview-dialog" @close="cleanupPreview">
      <div class="preview-body">
        <div v-if="previewType === 'image'" class="preview-image-wrap">
          <img :src="previewSrc" style="max-width:100%;max-height:100%;object-fit:contain" />
        </div>
        <div v-else-if="previewType === 'excel'" class="preview-table-wrap">
          <table class="preview-table">
            <tr v-for="(row, ri) in previewRows" :key="ri">
              <td v-for="(cell, ci) in row" :key="ci">{{ cell }}</td>
            </tr>
          </table>
        </div>
        <div v-else style="text-align:center;color:var(--text-muted);padding:40px">暂无可预览内容</div>
      </div>
    </el-dialog>

    <!-- Detail dialog -->
    <el-dialog v-model="showDetailDlg" title="处理详情" width="70%" :close-on-click-modal="false" top="5vh">
      <div class="detail-logs">
        <div v-if="detailLogs.length === 0" style="text-align:center;color:var(--text-muted);padding:40px">暂无该文件的处理日志</div>
        <div v-for="(line, i) in detailLogs" :key="i" class="detail-line" :class="{err: line.includes('失败')||line.includes('错误'), ok: line.includes('完成')}">{{ line }}</div>
      </div>
      <template #footer>
        <el-button @click="showDetailDlg = false">关闭</el-button>
      </template>
    </el-dialog>

    <div class="pagination-wrap">
      <el-pagination
        v-model:current-page="page"
        :page-size="pageSize"
        :total="total"
        layout="total, prev, pager, next"
        @current-change="loadData"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Right } from '@element-plus/icons-vue'
import { useProcessingStore } from '../../stores/processing'
import api from '../../api'

const processingStore = useProcessingStore()

const items = ref<any[]>([])
const total = ref(0)
const page = ref(1)
const pageSize = 50
const loading = ref(true)
const selected = ref<any[]>([])
const sortBy = ref('created_at')
const sortOrder = ref('desc')

// Preview
const showPreview = ref(false)
const previewType = ref('')
const previewSrc = ref('')
const previewRows = ref<string[][]>([])

// Detail
const showDetailDlg = ref(false)
const detailLogs = ref<string[]>([])

function statusType(s: string) {
  const m: Record<string, string> = { done: 'success', merged: 'success', excel_done: 'warning', ocr_done: 'info', pending: 'info' }
  return m[s] || 'info'
}
function statusText(s: string) {
  const m: Record<string, string> = { done: '已完成', merged: '已合并', excel_done: '已处理', ocr_done: '已OCR', pending: '待处理' }
  return m[s] || s
}

function fmtTime(t: string): string {
  if (!t) return '--'
  return t.replace('T', ' ').slice(0, 19)
}

async function loadData() {
  loading.value = true
  try {
    const res = await api.get('/files/relations', { params: { view: 'orders', page: page.value, page_size: pageSize, sort_by: sortBy.value, sort_order: sortOrder.value } })
    items.value = res.data.items
    total.value = res.data.total
  } catch {}
  loading.value = false
}

function onSelect(rows: any[]) { selected.value = rows }

async function previewFile(row: any) {
  const token = localStorage.getItem('token')
  const fname = row.result_purchase || row.output_excel || row.input_image
  const dir = row.result_purchase ? 'result' : row.output_excel ? 'output' : 'input'
  const url = `/api/files/preview/${dir}/${encodeURIComponent(fname)}`

  try {
    const resp = await fetch(url, { headers: { Authorization: `Bearer ${token}` } })
    const ct = resp.headers.get('content-type') || ''

    if (ct.includes('image')) {
      previewType.value = 'image'
      const blob = await resp.blob()
      previewSrc.value = URL.createObjectURL(blob)
    } else {
      const data = await resp.json()
      if (data.type === 'excel') {
        previewType.value = 'excel'
        previewRows.value = data.rows
      }
    }
    showPreview.value = true
  } catch {
    ElMessage.error('预览失败')
  }
}

function cleanupPreview() {
  if (previewSrc.value && previewSrc.value.startsWith('blob:')) {
    URL.revokeObjectURL(previewSrc.value)
  }
  previewSrc.value = ''
  previewType.value = ''
  previewRows.value = []
}

function showDetail(row: any) {
  const fname = row.result_purchase || row.output_excel || row.input_image
  const stem = fname.replace(/\.[^.]+$/, '')
  // Filter logs from the processing store that mention this file
  detailLogs.value = (processingStore.logs || []).filter(
    (l: string) => l.includes(fname) || l.includes(stem)
  )
  showDetailDlg.value = true
}

function onSortChange({ prop, order }: any) {
  if (prop === 'created_at') {
    sortBy.value = 'created_at'
    sortOrder.value = order === 'ascending' ? 'asc' : 'desc'
  } else {
    sortBy.value = ''
    sortOrder.value = 'desc'
  }
  loadData()
}

async function downloadFile(row: any) {
  const token = localStorage.getItem('token')
  window.open(`/api/files/download/result/${encodeURIComponent(row.result_purchase)}?token=${token}`, '_blank')
}

async function deleteFile(row: any) {
  try {
    await ElMessageBox.confirm(`确定删除 ${row.result_purchase}？`, '确认')
    await api.delete(`/files/result/${encodeURIComponent(row.result_purchase)}`)
    if (row.id) await api.delete('/files/relations', { data: { ids: [row.id] } })
    ElMessage.success('已删除')
    loadData()
  } catch {}
}

async function batchMerge() {
  if (!selected.value.length) return
  try {
    const filenames = selected.value.map(r => r.result_purchase).filter(Boolean)
    const res = await api.post('/processing/merge-batch', { filenames })
    ElMessage.success(`合并任务已创建: ${res.data.task_id}`)
  } catch (err: any) {
    ElMessage.error(err.response?.data?.detail || '合并失败')
  }
}

async function batchDownload() {
  const token = localStorage.getItem('token')
  for (const row of selected.value) {
    if (row.result_purchase) {
      window.open(`/api/files/download/result/${encodeURIComponent(row.result_purchase)}?token=${token}`, '_blank')
    }
  }
}

async function batchDelete() {
  try {
    await ElMessageBox.confirm(`确定删除选中的 ${selected.value.length} 个文件？`, '确认')
    for (const row of selected.value) {
      if (row.result_purchase) {
        await api.delete(`/files/result/${encodeURIComponent(row.result_purchase)}`)
      }
      if (row.id) {
        await api.delete('/files/relations', { data: { ids: [row.id] } })
      }
    }
    ElMessage.success('批量删除完成')
    loadData()
  } catch {}
}

onMounted(loadData)
</script>

<style scoped>
.file-page {
  width: 100%;
}
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}
.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}
.header-left h3 {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
}
.header-actions {
  display: flex;
  gap: 8px;
}
.file-name.primary {
  font-weight: 600;
  color: var(--text-primary);
}
.file-name.secondary {
  color: var(--text-muted);
  font-size: 13px;
}
.time-text {
  font-size: 13px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.pagination-wrap {
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
}

.preview-table td {
  border: 1px solid var(--border-light);
  padding: 4px 8px;
  white-space: nowrap;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.preview-table tr:nth-child(even) { background: #fafafa; }
.preview-table tr:first-child { background: #f0f0f0; font-weight: 600; }

.detail-logs {
  max-height: 60vh;
  overflow-y: auto;
  background: #09090b;
  border-radius: 8px;
  padding: 14px;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.8;
}
.detail-line { color: #a1a1aa; }
.detail-line.err { color: #ef4444; }
.detail-line.ok { color: #22c55e; }

:global(.preview-dialog.el-dialog.is-fullscreen) { display:flex; flex-direction:column; width:96vw; height:94vh; margin:3vh 2vw; border-radius:12px!important }
:global(.preview-dialog.el-dialog.is-fullscreen) .el-dialog__header { flex-shrink:0 }
:global(.preview-dialog.el-dialog.is-fullscreen) .el-dialog__body { flex:1; min-height:0; padding:8px 16px 16px; overflow:hidden; display:flex; flex-direction:column }
.preview-body { flex:1; min-height:0; display:flex; flex-direction:column }
.preview-image-wrap { flex:1; display:flex; align-items:center; justify-content:center; min-height:0 }
.preview-table-wrap { flex:1; overflow:auto; min-height:0; border:1px solid var(--border-light); border-radius:8px }
.preview-table { border-collapse:collapse;font-size:12px;width:100% }
</style>
