# -*- coding: utf-8 -*-
from pathlib import Path

PATH = Path(__file__).resolve().parent / "wms-v3-blueprint-prototype.html"
text = PATH.read_text(encoding="utf-8")

def rep(old, new, label):
    global text
    if old not in text:
        raise SystemExit(f"MISSING: {label}")
    text = text.replace(old, new, 1)

if 'k.startsWith("semi-")' not in text:
    rep(
        """      } else if (k.startsWith("recap-")) {
        type = "countRecap";
      }
    }""",
        """      } else if (k.startsWith("recap-")) {
        type = "countRecap";
      } else if (k.startsWith("semi-")) {
        type = "semiIn";
        ctx.semiId = k.slice(5);
      } else if (k.startsWith("rtn-")) {
        type = "rtnIn";
        ctx.rtnId = k.slice(4);
      } else if (k.startsWith("sign-")) {
        type = "deliverySign";
        ctx.so = k.slice(5);
      }
    }""",
        "pda keys",
    )

rep(
    """    } else if (type === "wcsConfirm") {
      const w = state.wcsTasks[0];""",
    """    } else if (type === "semiIn") {
      const s = ctx?.semiId
        ? (state.semiFinishedInbound || []).find((x) => x.id === ctx.semiId && x.status !== "done")
        : (state.semiFinishedInbound || []).find((x) => x.status !== "done");
      if (!s) { toast("暂无半成品入库任务", ""); return; }
      state.pdaActive = { type: "semiIn", semiId: s.id };
    } else if (type === "rtnIn") {
      const r = ctx?.rtnId
        ? (state.salesReturnInbound || []).find((x) => x.id === ctx.rtnId && x.status !== "done")
        : (state.salesReturnInbound || []).find((x) => x.status !== "done");
      if (!r) { toast("暂无退货入库任务", ""); return; }
      state.pdaActive = { type: "rtnIn", rtnId: r.id };
    } else if (type === "deliverySign") {
      const d = ctx?.so
        ? (state.deliverySignoffs || []).find((x) => x.outboundId === ctx.so && x.signStatus === "待签收")
        : (state.deliverySignoffs || []).find((x) => x.signStatus === "待签收");
      if (!d) { toast("暂无待签收出库单", ""); return; }
      state.pdaActive = { type: "deliverySign", so: d.outboundId };
    } else if (type === "serialBind") {
      state.pdaActive = { type: "serialBind" };
    } else if (type === "wcsConfirm") {
      const w = state.wcsTasks[0];""",
    "pdaOpenJob new types",
)

if 'act.type === "semiIn"' not in text:
    rep(
        """    } else if (act.type === "material") {
      pri.textContent = "确认分拣";
      pri.onclick = () => {
        if (!w.scans.mat) return toast("请扫物料", "");
        document.getElementById("pda-commit-material")?.click();
      };
    } else {
      pri.textContent = "完成";
      pri.onclick = () => sec.onclick();
    }""",
        """    } else if (act.type === "material") {
      pri.textContent = "确认分拣";
      pri.onclick = () => {
        if (!w.scans.mat) return toast("请扫物料", "");
        document.getElementById("pda-commit-material")?.click();
      };
    } else if (act.type === "semiIn") {
      pri.textContent = "确认半成品入库";
      pri.onclick = () => {
        if (!w.scans.doc || !w.scans.mat) return toast("请扫入库单与条码", "");
        document.getElementById("pda-commit-semi")?.click();
      };
    } else if (act.type === "rtnIn") {
      pri.textContent = "确认退货入库";
      pri.onclick = () => {
        if (!w.scans.doc || !w.scans.mat) return toast("请扫退货单与物料", "");
        document.getElementById("pda-commit-rtn-in")?.click();
      };
    } else if (act.type === "deliverySign") {
      pri.textContent = "确认签收";
      pri.onclick = () => {
        if (!w.scans.so || !w.scans.signer) return toast("请扫出库单与签收信息", "");
        document.getElementById("pda-commit-delivery-sign")?.click();
      };
    } else if (act.type === "serialBind") {
      pri.textContent = "绑定序列号";
      pri.onclick = () => {
        if (!w.scans.sn || !w.scans.mat) return toast("请扫 SN 与箱码", "");
        document.getElementById("pda-commit-serial-bind")?.click();
      };
    } else {
      pri.textContent = "完成";
      pri.onclick = () => sec.onclick();
    }""",
        "action bar",
    )

if 'type === "semiIn"' not in text or '半成品入库 #114' not in text:
    rep(
        """    if (type === "fg") {
      const f = state.finishedInbound.find((x) => x.status === "putaway") || state.finishedInbound[0];
      return (
        back +
        `<div class="pda-wizard-head"><h4>${f?.id}</h4><p class="wire-label">${f?.wo} · ${f?.batch}</p></div>""",
        """    if (type === "semiIn") {
      const s = (state.semiFinishedInbound || []).find((x) => x.id === act.semiId) || (state.semiFinishedInbound || [])[0];
      return back + `<div class="pda-wizard-head"><h4>半成品入库 #114</h4><span class="wire-label">${s?.id || ""} · ${s?.sku || ""}</span></div>
        <div class="scan-input ${w.scans.doc ? "filled" : ""}" data-scan="doc" data-expect="${s?.id || "SF-9920"}">${w.scans.doc || "扫入库单"}</div>
        <div class="scan-input ${w.scans.mat ? "filled" : ""}" data-scan="mat" data-expect="${s?.sku || "SF-2001"}">${w.scans.mat || "扫物料条码"}</div>
        <button type="button" class="btn btn-primary" id="pda-commit-semi">确认入库</button>`;
    }
    if (type === "rtnIn") {
      const r = (state.salesReturnInbound || []).find((x) => x.id === act.rtnId) || (state.salesReturnInbound || [])[0];
      return back + `<div class="pda-wizard-head"><h4>退货入库 #116</h4><span class="wire-label">${r?.returnType || ""}</span></div>
        <div class="scan-input ${w.scans.doc ? "filled" : ""}" data-scan="doc" data-expect="${r?.id || "RTN-S001"}">${w.scans.doc || "扫退货单"}</div>
        <div class="scan-input ${w.scans.mat ? "filled" : ""}" data-scan="mat" data-expect="${r?.sku || "FG-1002"}">${w.scans.mat || "扫物料"}</div>
        <button type="button" class="btn btn-primary" id="pda-commit-rtn-in">复核入库</button>`;
    }
    if (type === "deliverySign") {
      const d = (state.deliverySignoffs || []).find((x) => x.outboundId === act.so) || (state.deliverySignoffs || [])[0];
      return back + `<div class="pda-wizard-head"><h4>签收确认 #125</h4><span class="wire-label">${d?.customer || ""}</span></div>
        <div class="scan-input ${w.scans.so ? "filled" : ""}" data-scan="so" data-expect="${d?.outboundId || "CK20260928002"}">${w.scans.so || "扫出库单"}</div>
        <div class="scan-input ${w.scans.signer ? "filled" : ""}" data-scan="signer" data-expect="SIGN-OK">${w.scans.signer || "扫签收码"}</div>
        <button type="button" class="btn btn-primary" id="pda-commit-delivery-sign">确认签收</button>`;
    }
    if (type === "serialBind") {
      const sn = (state.serialNumbers || [])[0];
      return back + `<div class="pda-wizard-head"><h4>序列号绑定 #122</h4></div>
        <div class="scan-input ${w.scans.sn ? "filled" : ""}" data-scan="sn" data-expect="${sn?.serial || "SN20260928001"}">${w.scans.sn || "扫序列号"}</div>
        <div class="scan-input ${w.scans.mat ? "filled" : ""}" data-scan="mat" data-expect="${sn?.sku || "FG-1002"}">${w.scans.mat || "扫箱码"}</div>
        <button type="button" class="btn btn-primary" id="pda-commit-serial-bind">绑定</button>`;
    }
    if (type === "fg") {
      const f = state.finishedInbound.find((x) => x.status === "putaway") || state.finishedInbound[0];
      return (
        back +
        `<div class="pda-wizard-head"><h4>${f?.id}</h4><p class="wire-label">${f?.wo} · ${f?.batch}</p></div>""",
        "workflow types",
    )

rep(
    """      semiIn: ["扫半成品单", "扫条码", "确认库位"],
      rtnIn: ["扫退货单", "扫物料", "复核入库"],
      deliverySign: ["扫出库单", "扫签收码/人", "确认签收"],
      serialBind: ["扫 SN", "扫箱码", "提交绑定"],
      splitPallet: ["扫托标", "拆分数", "新箱码", "打印提交"],""",
    """      semiIn: ["扫入库单", "扫条码", "确认"],
      rtnIn: ["扫退货单", "扫物料", "复核"],
      deliverySign: ["扫出库单", "扫签收", "确认"],
      serialBind: ["扫 SN", "扫箱码", "绑定"],
      splitPallet: ["扫托标", "拆分数", "新箱码", "打印提交"],""",
    "stepDefs",
)

if 'pda-commit-semi' not in text or 'document.getElementById("pda-commit-semi")?.addEventListener' not in text:
    rep(
        """    document.getElementById("pda-commit-material")?.addEventListener("click", () => {
      const wo = state.pdaActive?.wo;""",
        """    document.getElementById("pda-commit-semi")?.addEventListener("click", () => {
      const s = (state.semiFinishedInbound || []).find((x) => x.id === state.pdaActive?.semiId);
      if (s) { s.status = "done"; s.loc = "S-03-02-01"; }
      state.pdaTasks = state.pdaTasks.filter((t) => !t.key || !String(t.key).startsWith("semi-"));
      pushIntegrationLog("K3-SF-IN", "成功", "半成品入库 #114", s?.id);
      pushAudit("PDA半成品入库", s?.id || "");
      toast("半成品入库完成", "success");
      state.pdaActive = null;
      document.getElementById("view-pda-full")?.classList.remove("workflow-open");
      persist(); renderPdaApp();
    });
    document.getElementById("pda-commit-rtn-in")?.addEventListener("click", () => {
      const r = (state.salesReturnInbound || []).find((x) => x.id === state.pdaActive?.rtnId);
      if (r) r.status = "done";
      state.pdaTasks = state.pdaTasks.filter((t) => !t.key || !String(t.key).startsWith("rtn-"));
      pushIntegrationLog("K3-RTN-IN", "成功", "退货入库 #116", r?.id);
      toast("退货入库完成", "success");
      state.pdaActive = null;
      document.getElementById("view-pda-full")?.classList.remove("workflow-open");
      persist(); renderPdaApp();
    });
    document.getElementById("pda-commit-delivery-sign")?.addEventListener("click", () => {
      const d = (state.deliverySignoffs || []).find((x) => x.outboundId === state.pdaActive?.so);
      if (d) {
        d.signStatus = "已签收";
        d.signedBy = state.pdaWizard?.scans?.signer || "客户";
        d.signedAt = new Date().toLocaleString("zh-CN", { hour12: false });
      }
      state.pdaTasks = state.pdaTasks.filter((t) => !t.key || !String(t.key).startsWith("sign-"));
      toast("签收完成 · 请 PC 同步 K3 #126", "success");
      state.pdaActive = null;
      document.getElementById("view-pda-full")?.classList.remove("workflow-open");
      persist(); renderPdaApp();
    });
    document.getElementById("pda-commit-serial-bind")?.addEventListener("click", () => {
      const sn = state.pdaWizard?.scans?.sn;
      if (sn) {
        let row = (state.serialNumbers || []).find((x) => x.serial === sn);
        if (!row) {
          state.serialNumbers = state.serialNumbers || [];
          state.serialNumbers.push({ serial: sn, sku: state.pdaWizard.scans.mat, batch: "—", status: "在库", boundAt: new Date().toISOString().slice(0, 10), outboundId: "—", inboundId: "PDA" });
        }
      }
      toast("序列号已绑定 #122", "success");
      state.pdaActive = null;
      document.getElementById("view-pda-full")?.classList.remove("workflow-open");
      persist(); renderPdaApp();
    });
    document.getElementById("pda-commit-material")?.addEventListener("click", () => {
      const wo = state.pdaActive?.wo;""",
        "commits",
    )

if 'link-gap-acceptance' not in text:
    rep(
        """    document.getElementById("btn-sync-k3")?.addEventListener("click", () => {""",
        """    document.getElementById("link-gap-acceptance")?.addEventListener("click", (e) => {
      e.preventDefault();
      go("blueprint-hub", { hub: "acceptance" });
    });
    document.body.addEventListener("click", (e) => {
      const btn = e.target.closest(".btn-semi-pda, .btn-rtn-pda, .btn-serial-bind-pda, .btn-delivery-sign-pda, .btn-delivery-sign");
      if (!btn) return;
      e.preventDefault();
      if (btn.classList.contains("btn-delivery-sign")) {
        const oid = btn.dataset.oid;
        const d = (state.deliverySignoffs || []).find((x) => x.outboundId === oid);
        if (d) {
          d.signStatus = "已签收";
          d.signedBy = "PC录入";
          d.signedAt = new Date().toLocaleString("zh-CN", { hour12: false });
          toast("已签收", "success");
          persist(); renderMain();
        }
        return;
      }
      openPdaFull();
      if (btn.classList.contains("btn-semi-pda")) pdaOpenJob("semiIn", {});
      else if (btn.classList.contains("btn-rtn-pda")) pdaOpenJob("rtnIn", {});
      else if (btn.classList.contains("btn-serial-bind-pda")) pdaOpenJob("serialBind", {});
      else if (btn.classList.contains("btn-delivery-sign-pda")) pdaOpenJob("deliverySign", { so: btn.dataset.oid });
    });
    document.getElementById("btn-delivery-sync-k3")?.addEventListener("click", () => {
      (state.deliverySignoffs || []).forEach((d) => {
        if (d.signStatus === "已签收") { d.k3Synced = true; d.k3SyncedAt = new Date().toLocaleString("zh-CN", { hour12: false }); }
      });
      pushIntegrationLog("K3-SIGN", "成功", "签收回写 #126", "batch");
      toast("K3 签收已同步", "success");
      persist(); renderMain();
    });
    document.getElementById("btn-serial-trace")?.addEventListener("click", () => {
      toast("序列号链路：入库→在库（演示）", "success");
    });
    document.getElementById("btn-sync-k3")?.addEventListener("click", () => {""",
        "PC handlers",
    )

if "semiFinishedInbound:" not in text:
    rep(
        """    finishedInbound: {
      title: "成品入库单",""",
        """    semiFinishedInbound: {
      title: "半成品入库单",
      idKey: "id",
      page: "warehousing",
      whSection: "semi",
      whTab: "order",
      fields: [
        { key: "id", label: "入库单号", required: true },
        { key: "wo", label: "工单" },
        { key: "sku", label: "SKU", required: true },
        { key: "batch", label: "批次" },
        { key: "qty", label: "数量" },
        { key: "status", label: "状态", default: "mes_ok" },
      ],
    },
    salesReturnInbound: {
      title: "退货入库单",
      idKey: "id",
      page: "warehousing",
      whSection: "rtn",
      whTab: "order",
      fields: [
        { key: "id", label: "退货入库单", required: true },
        { key: "returnType", label: "类型", default: "销售退货" },
        { key: "sourceNo", label: "来源单号" },
        { key: "sku", label: "SKU" },
        { key: "qty", label: "数量" },
        { key: "status", label: "状态", default: "pending" },
      ],
    },
    finishedInbound: {
      title: "成品入库单",""",
        "crud",
    )

PATH.write_text(text, encoding="utf-8")
print("handlers2 OK")
