(() => {
  'use strict';

  const language = document.documentElement.lang || navigator.language || 'de-DE';
  const zone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';
  const formatter = new Intl.DateTimeFormat(language, {
    dateStyle: 'short',
    timeStyle: 'medium'
  });

  function parseUtc(value) {
    if (!value) return null;
    let normalized = String(value).trim();
    if (!normalized) return null;
    // Project database timestamps without an offset are UTC by convention.
    if (/^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?$/.test(normalized)) {
      normalized = normalized.replace(' ', 'T') + 'Z';
    }
    const date = new Date(normalized);
    return Number.isNaN(date.getTime()) ? null : date;
  }

  function formatUtc(value, fallback = '') {
    const date = parseUtc(value);
    return date ? formatter.format(date) : (fallback || value || '');
  }

  function localizeElement(element) {
    const value = element.getAttribute('datetime') || element.dataset.utc;
    if (!value) return;
    const formatted = formatUtc(value, element.textContent);
    element.textContent = formatted;
    element.title = `${value} UTC · ${zone}`;
    element.dataset.localTimeApplied = 'true';
    const cell = element.closest('[data-sort-value]');
    if (cell) cell.dataset.sortValue = value;
  }

  const isoPattern = /(?<!\d)(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)(?!\d)/g;
  function localizeLogText(element) {
    if (!element || element.dataset.localizingLog === 'true') return;
    const original = element.textContent || '';
    const converted = original.replace(isoPattern, match => formatUtc(match, match));
    if (converted !== original) {
      element.dataset.localizingLog = 'true';
      element.textContent = converted;
      delete element.dataset.localizingLog;
    }
    element.title = zone;
  }

  function scan(root = document) {
    if (root.matches?.('time[data-utc], time[datetime].local-time')) localizeElement(root);
    root.querySelectorAll?.('time[data-utc], time[datetime].local-time').forEach(localizeElement);
    if (root.matches?.('[data-localize-log]')) localizeLogText(root);
    root.querySelectorAll?.('[data-localize-log]').forEach(localizeLogText);
  }

  window.AssetManagerTime = {formatUtc, parseUtc, zone, scan};
  scan(document);

  const observer = new MutationObserver(mutations => {
    for (const mutation of mutations) {
      mutation.addedNodes.forEach(node => {
        if (node.nodeType === Node.ELEMENT_NODE) scan(node);
      });
      const owner = mutation.target.nodeType === Node.ELEMENT_NODE
        ? mutation.target.closest?.('[data-localize-log]')
        : mutation.target.parentElement?.closest?.('[data-localize-log]');
      if (owner) localizeLogText(owner);
    }
  });
  observer.observe(document.body, {childList: true, subtree: true, characterData: true});
})();
