# -*- 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 must_replace(old, new, label):
    global text
    if old not in text:
        raise SystemExit(f"MISSING: {label}")
    text = text.replace(old, new, 1)

must_replace(
    """      } 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);
      }
    }""",
    "pdaOpenJob keys",
)

must_replace(
    """    } else if (type === "fg") {
      const f = ctx?.fgId
        ? state.finishedInbound.find((x) => x.id === ctx.fgId && x.status === "putaway")
        : state.finishedInbound.find((x) => x.status === "putaway");
      if (!f) {
        toast("暂无待上架成品单", "");
        return;
      }
      state.pdaActive = { type: "fg", fgId: f.id };
    } else if (type === "count") {""",
    """    } else if (type === "fg") {
      const f = ctx?.fgId
        ? state.finishedInbound.find((x) => x.id === ctx.fgId && x.status === "putaway")
        : state.finishedInbound.find((x) => x.status === "putaway");
      if (!f) {
        toast("暂无待上架成品单", "");
        return;
      }
      state.pdaActive = { type: "fg", fgId: f.id };
    } 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 === "count") {""",
    "pdaOpenJob types",
)

must_replace(
    """    } 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();
    }""",
    "bindPdaActionBar",
)

# Workflow HTML snippets - insert before fg block
must_replace(
    """    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 `<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>
        <div class="pda-hint info">推荐库位 S-03-02-01 · 可绑定序列号 #122</div>
        <button type="button" class="btn btn-primary" id="pda-commit-semi" style="display:none">提交</button>`;
    }
    if (type === "rtnIn") {
      const r = (state.salesReturnInbound || []).find((x) => x.id === act.rtnId) || (state.salesReturnInbound || [])[0];
      return `<div class="pda-wizard-head"><h4>退货入库 #116</h4><span class="wire-label">${r?.returnType || ""} · ${r?.sourceNo || ""}</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" style="display:none">提交</button>`;
    }
    if (type === "deliverySign") {
      const d = (state.deliverySignoffs || []).find((x) => x.outboundId === act.so) || (state.deliverySignoffs || [])[0];
      return `<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" style="display:none">提交</button>`;
    }
    if (type === "serialBind") {
      const sn = (state.serialNumbers || [])[0];
      return `<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 || "扫序列号 SN"}</div>
        <div class="scan-input ${w.scans.mat ? "filled" : ""}" data-scan="mat" data-expect="${sn?.sku || "FG-1002"}">${w.scans.mat || "扫箱码/SKU"}</div>
        <button type="button" class="btn btn-primary" id="pda-commit-serial-bind" style="display:none">提交</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>""",
    "renderPdaWorkflow new types",
)

must_replace(
    """    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("半成品入库完成 · K3 过账", "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);
      pushAudit("PDA退货入库", 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-"));
      pushAudit("PDA签收 #125", d?.outboundId || "");
      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 || "SN20260928001";
      let row = (state.serialNumbers || []).find((x) => x.serial === sn);
      if (!row && state.serialNumbers) {
        row = { serial: sn, sku: state.pdaWizard.scans.mat, batch: "—", status: "在库", boundAt: new Date().toISOString().slice(0, 10), outboundId: "—", inboundId: "PDA" };
        state.serialNumbers.push(row);
      } else if (row) {
        row.boundAt = new Date().toISOString().slice(0, 10);
      }
      pushAudit("序列号绑定 #122", sn);
      toast("序列号已绑定", "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;""",
    "pda commit handlers",
)

must_replace(
    """          ".btn-fg-pda, .btn-other-exec, .btn-pda-launch, .btn-vis-export, .btn-arrival-receive, .btn-out-pick, .btn-out-ship, .btn-reject-return, .btn-move-pda-row, .btn-shift-pda, .btn-bind-pda, .btn-manual-release, .btn-transfer-close, .btn-stale-out",
        )
      ) {
        return;
      }""",
    """          ".btn-fg-pda, .btn-semi-pda, .btn-rtn-pda, .btn-delivery-sign-pda, .btn-serial-bind-pda, .btn-delivery-sign, .btn-other-exec, .btn-pda-launch, .btn-vis-export, .btn-arrival-receive, .btn-out-pick, .btn-out-ship, .btn-reject-return, .btn-move-pda-row, .btn-shift-pda, .btn-bind-pda, .btn-manual-release, .btn-transfer-close, .btn-stale-out",
        )
      ) {
        return;
      }""",
    "admin delegate exclude",
)

must_replace(
    """    document.getElementById("btn-sync-k3")?.addEventListener("click", () => {""",
    """    document.getElementById("link-gap-acceptance")?.addEventListener("click", (e) => {
      e.preventDefault();
      go("blueprint-hub", { hub: "acceptance" });
    });
    document.querySelectorAll(".btn-semi-pda").forEach((btn) =>
      btn.addEventListener("click", () => {
        openPdaFull();
        pdaOpenJob("semiIn", {});
      }),
    );
    document.querySelectorAll(".btn-rtn-pda").forEach((btn) =>
      btn.addEventListener("click", () => {
        openPdaFull();
        pdaOpenJob("rtnIn", {});
      }),
    );
    document.querySelectorAll(".btn-serial-bind-pda").forEach((btn) =>
      btn.addEventListener("click", () => {
        openPdaFull();
        pdaOpenJob("serialBind", {});
      }),
    );
    document.querySelectorAll(".btn-delivery-sign-pda").forEach((btn) =>
      btn.addEventListener("click", () => {
        openPdaFull();
        const oid = btn.dataset.oid;
        pdaOpenJob("deliverySign", oid ? { so: oid } : {});
      }),
    );
    document.querySelectorAll(".btn-delivery-sign").forEach((btn) =>
      btn.addEventListener("click", () => {
        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 });
          pushAudit("PC签收 #125", oid);
          toast("已签收 · 请同步 K3 #126", "success");
          persist();
          renderMain();
        }
      }),
    );
    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", () => {
      const sn = document.querySelector('.page[data-page="inventory"] .gc-q-input[data-q="sn"]')?.value || "SN20260928001";
      const row = (state.serialNumbers || []).find((x) => x.serial === sn);
      toast(row ? `SN ${sn} · ${row.sku} · ${row.status}` : "未找到序列号", row ? "success" : "");
    });
    document.getElementById("btn-sync-k3")?.addEventListener("click", () => {""",
    "PC button handlers",
)

# crud schemas for new stores - grep semiFinishedInbound in crudSchemas
if "semiFinishedInbound:" not in text:
    must_replace(
        """    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 schemas",
    )

must_replace(
    """        btn.matches(
          ".btn-lims, .btn-putaway-pda, .btn-row-receive, .btn-pick-pda, .btn-workshop-receive, .btn-return-pda, .btn-return-lims, .btn-fg-pda,""",
    """        btn.matches(
          ".btn-lims, .btn-putaway-pda, .btn-row-receive, .btn-pick-pda, .btn-workshop-receive, .btn-return-pda, .btn-return-lims, .btn-fg-pda, .btn-semi-pda, .btn-rtn-pda, .btn-delivery-sign-pda, .btn-serial-bind-pda,""",
    "btn matches",
)

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