/* doc-project | caisse-aqp/public/assets/js/services/payloads/orderAddressPayloadNormalizer.js | Normalise les payloads commande avant sauvegarde/mise à jour en convertissant les sélecteurs UI composites ville/code postal en champs séparés compatibles backend, en ne mettant à jour code_postal / ville que lorsqu’une option valide du PDV est réellement sélectionnée, et en marquant sinon explicitement les conteneurs à préserver pour empêcher tout écrasement silencieux des valeurs déjà présentes en base. | Expose: normalizeOrderAddressPayload | Dépend de: JSON, ../../app-js/address/deliveryCityChoices.js?ts=20260405-1 | Impacte: payloads envoyés à saveOrder.php et updateOrder.php, cohérence des adresses client et adresses temporaires, validation backend des communes autorisées, conservation des adresses historiques hors PDV | Tables: aucune */

import { buildAllowedChoiceValue as buildAllowedDeliveryCityChoiceValue } from "../../app-js/address/deliveryCityChoices.js?ts=20260405-1";

function cloneJsonSafe(value){
  try{
    return JSON.parse(JSON.stringify(value ?? {}));
  } catch (_e){
    return {};
  }
}

function isPostalCode(value){
  return /^\d{4,6}$/.test(String(value ?? "").trim());
}

function normalizeStoreSuffix(value){
  const s = String(value ?? "").trim().toLowerCase();
  return s === "pel" ? "pel" : "lan";
}

function parseCompositeCityPostal(value){
  const raw = String(value ?? "").trim();
  if (!raw) return null;

  const parts = raw
    .split("|")
    .map((item) => String(item ?? "").trim())
    .filter(Boolean);

  if (parts.length !== 2) return null;

  const a = parts[0];
  const b = parts[1];

  if (isPostalCode(a) && !isPostalCode(b)){
    return { codePostal: a, ville: b };
  }
  if (!isPostalCode(a) && isPostalCode(b)){
    return { codePostal: b, ville: a };
  }

  return null;
}

function readNonEmpty(obj, keys){
  const src = (obj && typeof obj === "object") ? obj : {};
  const list = Array.isArray(keys) ? keys : [];
  for (const key of list){
    const value = String(src?.[key] ?? "").trim();
    if (value) return value;
  }
  return "";
}

function deleteKeys(obj, keys){
  if (!obj || typeof obj !== "object") return;
  const list = Array.isArray(keys) ? keys : [];
  for (const key of list){
    try { delete obj[key]; } catch (_e) {}
  }
}

function normalizeAddressContainer(container, config = {}){
  const target = (container && typeof container === "object") ? container : null;
  if (!target) return;

  const compositeValue = readNonEmpty(target, config.compositeKeys);
  const parsed = parseCompositeCityPostal(compositeValue);
  const selectedChoiceValue = parsed
    ? buildAllowedDeliveryCityChoiceValue(config.storeSuffix, parsed.ville, parsed.codePostal)
    : "";
  const hasValidSelectedChoice = selectedChoiceValue !== "";

  const finalPostal = hasValidSelectedChoice
    ? String(parsed?.codePostal ?? "").trim()
    : readNonEmpty(target, config.postalKeys);
  const finalCity = hasValidSelectedChoice
    ? String(parsed?.ville ?? "").trim()
    : readNonEmpty(target, config.cityKeys);

  if (config.preferredPostalKey && (finalPostal || readNonEmpty(target, [config.preferredPostalKey]))){
    target[config.preferredPostalKey] = finalPostal;
  }
  if (config.preferredCityKey && (finalCity || readNonEmpty(target, [config.preferredCityKey]))){
    target[config.preferredCityKey] = finalCity;
  }
  if (config.preserveFlagKey){
    if (hasValidSelectedChoice){
      try { delete target[config.preserveFlagKey]; } catch (_e) {}
    } else {
      target[config.preserveFlagKey] = 1;
    }
  }

  if (Array.isArray(config.postalAliases)){
    for (const key of config.postalAliases){
      if (key !== config.preferredPostalKey){
        try { delete target[key]; } catch (_e) {}
      }
    }
  }
  if (Array.isArray(config.cityAliases)){
    for (const key of config.cityAliases){
      if (key !== config.preferredCityKey){
        try { delete target[key]; } catch (_e) {}
      }
    }
  }

  deleteKeys(target, config.compositeKeys);
}

export function normalizeOrderAddressPayload(payload){
  const out = cloneJsonSafe(payload);
  const storeSuffix = normalizeStoreSuffix(out.store ?? out.storeId ?? out.store_id);

  normalizeAddressContainer(out, {
    compositeKeys: ["deliveryCityChoice", "city_choice"],
    postalKeys: ["codePostal", "code_postal"],
    cityKeys: ["ville", "city"],
    preferredPostalKey: "codePostal",
    preferredCityKey: "ville",
    postalAliases: ["codePostal", "code_postal"],
    cityAliases: ["ville", "city"],
    storeSuffix,
  });

  normalizeAddressContainer(out.client, {
    compositeKeys: ["deliveryCityChoice", "city_choice"],
    postalKeys: ["codePostal", "code_postal"],
    cityKeys: ["ville", "city"],
    preferredPostalKey: "code_postal",
    preferredCityKey: "ville",
    postalAliases: ["codePostal", "code_postal"],
    cityAliases: ["ville", "city"],
    preserveFlagKey: "deliveryCityChoicePreserveExisting",
    storeSuffix,
  });

  normalizeAddressContainer(out.customer, {
    compositeKeys: ["deliveryCityChoice", "city_choice"],
    postalKeys: ["codePostal", "code_postal"],
    cityKeys: ["ville", "city"],
    preferredPostalKey: "code_postal",
    preferredCityKey: "ville",
    postalAliases: ["codePostal", "code_postal"],
    cityAliases: ["ville", "city"],
    preserveFlagKey: "deliveryCityChoicePreserveExisting",
    storeSuffix,
  });

  normalizeAddressContainer(out.address, {
    compositeKeys: ["deliveryCityChoice", "city_choice"],
    postalKeys: ["codePostal", "code_postal"],
    cityKeys: ["ville", "city"],
    preferredPostalKey: "code_postal",
    preferredCityKey: "ville",
    postalAliases: ["codePostal", "code_postal"],
    cityAliases: ["ville", "city"],
    preserveFlagKey: "deliveryCityChoicePreserveExisting",
    storeSuffix,
  });

  normalizeAddressContainer(out.temporaryDeliveryAddress, {
    compositeKeys: ["temporaryDeliveryCityChoice", "deliveryCityChoice", "city_choice"],
    postalKeys: ["codePostal", "code_postal"],
    cityKeys: ["ville", "city"],
    preferredPostalKey: "code_postal",
    preferredCityKey: "ville",
    postalAliases: ["codePostal", "code_postal"],
    cityAliases: ["ville", "city"],
    preserveFlagKey: "deliveryCityChoicePreserveExisting",
    storeSuffix,
  });

  normalizeAddressContainer(out.temporary_delivery_address, {
    compositeKeys: ["temporaryDeliveryCityChoice", "deliveryCityChoice", "city_choice"],
    postalKeys: ["codePostal", "code_postal"],
    cityKeys: ["ville", "city"],
    preferredPostalKey: "code_postal",
    preferredCityKey: "ville",
    postalAliases: ["codePostal", "code_postal"],
    cityAliases: ["ville", "city"],
    preserveFlagKey: "deliveryCityChoicePreserveExisting",
    storeSuffix,
  });

  return out;
}