// Structured recipient address from Shoptet's "Edit Shipping Address" modal.
//
// The order-detail page only exposes the delivery address as a FLATTENED
// clipboard string (#shipping-address [data-clipboard]); parsing it back into
// discrete fields is fragile — it broke on the Polish postcode format "31-511"
// (Tic-0019 / UAT-011-A) and on missing house numbers. Shoptet itself keeps the
// address as discrete fields in the edit modal, loaded from
//   GET /admin/edit-shipping-address/?documentId=<orderId>
// and the currently-selected <option> in #shippingAddressBox carries the WHOLE
// record as JSON in its data-record attribute. Reading that (or, as a fallback,
// the populated #deliveryStreet/#deliveryZip/... inputs) gives us street,
// building, city, postCode, region and the numeric country id with zero
// guesswork — locale- and format-independent.
//
// This module exports the *source* of an async function as a string so it can be
// inlined into the executeJavaScript payloads that already run inside the Shoptet
// WebContentsView (which has DOMParser + the logged-in session cookies). Callers
// inline SHIPPING_MODAL_SNIPPET, then `await __npStructuredAddress(documentId)`.
//
// Returns null (caller falls back to the flattened parse) when:
//   - documentId is missing,
//   - the endpoint can't be fetched / parsed,
//   - the order ships "Same as billing" (no own shipping record),
//   - the record lacks street/city/postCode (not enough to trust).
// The numeric Shoptet countryId is returned raw; map it to ISO in Node via
// shared/shoptet/shoptet-country-ids.js (locale-independent).

const SHIPPING_MODAL_SNIPPET = `
async function __npStructuredAddress(documentId) {
  if (!documentId) return null;
  try {
    var url = location.origin + '/admin/edit-shipping-address/?documentId=' + encodeURIComponent(documentId);
    var r = await fetch(url, { credentials: 'include', redirect: 'follow' });
    if (!r.ok) return null;
    var txt = await r.text();
    var doc = null;
    try { doc = new DOMParser().parseFromString(txt, 'text/html'); } catch (e) {}
    var box = doc && doc.querySelector('#shippingAddressBox, [name="shippingAddressBox"]');
    var streetInput = doc && doc.querySelector('#deliveryStreet, [name="deliveryStreet"]');
    if (!box && !streetInput) {
      // Some Shoptet builds return the modal wrapped in a JSON envelope.
      try {
        var j = JSON.parse(txt);
        var h = j.content || j.html || j.body || (j.data && (j.data.content || j.data.html));
        if (h) {
          doc = new DOMParser().parseFromString(String(h), 'text/html');
          box = doc.querySelector('#shippingAddressBox, [name="shippingAddressBox"]');
          streetInput = doc.querySelector('#deliveryStreet, [name="deliveryStreet"]');
        }
      } catch (e2) {}
    }
    if (!doc) return null;
    function gv(sel) {
      var el = doc.querySelector(sel);
      if (!el) return '';
      return String(el.value != null ? el.value : (el.getAttribute('value') || '')).trim();
    }
    var rec = null;
    // Primary source: the SELECTED address option's data-record JSON.
    if (box && box.options) {
      var opt = box.options[box.selectedIndex] || box.querySelector('option[selected]');
      if (opt && String(opt.value || '').trim()) {
        // A SAVED shipping record — read its data-record JSON.
        try { rec = JSON.parse(opt.getAttribute('data-record') || 'null'); } catch (e3) { rec = null; }
      }
      // An empty option value is EITHER "Same as billing" OR a freshly-typed
      // "New address" Shoptet hasn't persisted as a saved record yet. Do NOT bail
      // here (the old early return null sent a different PL/SK delivery address to
      // the billing fallback -> wrong-country zip, GLS receiver-zipcode-invalid).
      // Fall through to the live #delivery* inputs below: they are populated for a
      // New address; if they are empty too (genuine Same-as-billing) the
      // street/city/zip guard below returns null and the billing fallback takes over.
    }
    var fullName, company, street, building, city, district, additional, zip, countryId, region;
    if (rec && (rec.deliveryStreet || rec.deliveryCity || rec.deliveryZip)) {
      fullName = rec.deliveryFullName; company = rec.deliveryCompany;
      street = rec.deliveryStreet; building = rec.deliveryHouseNumber;
      city = rec.deliveryCity; district = rec.deliveryDistrict;
      additional = rec.deliveryAdditional; zip = rec.deliveryZip;
      countryId = rec.deliveryCountryId; region = rec.deliveryRegionName;
    } else {
      // Fallback: read the live (populated) modal inputs.
      fullName = gv('#deliveryFullName'); company = gv('#deliveryCompany');
      street = gv('#deliveryStreet'); building = gv('#deliveryHouseNumber');
      city = gv('#deliveryCity'); district = gv('#deliveryDistrict');
      additional = gv('#deliveryAdditional'); zip = gv('#deliveryZip');
      region = gv('#deliveryRegionName');
      var csel = doc.querySelector('#deliveryCountryId, [name="deliveryCountryId"]');
      if (csel && csel.options) {
        var co = csel.options[csel.selectedIndex] || csel.querySelector('option[selected]');
        countryId = co ? co.value : (csel.value || '');
      } else if (csel) {
        countryId = csel.value || '';
      }
    }
    function s(v) { return v == null ? '' : String(v).trim(); }
    street = s(street); city = s(city); zip = s(zip);
    if (!street || !city || !zip) return null; // not enough to trust
    return {
      recipientName: s(fullName),
      recipientCompany: s(company),
      street: street,
      building: s(building),
      city: city,
      postCode: zip,
      district: s(district),
      additional: s(additional),
      region: s(region),
      countryId: (countryId != null && String(countryId).trim() !== '') ? String(countryId).trim() : null
    };
  } catch (e) { return null; }
}
`;

// Pull the numeric document/order id out of a Shoptet order URL (?id= or
// ?documentId=). The edit-shipping-address endpoint keys on documentId, which
// equals the order's document id.
function extractDocumentId(u) {
  var m = String(u || '').match(/[?&](?:documentId|id)=(\d+)/i);
  return m ? m[1] : '';
}

module.exports = { SHIPPING_MODAL_SNIPPET, extractDocumentId };
