// @ts-check

import { L } from './map-service.js';

// --- CSS INJEKTION FÜR GROSSE DREIECKE ---
(function injectMarkerStyles() {
  const styleId = "marker-fix-styles";
  if (typeof document !== 'undefined' && !document.getElementById(styleId)) {
    const style = document.createElement('style');
    style.id = styleId;
    style.innerHTML = `
      .leaflet-marker-icon {
          background: none !important;
          border: none !important;
          overflow: visible !important; 
      }
      .marker-fa-stack {
          overflow: visible !important;
      }
      .marker-fa-icon {
          overflow: visible !important;
          display: flex !important;
          align-items: center;
          justify-content: center;
      }
      /* Korrektur für FontAwesome Positionierung im Stack */
      .fa-stack-1x {
          line-height: inherit !important;
          position: absolute !important;
      }
    `;
    document.head.appendChild(style);
  }
})();

/**
 * @type {HTMLDivElement|null}
 */
let toastElement = null;

/**
 * @type {number|null}
 */
let toastTimeout = null; 

/**
 * Zeigt den übergebenen String und ggf. den Parameter für kurze Zeit als Info an.
 * @param {string} message
 * @param {string} [details=""]
 * @param {number} [duration=3000]
 */
export function showToast(message, details = "", duration = 3000) {
  if (!toastElement) {
    toastElement = document.createElement('div');
    toastElement.id = 'toast-message';
    toastElement.style.cssText = `
      visibility: hidden;
      min-width: 250px;
      margin-left: -125px;
      background-color: #333;
      color: #fff;
      text-align: center;
      border-radius: 8px;
      padding: 16px;
      position: fixed;
      z-index: 999999;
      left: 50%;
      bottom: 50%;
      font-size: 17px;
      white-space: pre-wrap;
      opacity: 0;
      transition: opacity 0.5s ease-in-out;
      pointer-events: none;
    `;
    document.body.appendChild(toastElement);
  }

  if (toastTimeout) {
    clearTimeout(toastTimeout);
  }

  toastElement.innerText = message + (details ? "\n\n" + details : "");
  toastElement.style.visibility = "visible";
  toastElement.style.opacity = "1";

  toastTimeout = window.setTimeout(() => {
    if (toastElement) {
      toastElement.style.opacity = "0";

      window.setTimeout(() => {
        if (toastElement && toastElement.style.opacity === "0") {
          toastElement.style.visibility = "hidden";
        }
      }, 500);
    }
    toastTimeout = null;
  }, duration);
}

/**
 * @returns {boolean}
 */
export function is_development() {
  return window.location.pathname.includes("DEVELOPMENT");
}

/**
 * @param {number} ms
 * @returns {Promise<void>}
 */
export function wait(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

/**
 * @returns {string}
 */
export function getCurrentTimestamp() {
  return new Date().toISOString();
}

/**
 * @returns {string}
 */
export function getCurrentUser() {
  const username = localStorage.getItem('username');
  return username || 'Unbekannt';
}

/**
 * @returns {Promise<void>}
 */
export function forceRedraw() {
  return new Promise(resolve => {
    requestAnimationFrame(() => {
      setTimeout(resolve, 0);
    });
  });
}

/**
 * @param {number} ms
 * @returns {Promise<never>}
 */
export function timeoutPromise(ms) {
  return new Promise((_, reject) =>
    setTimeout(() => reject(new Error(`Timeout nach ${ms}ms`)), ms)
  );
}

/**
 * @param {number|null|undefined} userLat
 * @param {number|null|undefined} userLng
 * @param {number|null|undefined} itemLat
 * @param {number|null|undefined} itemLng
 * @param {number} [maxDistance=600000]
 * @returns {boolean|null}
 */
export function checkDistance(userLat, userLng, itemLat, itemLng, maxDistance = 600000) {
  if (userLat == null || userLng == null || itemLat == null || itemLng == null) return null;
  if (!isNaN(userLat) && !isNaN(userLng)) {
    // Absicherung gegen nicht initialisierte Leaflet-Instanz
    if (!L) return false;
    const distance = L.latLng(userLat, userLng).distanceTo(L.latLng(itemLat, itemLng));
    return distance <= maxDistance;
  }
  return false;
}

/**
 * @param {...any} args
 */
export function mylog(...args) {
  const timestamp = new Date().toLocaleString('de-DE', {
    year: 'numeric', month: '2-digit', day: '2-digit',
    hour: '2-digit', minute: '2-digit', second: '2-digit',
    fractionalSecondDigits: 3, hour12: false
  });
  console.log(`[${timestamp}]`, ...args);
}

/**
 * @param {string} text
 */
export function updateSpinner(text) {
  const textElement = document.querySelector('#loading-spinner-content p');
  if (textElement) textElement.textContent = text;
}

/**
 * @param {string|null|undefined} lastCleanedTimestamp
 * @returns {{colorCode: string, text: string}}
 */
export function getColorCodeAndText(lastCleanedTimestamp) {
  const now = new Date();
  let colorCode = "gray";
  let text = "Unbekannt";

  if (lastCleanedTimestamp) {
    const lastCleaned = new Date(lastCleanedTimestamp);
    // Mathematische Operation durch getTime() abgesichert für numerische Differenzierung
    const diffDays = Math.ceil(Math.abs(now.getTime() - lastCleaned.getTime()) / (1000 * 60 * 60 * 24));

    if (diffDays <= 30) { colorCode = "green"; text = "im letzten Monat"; }
    else if (diffDays <= 90) { colorCode = "yellow"; text = "vor 2 bis 3 Monaten"; }
    else if (diffDays <= 180) { colorCode = "orange"; text = "vor 4 bis 6 Monaten"; }
    else { colorCode = "red"; text = "vor über 6 Monaten"; }
  }
  return { colorCode, text };
}

/**
 * Generiert das Marker-Icon.
 * @param {string|null|undefined} caretakerStatus
 * @param {string} colorCode
 * @returns {string}
 */
export function getMarkerIcon(caretakerStatus, colorCode) {
  const isShield = caretakerStatus?.trim();
  let displayColor = colorCode === "green" ? "#28a745" : colorCode;
  const symbolColor = colorCode === "yellow" ? "black" : "white";

  if (isShield) {
    return `<i class="fas fa-shield-alt marker-fa-icon" style="font-size: 42px; color: ${displayColor}; filter: drop-shadow(0 0 2px rgba(0,0,0,0.4));"></i>`;
  }

  return `
    <div class="marker-fa-stack" style="width: 50px; height: 50px; display: flex; align-items: center; justify-content: center; filter: drop-shadow(0 0 2px rgba(0,0,0,0.4));">
      <svg viewBox="0 0 512 512" style="width: 42px; height: 42px;" xmlns="http://www.w3.org/2000/svg">
        <path fill="${displayColor}" d="M449.07 399.08L278.64 82.58c-12.08-22.44-44.26-22.44-56.35 0L51.87 399.08A32 32 0 0080.05 448h340.92a32 32 0 0028.1-48.92z"/>
        <rect x="232" y="190" width="48" height="130" rx="24" fill="${symbolColor}" />
        <circle cx="256" cy="370" r="28" fill="${symbolColor}" />
      </svg>
    </div>
  `;
}

/**
 * @param {string} errorMessage
 * @returns {never}
 */
export function terminateApp(errorMessage) {
  console.error("KRITISCHER FEHLER: App-Ausführung gestoppt.", errorMessage);

  document.body.innerHTML = `
            <div style="
                position: fixed; top: 0; left: 0; width: 100%; height: 100%; 
                background: #fff5f5; color: #900; font-family: sans-serif; 
                display: flex; flex-direction: column; align-items: center; 
                justify-content: center; z-index: 9999; padding: 20px; text-align: center;
            ">
                <h2 style="margin-bottom: 10px;">⚠️ Anwendung gestoppt</h2>
                <p style="font-size: 1.1em;">Sicherheitsprüfung fehlgeschlagen: <br>
                   <strong style="color: #000;">${errorMessage}</strong></p>
                <hr style="width: 50px; border: 1px solid #900; margin: 20px 0;">
                <p style="font-size: 0.9em; color: #666;">
                    Bitte prüfen Sie die URL-Parameter (z.B. <code>?db=prod</code>).
                </p>
            </div>
        `;

  window.stop();
  throw new Error("Application execution terminated by UIUtils.");
}

/**
 * FrontendConfig - One-and-Only Instanz für env und Passwort-Regeln.
 */
class FrontendConfig {
  /**
   * @type {FrontendConfig|null}
   */
  static instance = null;

  constructor() {
    if (FrontendConfig.instance) {
      return FrontendConfig.instance;
    }

    /**
     * @private
     * @type {{minPwdLength: number, env: string}}
     */
    this._config = {
      minPwdLength: 8,
      env: 'prod' 
    };
    
    /**
     * @private
     * @type {boolean}
     */
    this._isLoaded = false;

    FrontendConfig.instance = this;
  }

  /**
   * @returns {Promise<boolean>}
   */
  async load() {
    if (this._isLoaded) return true;

    try {
      const response = await fetch(`get-frontend-config.php${window.location.search}`);
      if (!response.ok) throw new Error(`HTTP ${response.status}`);

      const data = await response.json();
      if (data && data.success && data.config) {
        this._config.minPwdLength = parseInt(data.config.minPwdLength, 10) || 8;
        this._config.env = data.config.env || 'prod';

        this._isLoaded = true;
        mylog("FrontendConfig: Werte vom Server übernommen.", this._config);
        return true;
      }
    } catch (e) {
      // Catch-Block Variable 'e' wird zu 'error' zwecks Typisierung oder Typ-Assertion konvertiert
      const error = /** @type {Error} */ (e);
      console.error("FrontendConfig: Fehler beim Laden, nutze Defaults.", error.message);
    }
    return false;
  }

  /** @returns {number} */
  get minPwdLength() { return this._config.minPwdLength; }
  
  /** @returns {string} */
  get env() { return this._config.env; }
}

export const frontendConfig = new FrontendConfig();

/** Globaler Event-Bus — querschnittlich für poi/cluster/map/app-Events. */
export const appEvents = new EventTarget();