<template>
  <section class="page-grid">
    <section class="panel">
      <div class="page-hero-card purchase-chain-hero purchase-receipt-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="primary-button" type="button" @click="openCreateDrawer">新增到货入库单</button>
        </div>
      </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="receiptControls.search.value"
        v-model:sort-key="receiptControls.sortKey.value"
        v-model:sort-direction="receiptControls.sortDirection.value"
        :sort-options="receiptControls.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 class="receipt-archive-col">归档</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="receipt in paginatedReceipts" :key="receipt.receipt_id" :class="{ 'row-selected': selectedReceiptId === receipt.receipt_id }">
              <td>
                <button class="link-button" type="button" @click="openDetailDrawer(receipt)">
                  {{ receipt.receipt_no }}
                </button>
              </td>
              <td>{{ receipt.po_no }}</td>
              <td><span class="table-chip">{{ purchaseTargetLabel(receipt.target_warehouse_type) }}</span></td>
              <td>{{ receipt.material_names || "-" }}</td>
              <td>{{ receipt.supplier_name }}</td>
              <td>{{ receipt.warehouse_name }}</td>
              <td>{{ formatDateTime(receipt.receipt_date) }}</td>
              <td>
                <StatusBadge :value="receipt.display_status || receipt.status" :text="formatStatusLabel(receipt.display_status || receipt.status)" />
              </td>
              <td class="receipt-archive-cell">
                <div class="receipt-archive-actions-compact">
                  <DocumentArchiveActions
                    :status="receipt.archive_status"
                    @preview="previewDocumentArchive('purchase-receipt', receipt.receipt_id)"
                    @download="downloadDocumentArchive('purchase-receipt', receipt.receipt_id, `${receipt.receipt_no || '到货入库单'}归档.pdf`)"
                    @regenerate="regenerateDocumentArchive('purchase-receipt', receipt.receipt_id)"
                  />
                </div>
              </td>
            </tr>
            <tr v-if="!filteredReceipts.length">
              <td colspan="9" class="empty-row">暂无到货入库单</td>
            </tr>
          </tbody>
        </table>
      </div>
      <PaginationBar v-model:page="receiptPage" v-model:page-size="receiptPageSize" :total="filteredReceipts.length" />
    </section>

    <FormDrawer
      :open="drawerOpen"
      eyebrow="到货入库"
      title="新增到货入库单"
      description="采购到货后登记收货；每次到货都会由系统自动生成新的库存批次号。"
      tag="待检入库"
      wide
      @close="drawerOpen = false"
    >
      <form class="stack-form receipt-document-form" @submit.prevent="submitReceipt">
        <DocumentPaper
          title="到货入库单"
          document-no="提交后自动生成"
          :signature-labels="['采购确认', '仓库接收', '质检交接', '制单人']"
          tone="green"
        >
          <DocumentGrid :fields="receiptDocumentHeaderFields" columns="3">
            <template #receipt_no>
              <span class="receipt-document-static-value">提交后自动生成</span>
            </template>
            <template #purchase_order>
              <select v-model.number="form.purchase_order_id" required>
                <option disabled value="">请选择采购订单</option>
                <option v-for="order in receivableOrders" :key="order.purchase_order_id" :value="order.purchase_order_id">
                  {{ formatReceiptOrderOption(order) }}
                </option>
              </select>
            </template>
            <template #target_warehouse_type>
              <span class="receipt-document-static-value">{{ selectedPoRecord ? purchaseTargetLabel(selectedPurchaseTargetType) : "待选择采购订单" }}</span>
            </template>
            <template #warehouse>
              <select v-model.number="form.warehouse_id" required>
                <option disabled value="">请选择仓库</option>
                <option v-for="warehouse in receiptWarehouses" :key="warehouse.id" :value="warehouse.id">
                  {{ warehouse.warehouse_name }}
                </option>
              </select>
            </template>
            <template #receiver>
              <select v-model.number="form.receiver_employee_id">
                <option value="">请选择</option>
                <option v-for="employee in employees" :key="employee.id" :value="employee.id">
                  {{ employeeOptionLabel(employee) }}
                </option>
              </select>
            </template>
            <template #waybill_no>
              <input v-model.trim="form.waybill_no" type="text" placeholder="可填运单号，或上传辅助照片" />
            </template>
            <template #freight_amount>
              <input v-model.number="form.freight_amount" type="number" min="0" step="0.01" required />
            </template>
            <template #order_photo>
              <label
                class="modern-upload-pill receipt-document-upload"
                :class="{ 'is-uploaded': form.order_photo_url, 'is-busy': logisticsPhotoUploading }"
              >
                <input
                  class="modern-upload-input"
                  type="file"
                  accept="image/*"
                  :disabled="logisticsPhotoUploading"
                  @change="handleLogisticsPhotoUpload"
                />
                <span class="modern-upload-icon" aria-hidden="true">{{ form.order_photo_url ? "✓" : "↑" }}</span>
                <strong>{{ logisticsPhotoUploading ? "上传中..." : form.order_photo_url ? "已上传辅助照片" : "上传辅助照片" }}</strong>
              </label>
              <small v-if="form.order_photo_url" class="modern-upload-note">已上传，可代替运单号</small>
            </template>
            <template #remark>
              <textarea v-model.trim="form.remark" rows="2"></textarea>
            </template>
          </DocumentGrid>

          <DocumentLineTable title="到货明细" :columns="receiptDocumentLineColumns">
            <template #actions>
              <button v-if="canAddReceiptRow" class="ghost-button" type="button" @click="addRow">增加明细行</button>
            </template>
            <tr v-for="(item, index) in form.items" :key="index">
              <td class="document-line-index">{{ index + 1 }}</td>
              <td>
                <span v-if="currentOrderItems.length === 1 && selectedPoItemForRow(item)" class="receipt-document-line-static">
                  {{ formatPoItemOption(selectedPoItemForRow(item)) }}
                </span>
                <select
                  v-else
                  v-model.number="item.purchase_order_item_id"
                  :disabled="!form.purchase_order_id"
                  @change="applyPoItem(index)"
                  required
                >
                  <option disabled value="">请选择采购明细</option>
                  <option v-for="poItem in currentOrderItems" :key="poItem.purchase_order_item_id" :value="poItem.purchase_order_item_id">
                    {{ formatPoItemOption(poItem) }}
                  </option>
                </select>
              </td>
              <td>
                <select v-model.number="item.location_id">
                  <option value="">默认库位</option>
                  <option v-for="location in currentLocations" :key="location.id" :value="location.id">
                    {{ location.location_name }}
                  </option>
                </select>
              </td>
              <td>
                <span class="receipt-document-line-static">系统自动生成库存批次号</span>
              </td>
              <td>
                <input v-model.number="item.unit_cost" type="number" min="0" step="0.0001" />
              </td>
              <td>
                <span class="receipt-document-line-static">{{ formatPoItemExpectedDate(selectedPoItemForRow(item)) }}</span>
              </td>
              <td>
                <input
                  v-if="selectedPurchaseTargetType === 'AUX'"
                  v-model.number="item.received_qty"
                  type="number"
                  min="0"
                  step="0.001"
                />
                <input v-else v-model.number="item.received_weight_kg" type="number" min="0" step="0.001" />
              </td>
              <td>
                <button
                  v-if="form.items.length > 1"
                  class="ghost-button danger-ghost table-action-button"
                  type="button"
                  @click="removeRow(index)"
                >
                  删除
                </button>
              </td>
            </tr>
          </DocumentLineTable>
        </DocumentPaper>

        <div class="drawer-form-actions receipt-document-actions">
          <button class="primary-button receipt-submit-button" type="submit" :disabled="submitting || logisticsPhotoUploading">
            {{ submitting ? "提交中..." : "创建到货入库单" }}
          </button>
        </div>
      </form>
    </FormDrawer>

    <FormDrawer
      :open="detailDrawerOpen"
      eyebrow="到货明细"
      :title="activeReceipt ? `${activeReceipt.receipt_no} · ${activeReceipt.supplier_name}` : '到货明细'"
      tag="待检批次"
      size="xl"
      @close="detailDrawerOpen = false"
    >
      <div v-if="activeReceipt" class="drawer-row-detail-grid">
        <article><span>运单号</span><strong>{{ activeReceipt.logistics_waybill_no || "-" }}</strong></article>
        <article><span>运费</span><strong>{{ formatFreight(activeReceipt.logistics_freight_amount) }}</strong></article>
        <article>
          <span>辅助照片</span>
          <strong>
            <button v-if="activeReceipt.logistics_photo_url" class="link-button" type="button" @click="openLogisticsPhoto(activeReceipt.logistics_photo_url)">查看</button>
            <span v-else>-</span>
          </strong>
        </article>
      </div>
      <TableControls
        v-model:search="receiptItemControls.search.value"
        v-model:sort-key="receiptItemControls.sortKey.value"
        v-model:sort-direction="receiptItemControls.sortDirection.value"
        :sort-options="receiptItemControls.sortOptions"
        placeholder="搜索物料、库存批次号、质检状态、库位"
      />
      <DrawerDataTable
        v-model:expanded-rows="expandedReceiptItemRows"
        :rows="paginatedReceiptItems"
        :columns="receiptItemDrawerColumns"
        row-key="receipt_item_id"
        empty-text="暂无到货明细"
      >
        <template #cell-lot_no="{ row }">
          <span class="drawer-cell-code" :title="row.lot_no || ''">{{ row.lot_no || "-" }}</span>
        </template>
        <template #detail="{ row }">
          <div class="drawer-row-detail-grid">
            <article><span>物料</span><strong>{{ row.material_name || "-" }}</strong></article>
            <article><span>库存批次号</span><strong>{{ row.lot_no || "-" }}</strong></article>
            <article>
              <span>质检状态</span>
              <strong><StatusBadge :value="row.quality_status" :text="formatQualityStatusLabel(row.quality_status)" /></strong>
            </article>
            <article><span>库位</span><strong>{{ row.location_name || "-" }}</strong></article>
          </div>
        </template>
      </DrawerDataTable>
      <PaginationBar v-model:page="receiptItemPage" v-model:page-size="receiptItemPageSize" :total="filteredReceiptItems.length" />
    </FormDrawer>
  </section>
</template>

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

import DrawerDataTable from "../components/DrawerDataTable.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 FormDrawer from "../components/FormDrawer.vue";
import PaginationBar from "../components/PaginationBar.vue";
import StatusBadge from "../components/StatusBadge.vue";
import TableControls from "../components/TableControls.vue";
import { downloadResource, fetchResource, openResource, postResource, uploadResource } from "../services/api";
import { PERSONNEL_PERMISSION_CODES, employeeOptionLabel, fetchPermissionEmployeeOptions } from "../services/employeeOptions";
import { formatDate, formatDateTime, formatWeight } from "../utils/formatters";
import { formatQualityStatusLabel, formatStatusLabel } from "../utils/dictionaries";
import { usePagination } from "../utils/pagination";
import { useTableControls } from "../utils/tableControls";

const orders = ref([]);
const orderItems = ref([]);
const warehouses = ref([]);
const locations = ref([]);
const employees = ref([]);
const receipts = ref([]);
const receiptItems = ref([]);
const feedbackMessage = ref("");
const errorMessage = ref("");
const submitting = ref(false);
const logisticsPhotoUploading = ref(false);
const selectedReceiptId = ref(null);
const drawerOpen = ref(false);
const detailDrawerOpen = ref(false);
const expandedReceiptItemRows = ref([]);

const form = reactive({
  purchase_order_id: "",
  warehouse_id: "",
  receiver_employee_id: "",
  waybill_no: "",
  order_photo_url: "",
  freight_amount: "",
  remark: "",
  items: [buildItemRow()]
});

const RECEIVABLE_ORDER_STATUSES = new Set(["LOCKED", "PENDING_QC", "PARTIAL", "PARTIAL_RECEIVED", "REJECTED"]);
const receivableOrders = computed(() =>
  orders.value.filter((order) =>
    RECEIVABLE_ORDER_STATUSES.has(String(order.status || "").toUpperCase()) ||
    RECEIVABLE_ORDER_STATUSES.has(String(order.display_status || "").toUpperCase())
  )
);
const currentOrderItems = computed(() => orderItems.value.filter((item) => item.purchase_order_id === Number(form.purchase_order_id)));
const canAddReceiptRow = computed(() => currentOrderItems.value.length > 1 && form.items.length < currentOrderItems.value.length);
const selectedPoRecord = computed(() => orders.value.find((o) => Number(o.purchase_order_id) === Number(form.purchase_order_id)) || null);
const selectedPurchaseTargetType = computed(() => normalizePurchaseTargetType(selectedPoRecord.value?.target_warehouse_type));
const receiptWarehouses = computed(() => {
  const poType = selectedPoRecord.value ? selectedPurchaseTargetType.value : null;
  if (poType) {
    return warehouses.value.filter((w) => normalizeWarehouseType(w) === poType);
  }
  return warehouses.value.filter((w) => ["RAW", "AUX"].includes(normalizeWarehouseType(w)));
});
const currentLocations = computed(() => locations.value.filter((item) => item.warehouse_id === Number(form.warehouse_id)));
const visibleReceiptItems = computed(() => {
  if (!selectedReceiptId.value) {
    return receiptItems.value;
  }
  return receiptItems.value.filter((item) => item.receipt_id === selectedReceiptId.value);
});
const receiptRows = computed(() =>
  receipts.value.map((receipt) => ({
    ...receipt,
    target_warehouse_label: purchaseTargetLabel(receipt.target_warehouse_type),
    material_names:
      receipt.material_names ||
      joinUniqueNames(receiptItems.value.filter((item) => item.receipt_id === receipt.receipt_id).map((item) => item.material_name)),
    display_status: deriveReceiptDisplayStatus(receipt)
  }))
);
const activeReceipt = computed(() => receiptRows.value.find((item) => item.receipt_id === selectedReceiptId.value) || null);
const receiptControls = useTableControls(receiptRows, {
  searchFields: ["receipt_no", "po_no", "target_warehouse_label", "material_names", "supplier_name", "warehouse_name", "display_status"],
  sortOptions: [
    { key: "receipt_no", label: "入库单号" },
    { key: "po_no", label: "采购单号" },
    { key: "target_warehouse_label", label: "到货库类型" },
    { key: "material_names", label: "物料" },
    { key: "receipt_date", label: "收货时间" },
    { key: "display_status", label: "状态" }
  ],
  defaultSortKey: "receipt_date",
  defaultSortDirection: "desc"
});
const filteredReceipts = receiptControls.rows;
const receiptItemControls = useTableControls(visibleReceiptItems, {
  searchFields: ["material_name", "lot_no", "quality_status", "location_name"],
  sortOptions: [
    { key: "lot_no", label: "库存批次号" },
    { key: "received_weight_kg", label: "收货量" },
    { key: "quality_status", label: "质检状态" }
  ],
  defaultSortKey: "lot_no",
  defaultSortDirection: "desc"
});
const filteredReceiptItems = receiptItemControls.rows;
const receiptItemDrawerColumns = computed(() => [
  { key: "material_name", label: "物料", type: "longText", width: "27%" },
  { key: "lot_no", label: "库存批次号", compactLabel: "库存批次", type: "code", width: "30%" },
  { key: "received_weight_kg", label: "收货量", type: "number", width: "106px", format: (_value, row) => formatReceiptItemReceived(row) },
  { key: "accepted_weight_kg", label: "合格量", type: "number", width: "106px", format: (_value, row) => formatReceiptItemAccepted(row) },
  { key: "quality_status", label: "质检状态", type: "status", width: "96px", format: (value) => formatQualityStatusLabel(value) },
  { key: "location_name", label: "库位", detailOnly: true }
]);
const receiptDocumentHeaderFields = computed(() => {
  const fields = [
    { key: "receipt_no", label: "入库单号", value: "提交后自动生成" },
    { key: "purchase_order", label: "采购订单", value: selectedPoRecord.value?.po_no || "" },
    { key: "target_warehouse_type", label: "到货库类型", value: purchaseTargetLabel(selectedPurchaseTargetType.value) },
    { key: "warehouse", label: "入库仓库", value: "" },
    { key: "receiver", label: "接收人", value: "" }
  ];
  if (selectedPurchaseTargetType.value === "RAW") {
    fields.push(
      { key: "waybill_no", label: "运单号", value: "" },
      { key: "freight_amount", label: "运费", value: "" },
      { key: "order_photo", label: "辅助照片", value: "" }
    );
  }
  fields.push({ key: "remark", label: "备注", value: form.remark || "" });
  return fields;
});
const receiptDocumentLineColumns = computed(() => [
  { key: "index", label: "序号", width: "58px", class: "document-line-index" },
  { key: "purchase_order_item", label: "采购明细", width: "30%" },
  { key: "location", label: "库位", width: "13%" },
  { key: "lot_no", label: "库存批次号", width: "18%" },
  { key: "unit_cost", label: selectedPurchaseTargetType.value === "AUX" ? "入库单价(元/件)" : "入库单价(元/kg)", width: "14%" },
  { key: "expected_date", label: "明细交期", width: "110px" },
  { key: "received", label: selectedPurchaseTargetType.value === "AUX" ? "收货数量" : "收货重量(kg)", width: "14%" },
  { key: "actions", label: "操作", width: "88px" }
]);
const {
  page: receiptPage,
  pageSize: receiptPageSize,
  rows: paginatedReceipts
} = usePagination(filteredReceipts);
const {
  page: receiptItemPage,
  pageSize: receiptItemPageSize,
  rows: paginatedReceiptItems
} = usePagination(filteredReceiptItems);

function buildItemRow() {
  return {
    purchase_order_item_id: "",
    material_item_id: "",
    location_id: "",
    received_qty: 0,
    received_weight_kg: 0,
    unit_cost: 0
  };
}

function joinUniqueNames(names) {
  const values = names.map((name) => String(name || "").trim()).filter(Boolean);
  return Array.from(new Set(values)).join("、");
}

function normalizeReceiptItemStatus(item) {
  const status = String(item.status || "").toUpperCase();
  const qualityStatus = String(item.quality_status || "").toUpperCase();
  if (status === "PASSED" || qualityStatus === "PASS") {
    return "PASSED";
  }
  if (status === "REJECTED" || qualityStatus === "REJECT") {
    return "REJECTED";
  }
  if (status === "PENDING_QC" || qualityStatus === "PENDING_QC") {
    return "PENDING_QC";
  }
  return status || qualityStatus;
}

function deriveReceiptDisplayStatus(receipt) {
  const items = receiptItems.value.filter((item) => Number(item.receipt_id) === Number(receipt.receipt_id));
  if (!items.length) {
    return receipt.status;
  }

  const statuses = items.map(normalizeReceiptItemStatus);
  if (statuses.some((status) => status === "PENDING_QC")) {
    return "PENDING_QC";
  }
  if (statuses.every((status) => status === "PASSED")) {
    return "PASSED";
  }
  if (statuses.every((status) => status === "REJECTED")) {
    return "REJECTED";
  }
  if (statuses.every((status) => ["PASSED", "REJECTED"].includes(status))) {
    return "PARTIAL";
  }
  return receipt.status;
}

function addRow() {
  const usedLineIds = new Set(form.items.map((item) => Number(item.purchase_order_item_id || 0)).filter(Boolean));
  const nextPoItem = currentOrderItems.value.find((item) => !usedLineIds.has(Number(item.purchase_order_item_id)));
  const nextRow = buildItemRow();
  if (nextPoItem) {
    nextRow.purchase_order_item_id = nextPoItem.purchase_order_item_id;
  }
  form.items.push(nextRow);
  if (nextPoItem) {
    applyPoItem(form.items.length - 1);
  }
}

function removeRow(index) {
  form.items.splice(index, 1);
}

function resetForm() {
  Object.assign(form, {
    purchase_order_id: "",
    warehouse_id: receiptWarehouses.value[0]?.id || "",
    receiver_employee_id: "",
    waybill_no: "",
    order_photo_url: "",
    freight_amount: "",
    remark: "",
    items: [buildItemRow()]
  });
}

function normalizeWarehouseType(item) {
  return String(item?.warehouse_type || "").toUpperCase();
}

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

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

function formatReceiptOrderMaterialNames(purchaseOrderId) {
  const names = orderItems.value
    .filter((item) => Number(item.purchase_order_id) === Number(purchaseOrderId))
    .map((item) => String(item.material_name || "").trim())
    .filter(Boolean);
  return Array.from(new Set(names)).join("、");
}

function formatReceiptOrderOption(order) {
  if (!order) {
    return "";
  }
  const materialNames = formatReceiptOrderMaterialNames(order.purchase_order_id);
  const materialSuffix = materialNames ? ` · ${materialNames}` : "";
  return `${order.po_no} · ${purchaseTargetLabel(order.target_warehouse_type)} · ${order.supplier_name || "-"}${materialSuffix}`;
}

function openCreateDrawer() {
  resetForm();
  drawerOpen.value = true;
}

function openDetailDrawer(receipt) {
  selectedReceiptId.value = receipt.receipt_id;
  expandedReceiptItemRows.value = [];
  detailDrawerOpen.value = true;
}

function selectedPoItemForRow(row) {
  return currentOrderItems.value.find((item) => Number(item.purchase_order_item_id) === Number(row.purchase_order_item_id)) || null;
}

function formatPoItemOption(poItem) {
  if (!poItem) {
    return "";
  }
  const isAux = selectedPurchaseTargetType.value === "AUX";
  const ordered = isAux ? `${formatQty(poItem.order_qty)}件` : formatWeight(poItem.order_weight_kg);
  const received = isAux ? `${formatQty(poItem.received_qty)}件` : formatWeight(poItem.received_weight_kg);
  return `${poItem.line_no} · ${poItem.material_name} · 采购 ${ordered} · 已收 ${received} · 明细交期 ${formatPoItemExpectedDate(poItem)}`;
}

function formatPoItemExpectedDate(poItem) {
  if (!poItem) {
    return "-";
  }
  return formatDate(poItem.expected_date || selectedPoRecord.value?.expected_date);
}

function syncReceiptRowsForPurchaseOrder() {
  const poItems = currentOrderItems.value;
  form.items.splice(0, form.items.length, buildItemRow());
  if (poItems.length === 1) {
    form.items[0].purchase_order_item_id = poItems[0].purchase_order_item_id;
    applyPoItem(0);
  }
}

function syncWarehouseForPurchaseOrder() {
  if (!form.purchase_order_id) {
    return;
  }
  const matchedWarehouses = receiptWarehouses.value;
  if (!matchedWarehouses.length) {
    form.warehouse_id = "";
    return;
  }
  if (!matchedWarehouses.some((warehouse) => Number(warehouse.id) === Number(form.warehouse_id))) {
    form.warehouse_id = matchedWarehouses[0].id;
  }
}

function applyPoItem(index) {
  const row = form.items[index];
  const poItem = currentOrderItems.value.find((item) => item.purchase_order_item_id === Number(row.purchase_order_item_id));
  if (!poItem) {
    return;
  }
  row.material_item_id = poItem.material_item_id;
  row.received_qty = selectedPurchaseTargetType.value === "AUX" ? remainingPurchaseQty(poItem) : 0;
  row.received_weight_kg = selectedPurchaseTargetType.value === "AUX" ? 0 : remainingPurchaseWeight(poItem);
  row.unit_cost = Number(poItem.unit_price || 0);
}

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

function formatFreight(value) {
  if (value === null || value === undefined || value === "") {
    return "-";
  }
  return `¥${Number(value || 0).toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}

function formatReceiptItemReceived(item) {
  const isAux = normalizePurchaseTargetType(receipts.value.find((row) => Number(row.receipt_id) === Number(item?.receipt_id))?.target_warehouse_type) === "AUX";
  return isAux ? `${formatQty(item.received_qty)} 件` : formatWeight(item.received_weight_kg);
}

function formatReceiptItemAccepted(item) {
  const isAux = normalizePurchaseTargetType(receipts.value.find((row) => Number(row.receipt_id) === Number(item?.receipt_id))?.target_warehouse_type) === "AUX";
  return isAux ? `${formatQty(item.accepted_qty)} 件` : formatWeight(item.accepted_weight_kg);
}

function remainingPurchaseWeight(poItem) {
  return Math.max(Number(poItem.order_weight_kg || 0) - Number(poItem.received_weight_kg || 0), 0);
}

function remainingPurchaseQty(poItem) {
  return Math.max(Number(poItem.order_qty || 0) - Number(poItem.received_qty || 0), 0);
}

function isFreightBlank(value) {
  return value === "" || value === null || value === undefined || Number.isNaN(Number(value));
}

function validateLogisticsForm() {
  if (selectedPurchaseTargetType.value !== "RAW") {
    return "";
  }
  if (!String(form.waybill_no || "").trim() && !String(form.order_photo_url || "").trim()) {
    return "请填写运单号或上传辅助照片";
  }
  if (isFreightBlank(form.freight_amount)) {
    return "请填写运费";
  }
  if (Number(form.freight_amount) < 0) {
    return "运费不能小于0";
  }
  return "";
}

async function handleLogisticsPhotoUpload(event) {
  const file = event.target.files?.[0];
  if (!file) {
    return;
  }
  const formData = new FormData();
  formData.append("file", file);
  logisticsPhotoUploading.value = true;
  try {
    const result = await uploadResource("/inventory/logistics-photos", formData);
    form.order_photo_url = result.url;
    feedbackMessage.value = "辅助照片已上传";
    errorMessage.value = "";
  } catch (error) {
    form.order_photo_url = "";
    errorMessage.value = error.message || "辅助照片上传失败";
  } finally {
    logisticsPhotoUploading.value = false;
    event.target.value = "";
  }
}

async function openLogisticsPhoto(url) {
  if (!url) {
    return;
  }
  try {
    await openResource(url);
  } 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 loadAll();
  } catch (error) {
    errorMessage.value = error.message || "PDF归档重新生成失败";
  }
}

async function loadAll() {
  const [orderRows, itemRows, warehouseRows, locationRows, employeeRows, receiptRows, receiptItemRows] = await Promise.all([
    fetchResource("/purchase/orders", []),
    fetchResource("/purchase/order-items", []),
    fetchResource("/master-data/warehouses", []),
    fetchResource("/master-data/locations", []),
    fetchPermissionEmployeeOptions(PERSONNEL_PERMISSION_CODES.PURCHASE_RECEIPT),
    fetchResource("/purchase/receipts", []),
    fetchResource("/purchase/receipt-items?limit=500", [])
  ]);
  orders.value = orderRows;
  orderItems.value = itemRows;
  warehouses.value = warehouseRows;
  locations.value = locationRows;
  employees.value = employeeRows;
  receipts.value = receiptRows;
  receiptItems.value = receiptItemRows;
}

async function submitReceipt() {
  feedbackMessage.value = "";
  errorMessage.value = "";
  submitting.value = true;
  try {
    const selectedPoId = Number(form.purchase_order_id || 0);
    const selectedWarehouseId = Number(form.warehouse_id || 0);
    if (!selectedPoId) {
      throw new Error("请选择采购订单");
    }
    if (!selectedWarehouseId) {
      throw new Error("请选择入库仓库");
    }
    const logisticsError = validateLogisticsForm();
    if (logisticsError) {
      throw new Error(logisticsError);
    }

    const selectedLineIds = new Set();
    form.items.forEach((item, index) => {
      const rowNo = index + 1;
      const poItemId = Number(item.purchase_order_item_id || 0);
      const materialItemId = Number(item.material_item_id || 0);
      const receivedQty = Number(item.received_qty || 0);
      const receivedWeight = Number(item.received_weight_kg || 0);
      const isAux = selectedPurchaseTargetType.value === "AUX";

      if (!poItemId) {
        throw new Error(`明细 ${rowNo} 请选择采购明细`);
      }
      if (!materialItemId) {
        throw new Error(`明细 ${rowNo} 缺少原材料，请重新选择采购明细`);
      }
      if (selectedLineIds.has(poItemId)) {
        throw new Error(`明细 ${rowNo} 的采购明细重复，请勿重复收货`);
      }
      selectedLineIds.add(poItemId);
      if (isAux && receivedQty <= 0) {
        throw new Error(`明细 ${rowNo} 的收货数量必须大于0`);
      }
      if (!isAux && receivedWeight <= 0) {
        throw new Error(`明细 ${rowNo} 的收货重量必须大于0`);
      }
      const poItem = currentOrderItems.value.find((candidate) => candidate.purchase_order_item_id === poItemId);
      if (!poItem) {
        throw new Error(`明细 ${rowNo} 的采购明细不存在，请重新选择`);
      }
    });
    const payloadWarehouseId = Number(form.warehouse_id || 0);
    if (!payloadWarehouseId) {
      throw new Error("请选择入库仓库");
    }

    const result = await postResource("/purchase/receipts", {
      purchase_order_id: selectedPoId,
      warehouse_id: payloadWarehouseId,
      receiver_employee_id: form.receiver_employee_id ? Number(form.receiver_employee_id) : null,
      waybill_no: selectedPurchaseTargetType.value === "RAW" ? form.waybill_no || null : null,
      order_photo_url: selectedPurchaseTargetType.value === "RAW" ? form.order_photo_url || null : null,
      freight_amount: selectedPurchaseTargetType.value === "RAW" ? Number(form.freight_amount) : null,
      remark: form.remark || null,
      items: form.items.map((item) => ({
        purchase_order_item_id: Number(item.purchase_order_item_id),
        material_item_id: Number(item.material_item_id),
        location_id: item.location_id ? Number(item.location_id) : null,
        received_qty: selectedPurchaseTargetType.value === "AUX" ? Number(item.received_qty || 0) : 0,
        received_weight_kg: selectedPurchaseTargetType.value === "AUX" ? 0 : Number(item.received_weight_kg || 0),
        unit_cost: Number(item.unit_cost || 0)
      }))
    });
    feedbackMessage.value = `到货入库单 ${result.receipt_no} 已创建`;
    selectedReceiptId.value = result.receipt_id;
    resetForm();
    drawerOpen.value = false;
    await loadAll();
  } catch (error) {
    errorMessage.value = error.message || "到货入库失败";
  } finally {
    submitting.value = false;
  }
}

watch(
  () => [form.purchase_order_id, currentOrderItems.value.map((item) => item.purchase_order_item_id).join("|")],
  () => {
    syncWarehouseForPurchaseOrder();
    syncReceiptRowsForPurchaseOrder();
  }
);

watch(
  () => form.warehouse_id,
  () => {
    form.items.forEach((item) => {
      item.location_id = "";
    });
  }
);

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

<style scoped>
.receipt-document-form {
  padding-bottom: 86px;
}

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

.receipt-document-line-static {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.receipt-archive-col,
.receipt-archive-cell {
  width: 188px;
  min-width: 188px;
}

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

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

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

.receipt-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;
}

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

.receipt-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;
}

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

.receipt-document-upload {
  min-height: 34px;
  padding: 7px 10px;
  border-radius: 6px;
}

.receipt-document-actions {
  position: fixed;
  right: max(38px, env(safe-area-inset-right));
  bottom: max(28px, env(safe-area-inset-bottom));
  z-index: 90;
  display: flex;
  justify-content: flex-end;
  width: auto;
  margin: 0;
  padding: 0;
  background: transparent;
  pointer-events: none;
}

.receipt-document-actions .receipt-submit-button {
  min-width: 188px;
  min-height: 44px;
  pointer-events: auto;
  box-shadow:
    0 14px 28px rgba(31, 122, 74, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.55);
}

@media (max-width: 760px) {
  .receipt-document-actions {
    right: max(18px, env(safe-area-inset-right));
    bottom: max(18px, env(safe-area-inset-bottom));
    width: calc(100vw - 36px);
  }

  .receipt-document-actions .receipt-submit-button {
    width: 100%;
  }
}
</style>
