// assets/worker/autowd.js
// Worker untuk mengirim flow incoming.json ke agent file-drop via Cloudflare Tunnel
// - Menerima { txId, brand, panelId, username, filedropUrl, suggestName, relaxDevice }
// - Ambil incoming.json dari endpoint panel (same-origin)
// - Push ke server file-drop pada base URL (Quick Tunnel) yang kamu set di localStorage: awd_filedrop_url
self.postMessage({ type: "ready" });

function reply(id, ok, payload) {
  self.postMessage(ok ? { id, ok: true, result: payload } : { id, ok: false, error: String(payload) });
}

self.addEventListener("message", async (ev) => {
  const msg = ev.data || {};
  if (msg.type === "hello") { self.postMessage({ type: "ready" }); return; }
  const { id, method, params } = msg;
  if (!id) return;

  try {
    if (method === "startJob") {
      const incomingText = await getIncomingJson(params); // params.relaxDevice didukung
      const fname = params.suggestName || `incoming-${(params.brand||'tiara')}-${(params.txId||'tx')}.json`;
      await pushToFiledrop(incomingText, params.filedropUrl, fname);
      return reply(id, true, { ok: true });
    }
    throw new Error("unknown_method");
  } catch (e) {
    reply(id, false, e?.message || e);
  }
});

async function getIncomingJson({ txId, brand, panelId, username, relaxDevice }) {
  const ORIGIN = self.location.origin;
  const tries = [
    `${ORIGIN}/awithdraw/${encodeURIComponent(txId)}/incoming.json?brand=${encodeURIComponent(brand)}`,
    `${ORIGIN}/api/awithdraw/${encodeURIComponent(txId)}/incoming.json?brand=${encodeURIComponent(brand)}`,
    `${ORIGIN}/api/awd/tx/${encodeURIComponent(txId)}/incoming.json?brand=${encodeURIComponent(brand)}`,
  ];

  let lastErr = null;

  // helper untuk fetch dengan/ tanpa header x-panel-id
  const doFetch = async (url, omitPanel) => {
    const headers = omitPanel ? {
      "x-panel-user": String(username || "anon"),
      "x-relax-device": "1",                // [PATCH] beri hint relax device di BE
    } : {
      "x-panel-id": String(panelId || ""),
      "x-panel-user": String(username || "anon"),
    };
    const r = await fetch(url, { credentials: "include", headers });
    const text = await r.text();
    return { ok: r.ok, status: r.status, text };
  };

  for (const url of tries) {
    try {
      // 1) jika relaxDevice diminta → langsung tanpa panel id
      if (relaxDevice) {
        const a = await doFetch(url, true);
        if (a.ok) { try { JSON.parse(a.text); } catch { throw new Error("invalid_json"); } return a.text; }
        lastErr = new Error(`HTTP ${a.status} (relax)`);
        continue;
      }

      // 2) normal (pakai panel id)
      let a = await doFetch(url, false);
      if (a.ok) { try { JSON.parse(a.text); } catch { throw new Error("invalid_json"); } return a.text; }

      // 3) jika gagal karena device_not_ready → retry relax
      const maybeJson = safeParseJson(a.text);
      if (maybeJson && (maybeJson.error === "device_not_ready" || /device.*not.*ready/i.test(a.text))) {
        const b = await doFetch(url, true);
        if (b.ok) { try { JSON.parse(b.text); } catch { throw new Error("invalid_json"); } return b.text; }
        lastErr = new Error(`HTTP ${b.status} (relax retry)`);
        continue;
      }

      lastErr = new Error(`HTTP ${a.status}`);
    } catch (e) {
      lastErr = e;
    }
  }
  throw lastErr || new Error("fetch_incoming_failed");
}

function safeParseJson(str){
  try { return JSON.parse(str); } catch { return null; }
}

async function pushToFiledrop(contentStr, baseUrl, fileName) {
  if (!baseUrl) throw new Error("filedrop_url_missing");
  const root = baseUrl.replace(/\/+$/, "");
  const name = fileName || `incoming-tx.json`;

  const variants = [
    { path: `/submit?name=${encodeURIComponent(name)}`, body: contentStr, headers: { "content-type": "application/json" } },
    { path: "/push",  body: JSON.stringify({ name, data: contentStr }), headers: { "content-type": "application/json" } },
    { path: `/drop?name=${encodeURIComponent(name)}`, body: contentStr, headers: { "content-type": "application/json" } },
    { path: "/v1/push", body: JSON.stringify({ filename: name, content: contentStr }), headers: { "content-type": "application/json" } },
  ];

  let lastErr = null;
  for (const v of variants) {
    try {
      const r = await fetch(root + v.path, {
        method: "POST",
        mode: "cors",
        credentials: "omit",
        headers: v.headers,
        body: v.body
      });
      if (r.ok) return true;
      const t = await r.text().catch(()=> '');
      lastErr = new Error(`push_fail_${v.path}_${r.status}_${t}`);
    } catch (e) { lastErr = e; }
  }
  throw lastErr || new Error("push_failed");
}
