import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join, resolve } from "node:path";

const __dirname = dirname(fileURLToPath(import.meta.url));
const source = readFileSync(join(__dirname, "InventoryLedgerView.vue"), "utf8");
const mainCss = readFileSync(resolve(__dirname, "../styles/main.css"), "utf8");

function functionBody(name) {
  const match = source.match(new RegExp(`async function ${name}\\(\\)[\\s\\S]*?\\n\\}`));
  assert.ok(match, `expected ${name} to exist`);
  return match[0];
}

function drawerBlock(openBinding, nextMarker) {
  const start = source.indexOf(`:open="${openBinding}"`);
  assert.ok(start >= 0, `expected drawer ${openBinding} to exist`);
  const end = source.indexOf(nextMarker, start + openBinding.length);
  assert.ok(end > start, `expected drawer ${openBinding} to end before ${nextMarker}`);
  return source.slice(start, end);
}

describe("InventoryLedgerView warehouse action layout", () => {
  it("keeps stocktake inside the tool action group instead of a standalone rack", () => {
    assert.equal(source.includes("warehouse-stocktake-rack"), false);
    assert.equal(source.includes("stocktake-launch-button"), false);

    const toolActionsMatch = source.match(/<div class="warehouse-tool-actions">([\s\S]*?)<\/div>/);
    assert.ok(toolActionsMatch, "expected warehouse tool action group to exist");
    assert.match(toolActionsMatch[1], /<strong>盘库<\/strong>/);
    assert.match(toolActionsMatch[1], /@click="openStocktakeDialog"/);
  });

  it("does not render the separate warehouse header strip above the switchboard", () => {
    assert.equal(source.includes("inventory-main-header"), false);
  });

  it("makes the selected warehouse card visibly heavier than inactive cards", () => {
    assert.match(mainCss, /\.warehouse-tab-card-active\s*\{[\s\S]*border:\s*2px solid color-mix\(in srgb,\s*currentColor 72%,\s*white 28%\);/);
    assert.match(mainCss, /\.warehouse-tab-card-active\s*\{[\s\S]*0 0 0 5px color-mix\(in srgb,\s*currentColor 14%,\s*transparent\)/);
    assert.match(mainCss, /\.warehouse-tab-card-active::before\s*\{[\s\S]*content:\s*"当前";/);
  });

  it("shows document archive actions in warehouse ledger rows", () => {
    assert.match(source, /DocumentArchiveActions/);
    assert.match(source, /warehouse-operation/);
    assert.match(source, /previewWarehouseLedgerArchive/);
    assert.match(source, /downloadWarehouseLedgerArchive/);
    assert.match(source, /regenerateWarehouseLedgerArchive/);
  });

  it("supports exporting warehouse ledger excel with current filters", () => {
    assert.match(source, /导出Excel/);
    assert.match(source, /exportWarehouseLedgerExcel/);
    assert.match(source, /\/inventory\/transaction-ledger\/export/);
    assert.match(source, /warehouseLedgerExporting/);
  });

  it("shows document archive actions in inventory detail transaction rows", () => {
    assert.match(source, /key:\s*"archive_actions"/);
    assert.match(source, /<template #cell-archive_actions="\{ row \}">/);
    assert.match(source, /单据留档/);
  });

  it("uses the shared paper document shell for warehouse operation forms", () => {
    assert.match(source, /import WarehouseDocumentFormShell/);
    assert.match(source, /import WarehouseDocumentSection/);
    assert.match(source, /import WarehouseDocumentActionBar/);
    assert.match(source, /<WarehouseDocumentFormShell/);
    assert.match(source, /<WarehouseDocumentSection/);
    assert.match(source, /<WarehouseDocumentActionBar/);
  });

  it("passes native dates to the paper document shell so it can render Chinese business dates", () => {
    assert.doesNotMatch(source, /formatDateTime\(new Date\(\)\)/);
    assert.match(source, /:business-date="new Date\(\)"/);
  });

  it("keeps production inbound preview fields in a full-width paper grid", () => {
    assert.doesNotMatch(source, /summary-grid compact-summary-grid/);
    assert.match(source, /warehouse-paper-summary-grid/);
    assert.match(mainCss, /\.warehouse-document-section-grid > \.warehouse-paper-summary-grid\s*\{[\s\S]*grid-column: 1 \/ -1;/);
    assert.match(mainCss, /\.warehouse-paper-summary-grid\s*\{[\s\S]*grid-template-columns: repeat\(4, minmax\(0, 1fr\)\);/);
  });

  it("keeps customer supplied inbound paper fields full width instead of squeezed into a side column", () => {
    assert.match(source, /title="客料入库单"/);
    assert.match(source, /class="warehouse-document-meta-strip"/);
    assert.match(source, /class="warehouse-paper-grid"/);
    assert.match(mainCss, /\.warehouse-document-operation-form\s*\{[\s\S]*width: 100%;/);
    assert.match(mainCss, /\.warehouse-document-section-grid > \.warehouse-document-meta-strip\s*\{[\s\S]*grid-column: 1 \/ -1;/);
    assert.match(mainCss, /\.warehouse-document-section-grid > \.warehouse-paper-grid\s*\{[\s\S]*grid-column: 1 \/ -1;/);
    assert.match(mainCss, /\.warehouse-paper-field > span\s*\{[\s\S]*font-size: 13px;/);
    assert.match(mainCss, /\.warehouse-paper-field input,[\s\S]*?\.warehouse-paper-field textarea\s*\{[\s\S]*font-size: 15px;/);
    assert.match(mainCss, /@media \(max-width: 520px\)[\s\S]*\.document-paper-binder,[\s\S]*\.document-retained-mark\s*\{[\s\S]*display: none;/);
    assert.match(mainCss, /@media \(max-width: 520px\)[\s\S]*\.document-paper-sheet\s*\{[\s\S]*padding: 18px 10px 22px;/);
    assert.match(mainCss, /body \.workflow-drawer\.form-drawer:has\(\.warehouse-document-operation-form\)\s*\{[\s\S]*width: min\(1280px, calc\(100vw - 24px\)\) !important;/);
    assert.match(mainCss, /body \.workflow-drawer\.form-drawer:has\(\.warehouse-document-operation-form\) \.form-drawer-body\s*\{[\s\S]*overflow-x: hidden !important;/);
    assert.match(mainCss, /body \.workflow-drawer\.form-drawer:has\(\.warehouse-document-operation-form\) \.document-paper-title\s*\{[\s\S]*font-size: clamp\(22px, 7\.2vw, 28px\) !important;/);
    assert.match(mainCss, /body \.workflow-drawer\.form-drawer:has\(\.warehouse-document-operation-form\) \.document-paper-title\s*\{[\s\S]*white-space: normal !important;/);
    assert.match(mainCss, /body \.workflow-drawer\.form-drawer:has\(\.warehouse-document-operation-form\) \.document-paper-title\s*\{[\s\S]*overflow-wrap: anywhere !important;/);
    assert.match(mainCss, /body \.workflow-drawer\.form-drawer:has\(\.warehouse-document-operation-form\) \.document-number-stamp\s*\{[\s\S]*width: min\(176px, 100%\) !important;/);
    assert.match(mainCss, /body \.workflow-drawer\.form-drawer:has\(\.warehouse-document-operation-form\) \.form-drawer-body\s*\{[\s\S]*padding: 10px !important;/);
  });

  it("wraps production-ledger controlled inbound forms in the shared paper control language", () => {
    assert.match(source, /warehouse-paper-control-grid/);
    assert.match(source, /warehouse-paper-source-lot-panel/);
    assert.match(source, /warehouse-paper-source-lot-table/);
    assert.match(source, /warehouse-paper-inline-summary/);
    assert.match(source, /warehouse-paper-settle-panel/);
    assert.match(source, /warehouse-paper-settle-toggle/);
    assert.match(source, /warehouse-paper-settle-grid/);
    assert.match(source, /warehouse-paper-settle-remark/);
    assert.match(mainCss, /\.warehouse-document-section-grid > \.warehouse-paper-control-grid\s*\{[\s\S]*grid-column: 1 \/ -1;/);
    assert.match(mainCss, /\.warehouse-paper-control-grid\s*\{[\s\S]*grid-template-columns: repeat\(4, minmax\(0, 1fr\)\);/);
    assert.match(mainCss, /\.warehouse-paper-source-lot-table/);
    assert.match(mainCss, /\.warehouse-paper-settle-toggle/);
  });

  it("keeps special adjustment documents inside the paper document language", () => {
    const specialAdjustmentBlock = source.slice(
      source.indexOf(':open="specialAdjustmentDrawerOpen"'),
      source.indexOf(':open="productionDrawerOpen"')
    );
    assert.match(source, /special-adjustment-paper-grid/);
    assert.match(source, /special-adjustment-paper-warning/);
    assert.match(source, /special-adjustment-paper-lines/);
    assert.match(source, /special-adjustment-paper-line-card/);
    assert.doesNotMatch(specialAdjustmentBlock, /<div class="double-field">[\s\S]*?specialAdjustmentForm\.reason/);
    assert.match(mainCss, /\.special-adjustment-paper-grid/);
    assert.match(mainCss, /\.special-adjustment-paper-line-card/);
  });

  it("keeps production outbound document controls paper-native", () => {
    assert.match(source, /production-out-paper-grid/);
    assert.match(source, /production-out-source-lot-panel/);
    assert.match(source, /production-out-source-lot-table/);
    assert.doesNotMatch(source, /<div class="workflow-tip">选择原材料库存批次出库/);
    assert.match(mainCss, /\.production-out-source-lot-panel/);
  });

  it("keeps production ledger inbound settlement controls paper-native", () => {
    const productionLedgerInboundBlock = source.slice(
      source.indexOf(':open="productionWorkOrderInboundDrawerOpen"'),
      source.indexOf("<StocktakeDialog")
    );
    assert.match(source, /production-ledger-inbound-paper-grid/);
    assert.match(source, /production-ledger-inbound-summary/);
    assert.match(source, /production-ledger-inbound-metrics/);
    assert.doesNotMatch(productionLedgerInboundBlock, /<div class="triple-field">[\s\S]*?productionWorkOrderInboundForm\.finished_qty/);
    assert.match(mainCss, /\.production-ledger-inbound-metrics/);
  });

  it("keeps raw material return outbound documents paper-native", () => {
    const block = drawerBlock("rawReturnDrawerOpen", ':open="returnInboundDrawerOpen"');
    assert.match(block, /raw-return-paper-grid/);
    assert.match(block, /raw-return-logistics-grid/);
    assert.doesNotMatch(block, /class="double-field"/);
    assert.doesNotMatch(block, /class="triple-field"/);
    assert.doesNotMatch(block, /class="form-field/);
    assert.doesNotMatch(block, /modern-upload/);
    assert.match(mainCss, /\.raw-return-paper-grid/);
  });

  it("keeps return inbound and return scrap inbound documents paper-native", () => {
    const returnBlock = drawerBlock("returnInboundDrawerOpen", ':open="returnScrapInboundDrawerOpen"');
    const scrapBlock = drawerBlock("returnScrapInboundDrawerOpen", ':open="openingImportDrawerOpen"');
    [returnBlock, scrapBlock].forEach((block) => {
      assert.match(block, /return-paper-grid/);
      assert.match(block, /return-trace-summary/);
      assert.doesNotMatch(block, /class="double-field"/);
      assert.doesNotMatch(block, /class="triple-field"/);
      assert.doesNotMatch(block, /class="form-field/);
    });
    assert.match(mainCss, /\.return-paper-grid/);
  });

  it("keeps finished inbound and sales outbound documents paper-native", () => {
    const completionBlock = drawerBlock("completionDrawerOpen", ':open="deliveryDrawerOpen"');
    const deliveryBlock = drawerBlock("deliveryDrawerOpen", ':open="returnReworkDrawerOpen"');
    assert.match(completionBlock, /completion-paper-grid/);
    assert.match(completionBlock, /completion-settle-panel/);
    assert.match(deliveryBlock, /sales-delivery-paper-grid/);
    assert.match(deliveryBlock, /sales-delivery-allocation-table/);
    [completionBlock, deliveryBlock].forEach((block) => {
      assert.doesNotMatch(block, /class="double-field"/);
      assert.doesNotMatch(block, /class="triple-field"/);
      assert.doesNotMatch(block, /class="form-field/);
      assert.doesNotMatch(block, /modern-upload/);
    });
    assert.match(mainCss, /\.completion-paper-grid/);
    assert.match(mainCss, /\.sales-delivery-paper-grid/);
  });

  it("keeps return rework and production ledger closeout tails paper-native", () => {
    const reworkBlock = drawerBlock("returnReworkDrawerOpen", ':open="warehouseLedgerDrawerOpen"');
    const productionBlock = drawerBlock("productionDrawerOpen", ':open="completionDrawerOpen"');
    const ledgerInboundBlock = drawerBlock("productionWorkOrderInboundDrawerOpen", "<StocktakeDialog");
    assert.match(reworkBlock, /return-rework-paper-grid/);
    assert.match(reworkBlock, /return-rework-trace-summary/);
    assert.match(productionBlock, /production-out-paper-remark/);
    assert.match(ledgerInboundBlock, /production-ledger-inbound-settle-panel/);
    assert.match(ledgerInboundBlock, /production-ledger-inbound-remark/);
    [reworkBlock, productionBlock, ledgerInboundBlock].forEach((block) => {
      assert.doesNotMatch(block, /class="double-field"/);
      assert.doesNotMatch(block, /class="triple-field"/);
      assert.doesNotMatch(block, /class="form-field/);
    });
    assert.match(mainCss, /\.return-rework-paper-grid/);
    assert.match(mainCss, /\.production-ledger-inbound-settle-panel/);
  });

  it("surfaces generated PDF archive feedback after independent warehouse saves", () => {
    [
      ["submitRawReturnOutbound", "退货出库"],
      ["submitReturnInbound", "退货入库"],
      ["submitReturnScrapInbound", "退货废料入库"],
      ["submitReturnReworkOutbound", "返工出库"],
      ["submitSalesOut", "销售出库单"],
      ["submitSpecialAdjustment", "specialAdjustmentDirectionText.value"]
    ].forEach(([name, label]) => {
      const body = functionBody(name);
      assert.match(body, new RegExp(`rememberWarehouseArchiveResult\\(result, ${label === "specialAdjustmentDirectionText.value" ? label.replace(".", "\\.") : `"${label}"`}\\)`));
      assert.match(body, /formatArchiveFeedback\(result\)/);
    });
  });

  it("uses compact industrial layout for warehouse ledger drawer controls and archive column", () => {
    assert.match(source, /warehouse-ledger-filter-fields/);
    assert.match(source, /warehouse-ledger-filter-actions/);
    assert.match(source, /warehouse-ledger-export-button/);
    assert.match(source, /warehouse-ledger-table-wrap/);
    assert.match(source, /warehouse-ledger-table/);
    assert.match(source, /warehouse-ledger-archive-cell/);
    assert.equal(source.includes("warehouse-ledger-table-toolbar"), false);
    const filterActionsMatch = source.match(/<div class="warehouse-ledger-filter-actions">([\s\S]*?)<\/div>/);
    assert.ok(filterActionsMatch, "expected warehouse ledger filter actions to exist");
    assert.match(
      filterActionsMatch[1],
      /warehouse-ledger-export-button/,
      "export should stay with the query/reset filter actions"
    );
    const exportIndex = source.indexOf("warehouse-ledger-export-button");
    const filterActionsIndex = source.indexOf("warehouse-ledger-filter-actions");
    assert.ok(exportIndex > filterActionsIndex, "expected export button to sit inside filter action area");
    assert.match(mainCss, /\.warehouse-ledger-filter-actions/);
    assert.match(mainCss, /\.warehouse-ledger-export-button/);
    assert.doesNotMatch(mainCss, /body \.warehouse-ledger-table-toolbar/);
    assert.match(mainCss, /\.warehouse-ledger-table \.document-archive-actions/);
    assert.match(mainCss, /body \.warehouse-ledger-filters\s*\{[\s\S]*grid-template-columns: 1fr !important;/);
    assert.match(mainCss, /body \.warehouse-ledger-filter-actions\s*\{[\s\S]*justify-self: end !important;/);
    assert.match(mainCss, /body \.warehouse-ledger-filter-actions \.warehouse-ledger-export-button\s*\{[\s\S]*font-weight: 800 !important;/);
    assert.match(mainCss, /body \.warehouse-ledger-filter-actions \.warehouse-ledger-export-button\s*\{[\s\S]*box-sizing: border-box !important;/);
    assert.match(mainCss, /body \.warehouse-ledger-filter-actions \.warehouse-ledger-export-button\s*\{[\s\S]*align-items: center !important;/);
    assert.match(mainCss, /body \.warehouse-ledger-filter-actions \.warehouse-ledger-export-button\s*\{[\s\S]*justify-content: center !important;/);
    assert.match(mainCss, /body \.warehouse-ledger-filter-actions \.warehouse-ledger-export-button\s*\{[\s\S]*gap: 7px !important;/);
    assert.match(mainCss, /body \.warehouse-ledger-filter-actions \.warehouse-ledger-export-button\s*\{[\s\S]*min-width: 126px !important;/);
    assert.match(mainCss, /body \.warehouse-ledger-filter-actions \.warehouse-ledger-export-button::before\s*\{[\s\S]*margin: 0 !important;/);
    assert.match(mainCss, /body \.warehouse-ledger-filter-actions \.warehouse-ledger-export-button\s*\{[\s\S]*0 8px 16px rgba\(15, 23, 42, 0\.08\)/);
    assert.doesNotMatch(
      mainCss.match(/body \.warehouse-ledger-filter-actions \.warehouse-ledger-export-button\s*\{[\s\S]*?\n\}/)?.[0] || "",
      /0 10px 22px rgba\(22, 163, 74, 0\.14\)/,
      "warehouse ledger export button should not use the oversized green call-to-action shadow"
    );
    assert.match(mainCss, /body \.warehouse-ledger-summary\s*\{[\s\S]*repeat\(auto-fit, minmax\(158px, 1fr\)\)/);
    assert.match(mainCss, /body \.workflow-drawer\.form-drawer:has\(\.warehouse-ledger-drawer\)/);
    assert.match(mainCss, /@media \(max-width: 560px\)[\s\S]*body \.warehouse-ledger-summary\s*\{[\s\S]*grid-template-columns: 1fr !important;/);
    assert.match(mainCss, /Final warehouse ledger drawer UI override/);
    assert.ok(
      mainCss.lastIndexOf("Final warehouse ledger drawer UI override") > mainCss.lastIndexOf("Shared warehouse paper-form components"),
      "warehouse ledger drawer overrides must stay after shared paper document styles"
    );
  });

  it("uses the shared black hover tooltip for truncated warehouse ledger values", () => {
    assert.match(source, /ref="warehouseLedgerTableRef"/);
    assert.match(source, /warehouseLedgerTooltipAttrs\(formatDateTime\(row\.biz_time\)\)/);
    assert.match(source, /warehouseLedgerTooltipAttrs\(formatInventoryTxnTypeLabel\(row\.txn_type\)\)/);
    assert.match(source, /warehouseLedgerTooltipAttrs\(formatWarehouseLedgerItemLabel\(row\)\)/);
    assert.match(source, /warehouseLedgerTooltipAttrs\(formatWarehouseLedgerLotNo\(row\)\)/);
    assert.match(source, /warehouseLedgerTooltipAttrs\(formatWarehouseLedgerSourceLabel\(row\)\)/);
    assert.match(source, /warehouseLedgerTooltipAttrs\(row\.operator_name \|\| ['"]-['"]\)/);
    assert.match(source, /warehouseLedgerTooltipAttrs\(formatWarehouseLedgerLogisticsLabel\(row\)\)/);
    assert.match(source, /warehouseLedgerTooltipAttrs\(row\.remark \|\| ['"]-['"]\)/);
    assert.match(source, /function warehouseLedgerTooltipAttrs\(value\)/);
    assert.match(source, /function bindWarehouseLedgerCellTooltip\(\)/);
    assert.match(source, /function showWarehouseLedgerCellTooltip\(cell, event\)/);
    assert.match(source, /table-cell-hover-tooltip/);
    assert.match(source, /data-table-tooltip/);
    assert.match(source, /data-table-full-value/);
    assert.match(source, /onBeforeUnmount\(clearWarehouseLedgerTooltipListeners\)/);
    assert.doesNotMatch(source, /<td :title="formatDateTime\(row\.biz_time\)"/);
    assert.doesNotMatch(source, /<td :title="formatWarehouseLedgerLotNo\(row\)"/);
  });
});
