<template>
  <section class="page-grid">
    <section class="panel">
      <div class="page-hero-card production-chain-hero production-ledger-hero">
        <div class="page-hero-copy">
          <p class="eyebrow">生产台账</p>
          <h3>按材料库存批次号和产品追踪仓库外生产流转</h3>
          <p class="page-hero-subtitle">以材料库存批次号串联领料、成品入库、余料归还和废料入库，保持生产闭环口径一致。</p>
        </div>
        <div class="page-hero-actions">
          <span class="panel-tag">材料批次 + 产品</span>
          <button class="ghost-button" type="button" @click="loadAll">刷新</button>
        </div>
      </div>

      <div
        v-if="!smartOperationReportEnabled"
        class="production-compact-tip production-mode-tip"
        title="当前未对接智能报工小程序，生产进度按成品入库数量和BOM毛重/净重反推；工序明细在此模式下隐藏。"
      >
        <strong>未对接智能报工小程序</strong>
        <span>生产进度按成品入库数量和BOM毛重/净重反推，工序明细隐藏。</span>
        <FieldHint text="当前未对接智能报工小程序，生产进度按成品入库数量和BOM毛重/净重反推；工序明细在此模式下隐藏。" />
      </div>
      <div v-if="feedbackMessage" class="feedback-banner">{{ feedbackMessage }}</div>
      <div v-if="errorMessage" class="feedback-banner error-banner">{{ errorMessage }}</div>

      <TableControls
        v-model:search="ledgerControls.search.value"
        v-model:sort-key="ledgerControls.sortKey.value"
        v-model:sort-direction="ledgerControls.sortDirection.value"
        :sort-options="ledgerControls.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>
              <th>状态</th>
            </tr>
          </thead>
          <tbody>
            <tr
              v-for="row in paginatedLedgers"
              :key="row.production_ledger_id"
              :class="{ 'row-selected': selectedLedgerId === row.production_ledger_id }"
            >
              <td>
                <button class="link-button" type="button" @click="openDetailDrawer(row)">
                  {{ row.material_lot_no || "-" }}
                </button>
              </td>
              <td>{{ formatItemLabel(row.product_code, row.product_name) }}</td>
              <td>{{ formatItemLabel(row.material_code, row.material_name) }}</td>
              <td>{{ formatWeight(row.total_issued_weight_kg) }}</td>
              <td>{{ formatWeight(row.outside_weight_kg) }}</td>
              <td>{{ formatQty(row.finished_inbound_qty) }}</td>
              <td>{{ formatWeight(row.surplus_inbound_weight_kg) }}</td>
              <td>{{ formatWeight(row.scrap_inbound_weight_kg) }}</td>
              <td><StatusBadge :value="row.status" /></td>
            </tr>
            <tr v-if="!filteredLedgers.length">
              <td colspan="9" class="empty-row">暂无生产台账</td>
            </tr>
          </tbody>
        </table>
      </div>
      <PaginationBar v-model:page="ledgerPage" v-model:page-size="ledgerPageSize" :total="filteredLedgers.length" />
    </section>

    <Teleport to="body">
      <div v-if="detailDrawerOpen" class="workflow-drawer-mask dual-drawer-mask work-order-detail-mask" @click.self="closeDetailDrawer">
        <div class="dual-drawer-shell">
          <aside class="workflow-drawer compact-side-drawer">
            <header class="workflow-drawer-head">
              <div>
                <p class="eyebrow">生产台账明细</p>
                <h3>{{ activeLedger?.material_lot_no || "材料库存批次号" }}</h3>
              </div>
              <button class="ghost-button" type="button" @click="closeDetailDrawer">关闭</button>
            </header>

            <div class="drawer-row-detail-grid">
              <article><span>产品</span><strong>{{ formatItemLabel(activeLedger?.product_code, activeLedger?.product_name) }}</strong></article>
              <article><span>原材料</span><strong>{{ formatItemLabel(activeLedger?.material_code, activeLedger?.material_name) }}</strong></article>
              <article><span>累计领料重量</span><strong>{{ formatWeight(activeLedger?.total_issued_weight_kg) }}</strong></article>
              <article><span>库外未闭环重量</span><strong>{{ formatWeight(activeLedger?.outside_weight_kg) }}</strong></article>
              <article><span>已入库成品</span><strong>{{ formatQty(activeLedger?.finished_inbound_qty) }}</strong></article>
              <article><span>已归还余料</span><strong>{{ formatWeight(activeLedger?.surplus_inbound_weight_kg) }}</strong></article>
              <article><span>已入库废料</span><strong>{{ formatWeight(activeLedger?.scrap_inbound_weight_kg) }}</strong></article>
              <article><span>状态</span><strong><StatusBadge :value="activeLedger?.status" /></strong></article>
            </div>

            <div v-if="activeLedger" class="production-archive-panel">
              <div>
                <span>生产领料出库单</span>
                <strong>{{ activeLedger.material_lot_no || "-" }}</strong>
              </div>
              <DocumentArchiveActions
                :status="activeLedger.material_out_archive_status"
                @preview="previewDocumentArchive('production-material-out', activeLedger.material_out_archive_business_id || activeLedger.production_ledger_id)"
                @download="downloadDocumentArchive('production-material-out', activeLedger.material_out_archive_business_id || activeLedger.production_ledger_id, `${activeLedger.material_lot_no || '生产领料出库单'}-${activeLedger.product_name || '产品'}归档.pdf`)"
                @regenerate="regenerateDocumentArchive('production-material-out', activeLedger.material_out_archive_business_id || activeLedger.production_ledger_id)"
              />
            </div>

            <div
              class="production-ledger-note"
              :title="`该行生产台账代表“${activeLedger?.material_lot_no || '材料库存批次号'}”用于生产“${activeLedger?.product_name || '产品'}”的仓库外总量。`"
            >
              该行生产台账代表“{{ activeLedger?.material_lot_no || "材料库存批次号" }}”用于生产“{{ activeLedger?.product_name || "产品" }}”的仓库外总量。
            </div>

            <button
              class="primary-button"
              type="button"
              :disabled="!canLockActiveLedger || lockingLedger"
              @click="lockActiveLedger"
            >
              {{ lockingLedger ? "结单中..." : "该批材料结单" }}
            </button>
          </aside>

          <aside class="workflow-drawer compact-side-drawer">
            <header class="workflow-drawer-head">
              <div>
                <p class="eyebrow">生产台账流水</p>
                <h3>{{ activeLedger?.product_name || "生产流转" }}</h3>
              </div>
            </header>

            <DrawerDataTable
              v-model:expanded-rows="expandedTxnRows"
              :rows="activeLedgerTxns"
              :columns="txnColumns"
              row-key="production_ledger_txn_id"
              empty-text="暂无生产台账流水"
            >
              <template #detail="{ row }">
                <div class="drawer-row-detail-grid">
                  <article><span>业务类型</span><strong>{{ row.txn_type || "-" }}</strong></article>
                  <article><span>数量变化</span><strong>{{ formatQty(row.qty_delta) }}</strong></article>
                  <article><span>重量变化</span><strong>{{ formatWeight(row.weight_delta_kg) }}</strong></article>
                  <article><span>变更后库外未闭环重量</span><strong>{{ formatWeight(row.outside_weight_after_kg) }}</strong></article>
                  <article><span>来源</span><strong>{{ row.source_doc_type || "-" }} #{{ row.source_doc_id || "-" }}</strong></article>
                  <article><span>时间</span><strong>{{ formatDateTime(row.biz_time) }}</strong></article>
                  <article><span>备注</span><strong>{{ row.remark || "-" }}</strong></article>
                </div>
                <div v-if="row.archive_business_id" class="production-archive-panel production-archive-panel-inline">
                  <div>
                    <span>生产入库结算单</span>
                    <strong>{{ row.txn_type || "-" }}</strong>
                  </div>
                  <DocumentArchiveActions
                    :status="row.archive_status"
                    @preview="previewDocumentArchive('production-inbound-settlement', row.archive_business_id)"
                    @download="downloadDocumentArchive('production-inbound-settlement', row.archive_business_id, `${activeLedger?.material_lot_no || '生产入库结算单'}-${row.txn_type || row.production_ledger_txn_id}归档.pdf`)"
                    @regenerate="regenerateDocumentArchive('production-inbound-settlement', row.archive_business_id)"
                  />
                </div>
              </template>
            </DrawerDataTable>

            <div
              v-if="smartOperationReportEnabled"
              class="production-compact-tip production-drawer-tip"
              title="工序明细由智能报工小程序按材料库存批次号回传，并在生产台账中用于辅助判断生产进度。"
            >
              <strong>小程序工序明细</strong>
              <span>按材料库存批次号回传，用于辅助判断生产进度。</span>
            </div>
            <div
              v-else
              class="production-compact-tip production-drawer-tip"
              title="当前未对接智能报工小程序，工序明细隐藏；系统按ERP入库数据反推生产进度。"
            >
              <strong>工序明细隐藏</strong>
              <span>当前未对接智能报工小程序，系统按ERP入库数据反推生产进度。</span>
            </div>
          </aside>
        </div>
      </div>
    </Teleport>
  </section>
</template>

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

import DocumentArchiveActions from "../components/documentForms/DocumentArchiveActions.vue";
import DrawerDataTable from "../components/DrawerDataTable.vue";
import FieldHint from "../components/FieldHint.vue";
import PaginationBar from "../components/PaginationBar.vue";
import StatusBadge from "../components/StatusBadge.vue";
import TableControls from "../components/TableControls.vue";
import { useBodyScrollLock } from "../composables/useBodyScrollLock";
import { downloadResource, fetchResource, openResource, postResource } from "../services/api";
import { loadSmartOperationReportConfig } from "../services/systemFeatures";
import { formatDateTime, formatQty, formatWeight } from "../utils/formatters";
import { usePagination } from "../utils/pagination";
import { useTableControls } from "../utils/tableControls";

const ledgers = ref([]);
const selectedLedgerId = ref(null);
const detailDrawerOpen = ref(false);
const expandedTxnRows = ref([]);
const feedbackMessage = ref("");
const errorMessage = ref("");
const lockingLedger = ref(false);
const smartOperationReportEnabled = ref(true);

const activeLedger = computed(() => ledgers.value.find((item) => Number(item.production_ledger_id) === Number(selectedLedgerId.value)) || null);
const activeLedgerTxns = computed(() => activeLedger.value?.txns || []);
const canLockActiveLedger = computed(() => activeLedger.value && activeLedger.value.status !== "锁单");

const ledgerControls = useTableControls(ledgers, {
  searchFields: ["material_lot_no", "product_code", "product_name", "material_code", "material_name", "status"],
  sortOptions: [
    { key: "material_lot_no", label: "材料库存批次号" },
    { key: "product_name", label: "产品" },
    { key: "material_name", label: "原材料" },
    { key: "total_issued_weight_kg", label: "累计领料重量" },
    { key: "outside_weight_kg", label: "库外未闭环重量" },
    { key: "finished_inbound_qty", label: "已入库成品" },
    { key: "status", label: "状态" }
  ],
  defaultSortKey: "material_lot_no",
  defaultSortDirection: "desc"
});

const filteredLedgers = ledgerControls.rows;
const {
  page: ledgerPage,
  pageSize: ledgerPageSize,
  rows: paginatedLedgers
} = usePagination(filteredLedgers);

const txnColumns = computed(() => [
  { key: "txn_type", label: "业务类型", type: "longText", width: "22%" },
  { key: "weight_delta_kg", label: "重量变化", type: "number", width: "104px", format: (value) => formatWeight(value) },
  { key: "qty_delta", label: "数量变化", type: "number", width: "96px", format: (value) => formatQty(value) },
  { key: "outside_weight_after_kg", label: "库外未闭环重量", type: "number", width: "124px", format: (value) => formatWeight(value) },
  { key: "biz_time", label: "业务时间", type: "date", width: "136px", format: (value) => formatDateTime(value) },
  { key: "txn_detail", label: "流水详情", detailOnly: true }
]);

useBodyScrollLock(computed(() => detailDrawerOpen.value));

function formatItemLabel(code, name) {
  const safeName = name || "-";
  return code ? `${code} · ${safeName}` : safeName;
}

function openDetailDrawer(row) {
  selectedLedgerId.value = row.production_ledger_id;
  expandedTxnRows.value = [];
  detailDrawerOpen.value = true;
}

function closeDetailDrawer() {
  detailDrawerOpen.value = false;
}

async function lockActiveLedger() {
  if (!canLockActiveLedger.value) {
    return;
  }
  const confirmed = window.confirm(
    [
      "确认该批材料结单？",
      "",
      `材料库存批次号：${activeLedger.value.material_lot_no || "-"}`,
      `产品：${activeLedger.value.product_name || "-"}`,
      `库外未闭环重量：${formatWeight(activeLedger.value.outside_weight_kg)}`,
      "",
      "确认后该材料库存批次号将从小程序待选列表中剔除；系统会把当前库外未闭环重量作为结单核销记录。"
    ].join("\n")
  );
  if (!confirmed) {
    return;
  }
  lockingLedger.value = true;
  errorMessage.value = "";
  feedbackMessage.value = "";
  try {
    await postResource("/production/production-ledger-inbounds", {
      production_ledger_id: Number(activeLedger.value.production_ledger_id),
      finished_qty: 0,
      surplus_weight_kg: 0,
      scrap_weight_kg: 0,
      lock_material_batch: true,
      lock_confirmed: true,
      deviation_remark: "用户在生产台账执行该批材料结单",
      remark: "生产台账该批材料结单"
    });
    feedbackMessage.value = `材料库存批次号 ${activeLedger.value.material_lot_no || ""} 已结单`;
    await loadAll();
  } catch (error) {
    errorMessage.value = error.message || "该批材料结单失败";
  } finally {
    lockingLedger.value = false;
  }
}

async function previewDocumentArchive(typeKey, businessId) {
  feedbackMessage.value = "";
  errorMessage.value = "";
  if (!businessId) {
    errorMessage.value = "缺少归档业务ID，无法预览";
    return;
  }
  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 = "";
  if (!businessId) {
    errorMessage.value = "缺少归档业务ID，无法下载";
    return;
  }
  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 = "";
  if (!businessId) {
    errorMessage.value = "缺少归档业务ID，无法重新生成";
    return;
  }
  try {
    const result = await postResource(`/document-archives/${typeKey}/${businessId}/generate`, {});
    feedbackMessage.value = result.message || "PDF归档已重新生成";
    await loadAll();
  } catch (error) {
    errorMessage.value = error.message || "PDF归档重新生成失败";
  }
}

async function loadAll() {
  errorMessage.value = "";
  const [rows, config] = await Promise.all([
    fetchResource("/production/production-ledger?limit=500", []),
    loadSmartOperationReportConfig()
  ]);
  ledgers.value = Array.isArray(rows) ? rows : [];
  smartOperationReportEnabled.value = config.enabled !== false;
}

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

<style scoped>
.production-archive-panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin: 14px 0;
  padding: 12px 14px;
  border: 1px solid rgba(59, 130, 246, 0.18);
  border-radius: 16px;
  background: linear-gradient(135deg, rgba(239, 246, 255, 0.96), rgba(255, 255, 255, 0.9));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
}

.production-archive-panel > div:first-child {
  display: grid;
  gap: 4px;
}

.production-archive-panel span {
  color: var(--muted);
  font-size: 12px;
}

.production-archive-panel strong {
  color: var(--ink);
  font-size: 14px;
}

.production-archive-panel-inline {
  margin-top: 12px;
}
</style>
