<template>
  <section class="page-grid">
    <section class="panel">
      <div class="page-hero-card purchase-chain-hero quality-inspection-hero">
        <div class="page-hero-copy">
          <p class="eyebrow">质量检验</p>
          <div class="quality-title-row">
            <h3>{{ activeTab === "pending" ? "采购到货待质检" : "已判定批次追踪" }}</h3>
            <div class="inventory-tabbar quality-title-tabbar">
              <button
                class="inventory-tab"
                :class="{ 'inventory-tab-active': activeTab === 'pending' }"
                type="button"
                @click="activeTab = 'pending'"
              >
                <strong>待检清单</strong>
                <span>{{ filteredPendingRows.length }}</span>
              </button>
              <button
                class="inventory-tab"
                :class="{ 'inventory-tab-active': activeTab === 'completed' }"
                type="button"
                @click="activeTab = 'completed'"
              >
                <strong>最近检验结果</strong>
                <span>{{ filteredCompletedRows.length }}</span>
              </button>
            </div>
          </div>
          <p class="page-hero-subtitle">按批次完成采购到货放行或拒收，并保留最近质检结论与备注线索。</p>
        </div>
        <div class="page-hero-actions">
          <span class="panel-tag">{{ activeTab === "pending" ? "仓库待放行" : "质量记录" }}</span>
        </div>
      </div>

      <div v-if="feedbackMessage" class="feedback-banner">{{ feedbackMessage }}</div>
      <div v-if="errorMessage" class="feedback-banner error-banner">{{ errorMessage }}</div>

      <div v-if="activeTab === 'pending'" class="inventory-tab-panel">
        <TableControls
          v-model:search="pendingControls.search.value"
          v-model:sort-key="pendingControls.sortKey.value"
          v-model:sort-direction="pendingControls.sortDirection.value"
          :sort-options="pendingControls.sortOptions"
          placeholder="搜索入库单、供应商、物料、批次、状态"
        />

        <div class="table-wrap">
          <table class="data-table compact-table">
            <thead>
              <tr>
                <th>入库单</th>
                <th>到货库类型</th>
                <th>供应商</th>
                <th>物料</th>
                <th>库存批次号</th>
                <th>收货量</th>
                <th>状态</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="row in paginatedPendingRows"
                :key="row.receipt_item_id"
                :class="{ 'row-selected': selectedId === row.receipt_item_id }"
                @click="selectedId = row.receipt_item_id"
              >
                <td>{{ row.receipt_no }}</td>
                <td><span class="table-chip">{{ purchaseTargetLabel(row.target_warehouse_type) }}</span></td>
                <td>{{ row.supplier_name }}</td>
                <td>{{ row.material_name }}</td>
                <td>{{ row.lot_no }}</td>
                <td>{{ formatInspectionReceived(row) }}</td>
                <td><StatusBadge :value="row.status" /></td>
                <td class="action-row">
                  <button class="ghost-button" type="button" @click.stop="openInspectionRemarkDialog(row, 'PASS')">放行</button>
                  <button class="ghost-button danger-ghost" type="button" @click.stop="openInspectionRemarkDialog(row, 'REJECT')">
                    拒收
                  </button>
                </td>
              </tr>
              <tr v-if="!filteredPendingRows.length">
                <td colspan="8" class="empty-row">当前没有待检批次</td>
              </tr>
            </tbody>
          </table>
        </div>
        <PaginationBar v-model:page="pendingPage" v-model:page-size="pendingPageSize" :total="filteredPendingRows.length" />
      </div>

      <div v-else class="inventory-tab-panel">
        <TableControls
          v-model:search="completedControls.search.value"
          v-model:sort-key="completedControls.sortKey.value"
          v-model:sort-direction="completedControls.sortDirection.value"
          :sort-options="completedControls.sortOptions"
          placeholder="搜索入库单、物料、批次、质检状态、备注"
        />

        <div class="table-wrap">
          <table class="data-table compact-table">
            <thead>
              <tr>
                <th>入库单</th>
                <th>到货库类型</th>
                <th>物料</th>
                <th>库存批次号</th>
                <th>合格量</th>
                <th>质检状态</th>
                <th>备注</th>
                <th class="quality-archive-col">归档</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="row in paginatedCompletedRows" :key="row.receipt_item_id">
                <td>{{ row.receipt_no }}</td>
                <td><span class="table-chip">{{ purchaseTargetLabel(row.target_warehouse_type) }}</span></td>
                <td>{{ row.material_name }}</td>
                <td>{{ row.lot_no }}</td>
                <td>{{ formatInspectionAccepted(row) }}</td>
                <td><StatusBadge :value="row.quality_status" :text="formatQualityStatusLabel(row.quality_status)" /></td>
                <td>{{ [row.inspector_name, row.remark].filter(Boolean).join(" / ") || "-" }}</td>
                <td class="quality-archive-cell">
                  <div class="quality-archive-actions-compact">
                    <DocumentArchiveActions
                      :status="row.archive_status"
                      @preview="previewDocumentArchive('quality-inspection', row.receipt_item_id)"
                      @download="downloadDocumentArchive('quality-inspection', row.receipt_item_id, `${row.receipt_no || '质量校验单'}-${row.lot_no || row.receipt_item_id}归档.pdf`)"
                      @regenerate="regenerateDocumentArchive('quality-inspection', row.receipt_item_id)"
                    />
                  </div>
                </td>
              </tr>
              <tr v-if="!filteredCompletedRows.length">
                <td colspan="8" class="empty-row">暂无已判定记录</td>
              </tr>
            </tbody>
          </table>
        </div>
        <PaginationBar v-model:page="completedPage" v-model:page-size="completedPageSize" :total="filteredCompletedRows.length" />
      </div>

      <Teleport to="body">
        <div v-if="showInspectionRemarkDialog" class="quality-remark-modal-mask" @click.self="closeInspectionRemarkDialog">
          <section class="quality-remark-modal" role="dialog" aria-modal="true" aria-label="校验备注">
            <DocumentPaper
              title="质量校验单"
              document-no="保存后自动生成"
              :signature-labels="['质检确认', '仓库复核', '采购确认', '制单人']"
              tone="green"
            >
              <DocumentGrid :fields="inspectionDocumentHeaderFields" columns="3">
                <template #inspection_no>
                  <span class="quality-document-static-value">保存后自动生成</span>
                </template>
                <template #inspection_result>
                  <span class="quality-result-pill" :class="{ 'quality-result-reject': pendingInspectionResult === 'REJECT' }">
                    {{ inspectionResultLabel(pendingInspectionResult) }}
                  </span>
                </template>
                <template #remark>
                  <textarea
                    v-model.trim="inspectionRemark"
                    rows="3"
                    placeholder="可填写尺寸偏差、表面划伤、重量偏差等检验结论，也可以留空"
                  ></textarea>
                </template>
              </DocumentGrid>

              <DocumentLineTable title="质检明细" :columns="inspectionDocumentLineColumns">
                <tr v-if="pendingInspectionRow">
                  <td class="document-line-index">1</td>
                  <td>{{ pendingInspectionRow.material_code || "-" }}</td>
                  <td>{{ pendingInspectionRow.material_name || "-" }}</td>
                  <td>{{ pendingInspectionRow.lot_no || "-" }}</td>
                  <td>{{ formatInspectionReceived(pendingInspectionRow) }}</td>
                  <td>{{ formatInspectionAcceptedPreview(pendingInspectionRow) }}</td>
                  <td>{{ purchaseTargetLabel(pendingInspectionRow.target_warehouse_type) }}</td>
                </tr>
              </DocumentLineTable>
            </DocumentPaper>

            <div class="quality-remark-actions">
              <button class="ghost-button" type="button" @click="closeInspectionRemarkDialog">取消</button>
              <button class="primary-button" type="button" @click="confirmInspectionResult">
                {{ pendingInspectionResult === "PASS" ? "确认放行" : "确认拒收" }}
              </button>
            </div>
          </section>
        </div>
      </Teleport>
    </section>
  </section>
</template>

<script setup>
import { computed, onMounted, ref } from "vue";

import DocumentArchiveActions from "../components/documentForms/DocumentArchiveActions.vue";
import DocumentGrid from "../components/documentForms/DocumentGrid.vue";
import DocumentLineTable from "../components/documentForms/DocumentLineTable.vue";
import DocumentPaper from "../components/documentForms/DocumentPaper.vue";
import PaginationBar from "../components/PaginationBar.vue";
import StatusBadge from "../components/StatusBadge.vue";
import TableControls from "../components/TableControls.vue";
import { downloadResource, fetchResource, openResource, postResource } from "../services/api";
import { formatWeight } from "../utils/formatters";
import { formatQualityStatusLabel } from "../utils/dictionaries";
import { usePagination } from "../utils/pagination";
import { useTableControls } from "../utils/tableControls";

const inspections = ref([]);
const selectedId = ref(null);
const inspectionRemark = ref("");
const feedbackMessage = ref("");
const errorMessage = ref("");
const activeTab = ref("pending");
const showInspectionRemarkDialog = ref(false);
const pendingInspectionRow = ref(null);
const pendingInspectionResult = ref("PASS");

const pendingRows = computed(() => inspections.value.filter((item) => item.status === "PENDING_QC"));
const completedRows = computed(() => inspections.value.filter((item) => item.status !== "PENDING_QC"));
const pendingControls = useTableControls(pendingRows, {
  searchFields: ["receipt_no", "po_no", (row) => purchaseTargetLabel(row.target_warehouse_type), "supplier_name", "material_name", "material_code", "lot_no", "status"],
  sortOptions: [
    { key: "receipt_no", label: "入库单" },
    { key: "target_warehouse_type", label: "到货库类型" },
    { key: "supplier_name", label: "供应商" },
    { key: "material_name", label: "物料" },
    { key: "lot_no", label: "库存批次号" },
    { key: "received_weight_kg", label: "收货量" },
    { key: "receipt_date", label: "收货时间" }
  ],
  defaultSortKey: "receipt_date",
  defaultSortDirection: "desc"
});
const completedControls = useTableControls(completedRows, {
  searchFields: ["receipt_no", (row) => purchaseTargetLabel(row.target_warehouse_type), "material_name", "material_code", "lot_no", "quality_status", "inspector_name", "remark"],
  sortOptions: [
    { key: "receipt_no", label: "入库单" },
    { key: "target_warehouse_type", label: "到货库类型" },
    { key: "material_name", label: "物料" },
    { key: "lot_no", label: "库存批次号" },
    { key: "accepted_weight_kg", label: "合格量" },
    { key: "quality_status", label: "质检状态" },
    { key: "receipt_date", label: "收货时间" }
  ],
  defaultSortKey: "receipt_date",
  defaultSortDirection: "desc"
});
const filteredPendingRows = pendingControls.rows;
const filteredCompletedRows = completedControls.rows;
const {
  page: pendingPage,
  pageSize: pendingPageSize,
  rows: paginatedPendingRows
} = usePagination(filteredPendingRows);
const {
  page: completedPage,
  pageSize: completedPageSize,
  rows: paginatedCompletedRows
} = usePagination(filteredCompletedRows);
const inspectionDocumentHeaderFields = computed(() => [
  { key: "inspection_no", label: "质检单号", value: "保存后自动生成" },
  { key: "receipt_no", label: "入库单", value: pendingInspectionRow.value?.receipt_no || "-" },
  { key: "po_no", label: "采购订单", value: pendingInspectionRow.value?.po_no || "-" },
  { key: "supplier_name", label: "供应商", value: pendingInspectionRow.value?.supplier_name || "-" },
  { key: "warehouse_name", label: "到货仓库", value: pendingInspectionRow.value?.warehouse_name || "-" },
  { key: "inspection_result", label: "检验结论", value: inspectionResultLabel(pendingInspectionResult.value) },
  { key: "remark", label: "校验备注", value: inspectionRemark.value || "", class: "quality-document-remark-cell" }
]);
const inspectionDocumentLineColumns = [
  { key: "index", label: "序号", width: "58px", class: "document-line-index" },
  { key: "material_code", label: "物料编码", width: "17%" },
  { key: "material_name", label: "物料名称", width: "21%" },
  { key: "lot_no", label: "库存批次号", width: "22%" },
  { key: "received", label: "收货量", width: "14%" },
  { key: "accepted", label: "合格量", width: "14%" },
  { key: "warehouse", label: "到货库", width: "12%" }
];

function normalizePurchaseTargetType(value) {
  return String(value || "RAW").toUpperCase() === "AUX" ? "AUX" : "RAW";
}

function purchaseTargetLabel(value) {
  return normalizePurchaseTargetType(value) === "AUX" ? "辅料库" : "原材料库";
}

function formatQty(value) {
  return Number(value || 0).toLocaleString("zh-CN", {
    maximumFractionDigits: 3
  });
}

function isAuxInspection(row) {
  return normalizePurchaseTargetType(row?.target_warehouse_type) === "AUX";
}

function formatInspectionReceived(row) {
  return isAuxInspection(row) ? `${formatQty(row?.received_qty)} 件` : formatWeight(row?.received_weight_kg);
}

function formatInspectionAccepted(row) {
  return isAuxInspection(row) ? `${formatQty(row?.accepted_qty)} 件` : formatWeight(row?.accepted_weight_kg);
}

function formatInspectionAcceptedPreview(row) {
  if (pendingInspectionResult.value === "REJECT") {
    return isAuxInspection(row) ? "0 件" : formatWeight(0);
  }
  return formatInspectionReceived(row);
}

function inspectionResultLabel(result) {
  return result === "REJECT" ? "拒收" : "放行";
}

async function loadInspections() {
  inspections.value = await fetchResource("/quality/receipt-inspections", []);
  if (!selectedId.value && pendingRows.value.length) {
    selectedId.value = pendingRows.value[0].receipt_item_id;
  }
}

function openInspectionRemarkDialog(row, result) {
  feedbackMessage.value = "";
  errorMessage.value = "";
  pendingInspectionRow.value = row;
  pendingInspectionResult.value = result;
  inspectionRemark.value = "";
  showInspectionRemarkDialog.value = true;
}

function closeInspectionRemarkDialog() {
  showInspectionRemarkDialog.value = false;
  pendingInspectionRow.value = null;
  inspectionRemark.value = "";
}

async function confirmInspectionResult() {
  if (!pendingInspectionRow.value?.receipt_item_id) {
    errorMessage.value = "缺少待检批次，无法处理";
    closeInspectionRemarkDialog();
    return;
  }
  await inspect(pendingInspectionRow.value.receipt_item_id, pendingInspectionResult.value, inspectionRemark.value);
}

async function inspect(receiptItemId, result, remarkText = "") {
  feedbackMessage.value = "";
  errorMessage.value = "";
  try {
    const row = await postResource(`/quality/receipt-inspections/${receiptItemId}`, {
      result,
      remark: remarkText || null
    });
    feedbackMessage.value = `批次 ${row.lot_no} 已${result === "PASS" ? "放行" : "拒收"}`;
    closeInspectionRemarkDialog();
    await loadInspections();
  } catch (error) {
    errorMessage.value = error.message || "质检处理失败";
  }
}

async function previewDocumentArchive(typeKey, businessId) {
  feedbackMessage.value = "";
  errorMessage.value = "";
  try {
    await openResource(`/document-archives/${typeKey}/${businessId}/latest/preview`);
  } catch (error) {
    errorMessage.value = error.message || "PDF归档预览失败";
  }
}

async function downloadDocumentArchive(typeKey, businessId, fallbackFilename) {
  feedbackMessage.value = "";
  errorMessage.value = "";
  try {
    await downloadResource(`/document-archives/${typeKey}/${businessId}/latest/download`, fallbackFilename);
    feedbackMessage.value = "PDF归档已下载";
  } catch (error) {
    errorMessage.value = error.message || "PDF归档下载失败";
  }
}

async function regenerateDocumentArchive(typeKey, businessId) {
  feedbackMessage.value = "";
  errorMessage.value = "";
  try {
    const result = await postResource(`/document-archives/${typeKey}/${businessId}/generate`, {});
    feedbackMessage.value = result.message || "PDF归档已重新生成";
    await loadInspections();
  } catch (error) {
    errorMessage.value = error.message || "PDF归档重新生成失败";
  }
}

onMounted(async () => {
  await loadInspections();
});
</script>

<style scoped>
.quality-archive-col,
.quality-archive-cell {
  width: 188px;
  min-width: 188px;
}

.quality-archive-cell {
  overflow: visible;
  white-space: normal;
}

.quality-archive-actions-compact {
  width: 172px;
}

.quality-archive-actions-compact :deep(.document-archive-actions) {
  display: grid;
  gap: 6px;
}

.quality-archive-actions-compact :deep(.document-archive-status) {
  min-height: 24px;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 11px;
  line-height: 1.2;
  white-space: nowrap;
}

.quality-archive-actions-compact :deep(.document-archive-buttons) {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
}

.quality-archive-actions-compact :deep(.document-archive-button) {
  min-height: 26px;
  padding: 0 5px;
  border-radius: 8px;
  font-size: 11px;
  line-height: 1;
  white-space: nowrap;
}

.quality-archive-actions-compact :deep(.document-archive-icon) {
  display: none;
}

.quality-remark-modal-mask {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  padding: 28px;
  overflow: auto;
  background:
    radial-gradient(circle at 20% 18%, rgba(60, 126, 92, 0.22), transparent 34%),
    radial-gradient(circle at 82% 76%, rgba(173, 74, 48, 0.18), transparent 32%),
    rgba(17, 24, 39, 0.58);
  backdrop-filter: blur(10px);
}

.quality-remark-modal {
  width: min(1060px, calc(100vw - 42px));
  border: 1px solid rgba(43, 68, 51, 0.18);
  border-radius: 28px;
  background: linear-gradient(145deg, rgba(248, 244, 232, 0.96), rgba(239, 232, 214, 0.94));
  box-shadow:
    0 30px 80px rgba(15, 23, 42, 0.32),
    inset 0 1px 0 rgba(255, 255, 255, 0.72);
}

.quality-remark-modal :deep(.document-paper-shell) {
  margin: 0;
  padding: 28px 28px 8px;
}

.quality-remark-modal :deep(.document-paper-sheet) {
  min-height: auto;
}

.quality-document-static-value {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  color: var(--document-paper-ink, #17120a);
  font-weight: 800;
}

.quality-result-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 32px;
  padding: 0 14px;
  border: 1px solid rgba(34, 120, 80, 0.28);
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(222, 247, 232, 0.96), rgba(190, 231, 210, 0.9));
  color: #17643f;
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.08em;
}

.quality-result-reject {
  border-color: rgba(190, 75, 75, 0.32);
  background: linear-gradient(180deg, rgba(255, 232, 226, 0.96), rgba(246, 202, 193, 0.92));
  color: #9e2f24;
}

.quality-document-remark-cell {
  grid-column: 1 / -1;
}

.quality-document-remark-cell textarea {
  width: 100%;
  resize: vertical;
}

.quality-remark-actions {
  position: sticky;
  bottom: 0;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 14px 28px 24px;
  border-radius: 0 0 28px 28px;
  background: linear-gradient(180deg, rgba(248, 244, 232, 0.3), rgba(248, 244, 232, 0.96) 34%);
}

@media (max-width: 760px) {
  .quality-remark-modal-mask {
    padding: 16px;
  }

  .quality-remark-modal {
    width: calc(100vw - 24px);
    border-radius: 22px;
  }

  .quality-remark-modal :deep(.document-paper-shell) {
    padding: 18px 14px 6px;
  }

  .quality-remark-actions {
    flex-direction: column-reverse;
    padding: 12px 18px 18px;
  }

  .quality-remark-actions > button {
    width: 100%;
  }
}
</style>
