(function (global) {
  const BOGOTA_TIME_ZONE = "America/Bogota";
  const COLOMBIA_OFFSET = "-05:00";
  const DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
  const ISO_DATE_TIME_PATTERN =
    /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:\d{2})?$/i;

  const dateFormatter = new Intl.DateTimeFormat("es-CO", {
    day: "2-digit",
    month: "short",
    year: "numeric",
    timeZone: "UTC",
  });
  const dateTimeFormatter = new Intl.DateTimeFormat("es-CO", {
    day: "2-digit",
    month: "short",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    hour12: true,
    timeZone: BOGOTA_TIME_ZONE,
  });

  function normalizeText(value) {
    return String(value ?? "").trim();
  }

  function parseDateOnly(value) {
    const normalized = normalizeText(value);
    if (!DATE_ONLY_PATTERN.test(normalized)) return null;
    const [year, month, day] = normalized.split("-").map(Number);
    const parsed = new Date(Date.UTC(year, month - 1, day));
    if (
      parsed.getUTCFullYear() !== year ||
      parsed.getUTCMonth() !== month - 1 ||
      parsed.getUTCDate() !== day
    ) {
      return null;
    }
    return parsed;
  }

  function parseDateTime(value) {
    const normalized = normalizeText(value);
    if (!normalized || !ISO_DATE_TIME_PATTERN.test(normalized)) return null;
    const isoValue = normalized.replace(" ", "T");
    const hasExplicitZone = /(?:Z|[+-]\d{2}:\d{2})$/i.test(isoValue);
    const parsed = new Date(hasExplicitZone ? isoValue : `${isoValue}${COLOMBIA_OFFSET}`);
    return Number.isNaN(parsed.getTime()) ? null : parsed;
  }

  function formatDateOnly(value) {
    const parsed = parseDateOnly(value);
    return parsed ? dateFormatter.format(parsed) : "";
  }

  function formatDateTime(value) {
    const parsed = parseDateTime(value);
    return parsed ? dateTimeFormatter.format(parsed) : "";
  }

  function formatMachineDate(value) {
    const normalized = normalizeText(value);
    if (!normalized) return "";
    if (DATE_ONLY_PATTERN.test(normalized)) {
      return formatDateOnly(normalized);
    }
    return formatDateTime(normalized);
  }

  function localizeMachineDates(root = global.document) {
    if (!root || typeof root.querySelectorAll !== "function") return;
    root.querySelectorAll("[data-local-date]").forEach((node) => {
      const rawValue = normalizeText(
        node.getAttribute("datetime") || node.dataset.rawDate || node.textContent
      );
      const formatted = formatMachineDate(rawValue);
      if (formatted) {
        node.textContent = formatted;
      }
    });
  }

  global.AppDateTime = Object.freeze({
    BOGOTA_TIME_ZONE,
    formatDateOnly,
    formatDateTime,
    formatMachineDate,
    localizeMachineDates,
  });
})(globalThis);
