<template>
  <DialogWidget
    ref="dlg"
    name="falukant-messages"
    :title="'falukant.messages.title'"
    :isTitleTranslated="true"
    icon="falukant/messages24.png"
  :buttons="[
    { text: 'falukant.messages.markAllRead', action: 'markAll' },
    { text: 'message.close', action: 'close' }
  ]"
    width="520px"
    height="420px"
  >
    <ul class="messages">
      <li v-for="n in messages" :key="n.id" :class="{ unread: !n.shown }">
        <div class="body">
          <div v-if="formatBody(n).title" class="notification-title">{{ formatBody(n).title }}</div>
          <div class="notification-description" v-html="formatBody(n).description || formatBody(n)"></div>
        </div>
        <div class="footer">
          <span>{{ formatDate(n.createdAt) }}</span>
        </div>
      </li>
      <li v-if="messages.length === 0" class="empty">{{ $t('falukant.messages.empty') }}</li>
    </ul>
    <div class="pagination" v-if="total > size">
      <button @click="firstPage" :disabled="!canPrev">«</button>
      <button @click="prevPage" :disabled="!canPrev">‹</button>
      <span>
        <input type="number" min="1" :max="totalPages" v-model.number="pageInput" @change="goToPage(pageInput)" />
        / {{ totalPages }}
      </span>
      <button @click="nextPage" :disabled="!canNext">›</button>
      <button @click="lastPage" :disabled="!canNext">»</button>
    </div>
  </DialogWidget>
  </template>

<script>
import DialogWidget from '@/components/DialogWidget.vue';
import apiClient from '@/utils/axios.js';

export default {
  name: 'FalukantMessagesDialog',
  components: { DialogWidget },
  data() {
    return {
      messages: [],
      page: 1,
      size: 10,
      total: 0,
  pageInput: 1,
    };
  },
  methods: {
    async open() {
      this.page = 1;
  this.pageInput = 1;
      await this.load();
      this.$refs.dlg.open();
      // mark unread as shown
      try { await apiClient.post('/api/falukant/notifications/mark-shown'); } catch {}
    },
    async markAll() {
      try {
        await apiClient.post('/api/falukant/notifications/mark-shown');
        // reload to update shown flags and unread count
        await this.load();
      } catch (e) {
        // ignore errors silently
      }
    },
    async load() {
      try {
        const { data } = await apiClient.get('/api/falukant/notifications/all', { params: { page: this.page, size: this.size } });
        if (data && Array.isArray(data.items)) {
          this.messages = data.items;
          this.total = data.total || 0;
        } else {
          this.messages = Array.isArray(data) ? data : [];
          this.total = this.messages.length;
        }
      } catch (e) {
        console.error('Failed to load messages', e);
        this.messages = [];
        this.total = 0;
      }
    },
    nextPage() {
      if (this.page < this.totalPages) {
        this.page++;
        this.pageInput = this.page;
        this.load();
      }
    },
    prevPage() {
      if (this.page > 1) {
        this.page--;
        this.pageInput = this.page;
        this.load();
      }
    },
    firstPage() {
      if (this.page !== 1) {
        this.page = 1;
        this.pageInput = 1;
        this.load();
      }
    },
    lastPage() {
      if (this.page !== this.totalPages) {
        this.page = this.totalPages;
        this.pageInput = this.page;
        this.load();
      }
    },
    goToPage(val) {
      let v = Number(val) || 1;
      if (v < 1) v = 1;
      if (v > this.totalPages) v = this.totalPages;
      if (v !== this.page) {
        this.page = v;
        this.pageInput = v;
        this.load();
      } else {
        this.pageInput = v;
      }
    },
    formatDate(dt) {
      try {
        return new Date(dt).toLocaleString();
      } catch { return dt; }
    },
    formatBody(n) {
      let raw = n.tr || '';
      let parsed = null;
      let value = null;
      let key = raw;
      let params = {};

      // 1) Parse JSON-Format: {"tr":"random_event.character_illness","value":{...}}
      if (typeof raw === 'string') {
        const trimmed = raw.trim();
        if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
          try {
            parsed = JSON.parse(trimmed);
            if (parsed && parsed.tr) {
              key = parsed.tr;
              value = parsed.value || {};
              
              // Extrahiere Parameter aus value und effects
              params = this.extractParamsFromValue(value, n);
              
              // Wenn value eine einfache Zahl ist (z.B. für overproduction), als value-Parameter verwenden
              if (typeof parsed.value === 'number') {
                params.value = parsed.value;
              }
              
              // Weitere Parameter aus parsed extrahieren (z.B. branch_id)
              if (parsed.branch_id !== undefined) {
                params.branch_id = parsed.branch_id;
              }
              if (parsed.region_id !== undefined) {
                params.region_id = parsed.region_id;
              }
            }
          } catch (e) {
            // Bei Parse-Fehler: Alte Struktur unterstützen
            try {
              parsed = JSON.parse(trimmed);
              if (parsed && parsed.tr) {
                key = parsed.tr;
                params = this.formatParams({ ...parsed });
                delete params.tr;
              }
            } catch (e2) {
              // Ignore parse errors
            }
          }
        }
      }

      // 2) Wenn value.title und value.description vorhanden sind, verwende diese
      if (value && value.title && value.description) {
        // Parameter aus effects extrahieren und formatieren
        const formattedParams = this.formatParams(params);
        // Zuerst Description interpolieren (für {amount} etc.), dann Effects hinzufügen
        let description = this.interpolateString(value.description, formattedParams);
        description = this.formatDescriptionWithEffects(description, value.effects || [], formattedParams);
        return {
          title: this.interpolateString(value.title, formattedParams),
          description: description
        };
      }

      // 3) Schlüssel normalisieren
      if (typeof key === 'string') {
        const trimmedKey = key.trim();
        if (trimmedKey.startsWith('falukant.')) {
          key = trimmedKey;
        } else {
          key = 'falukant.notifications.' + trimmedKey;
        }
      }

      // 4) Prüfe, ob es sich um ein random_event handelt mit title/description Struktur
      if (key.startsWith('falukant.notifications.random_event.')) {
        const eventId = key.replace('falukant.notifications.random_event.', '');
        const eventKey = `falukant.notifications.random_event.${eventId}`;
        try {
          const titleKey = `${eventKey}.title`;
          const descKey = `${eventKey}.description`;
          
          // Wenn keine Parameter extrahiert wurden, versuche es aus der Notification
          if ((!params || Object.keys(params).length === 0) && n) {
            params = this.extractParams(n) || {};
          }
          
          // Wenn value vorhanden ist, verwende effects für Details
          if (value && value.effects) {
            params = this.extractParamsFromValue(value, n);
          }

          const formattedParams = this.formatParams(params);
          
          if (this.$te(titleKey) && this.$te(descKey)) {
            const title = this.$t(titleKey, formattedParams);
            let description = this.$t(descKey, formattedParams);
            
            // Stelle sicher, dass auch hier die Parameter interpoliert werden (für {amount} etc.)
            // Vue i18n interpoliert bereits, aber wir müssen sicherstellen, dass formatParams korrekt formatiert
            description = this.interpolateString(description, formattedParams);
            
            // Füge Effect-Details hinzu, falls vorhanden
            if (value && value.effects) {
              description = this.formatDescriptionWithEffects(description, value.effects, formattedParams);
            }
            
            return { title, description };
          }
        } catch (e) {
          // Fallback zur alten Methode
        }
      }

      // Fallback: Alte Methode für andere Notification-Typen
      const formattedParams = this.formatParams(params);
      return this.$t(key, formattedParams);
    },
    
    formatParams(params) {
      const formatted = {};
      
      // Geldbeträge formatieren
      if (params.amount !== undefined && params.amount !== null) {
        formatted.amount = this.formatMoney(Number(params.amount));
      }
      if (params.absolute !== undefined && params.absolute !== null) {
        formatted.amount = this.formatMoney(Number(params.absolute));
      }
      if (params.percent !== undefined && params.percent !== null) {
        formatted.percent = `${params.percent > 0 ? '+' : ''}${params.percent.toFixed(1)}%`;
      }
      
      // Einfache Werte (z.B. für overproduction)
      if (params.value !== undefined && params.value !== null) {
        formatted.value = Number(params.value);
      }
      
      // Filiale-Information
      if (params.branch_id !== undefined && params.branch_id !== null) {
        formatted.branch_info = ` (Filiale #${params.branch_id})`;
      } else {
        formatted.branch_info = '';
      }
      
      // Gesundheit formatieren
      if (params.change !== undefined && params.change !== null) {
        formatted.healthChange = params.change > 0 ? `+${params.change}` : `${params.change}`;
        formatted.change = formatted.healthChange;
      }
      if (params.healthChange !== undefined && params.healthChange !== null && !formatted.healthChange) {
        formatted.healthChange = typeof params.healthChange === 'string' 
          ? params.healthChange 
          : (params.healthChange > 0 ? `+${params.healthChange}` : `${params.healthChange}`);
      }
      
      // Charakternamen
      if (params.characterName) {
        formatted.characterName = params.characterName;
      }
      if (params.character_first_name || params.character_last_name) {
        const firstName = params.character_first_name || '';
        const lastName = params.character_last_name || '';
        formatted.characterName = `${firstName} ${lastName}`.trim() || formatted.characterName;
      }
      
      // Regions-Informationen
      if (params.regionName) {
        formatted.regionName = params.regionName;
      }
      if (params.region_id) {
        formatted.region_id = params.region_id;
      }
      
      // Schaden formatieren (für Kompatibilität mit alter Struktur)
      if (params.inventory_damage_percent !== undefined && params.inventory_damage_percent !== null) {
        formatted.damagePercent = ` Lagerbestand beschädigt: ${params.inventory_damage_percent.toFixed(1)}%.`;
      }
      if (params.storage_destruction_percent !== undefined && params.storage_destruction_percent !== null) {
        formatted.destructionPercent = ` Lager zerstört: ${params.storage_destruction_percent.toFixed(1)}%.`;
      }
      
      // Alle anderen Parameter übernehmen
      for (const [key, value] of Object.entries(params)) {
        if (!formatted.hasOwnProperty(key) && key !== 'tr' && value !== undefined && value !== null) {
          formatted[key] = value;
        }
      }
      
      return formatted;
    },
    
    extractParamsFromValue(value, n) {
      const params = {};
      
      // Geldbeträge direkt aus value extrahieren (neue Struktur)
      if (value.money_change_absolute !== undefined && value.money_change_absolute !== null) {
        params.absolute = value.money_change_absolute;
        params.amount = value.money_change_absolute;
      }
      if (value.money_change_percent !== undefined && value.money_change_percent !== null) {
        params.percent = value.money_change_percent;
      }
      
      // Charakternamen aus value extrahieren
      if (value.character_first_name || value.character_last_name) {
        const firstName = value.character_first_name || '';
        const lastName = value.character_last_name || '';
        params.characterName = `${firstName} ${lastName}`.trim() || value.character_id ? `#${value.character_id}` : null;
      }
      if (value.character_id) {
        params.character_id = value.character_id;
      }
      
      // Regions-Informationen
      if (value.region_id) {
        params.region_id = value.region_id;
      }
      if (value.regionName) {
        params.regionName = value.regionName;
      }
      
      // Parameter aus effects extrahieren (falls nicht bereits aus value extrahiert)
      if (value.effects && Array.isArray(value.effects)) {
        for (const effect of value.effects) {
          if (effect.type === 'money_change') {
            // Nur verwenden, wenn nicht bereits aus value extrahiert
            if (params.absolute === undefined && effect.absolute !== undefined) {
              params.absolute = effect.absolute;
              params.amount = effect.absolute;
            }
            if (params.percent === undefined && effect.percent !== undefined) {
              params.percent = effect.percent;
            }
          } else if (effect.type === 'character_health_change') {
            // Charakternamen aus Effect haben Vorrang
            if (effect.character_first_name || effect.character_last_name) {
              const firstName = effect.character_first_name || '';
              const lastName = effect.character_last_name || '';
              params.characterName = `${firstName} ${lastName}`.trim();
            }
            if (effect.character_id) {
              params.character_id = effect.character_id;
            }
            if (effect.change !== undefined) {
              params.change = effect.change;
              params.healthChange = effect.change > 0 ? `+${effect.change}` : `${effect.change}`;
            }
          } else if (effect.type === 'character_death') {
            if (effect.character_first_name || effect.character_last_name) {
              const firstName = effect.character_first_name || '';
              const lastName = effect.character_last_name || '';
              params.characterName = `${firstName} ${lastName}`.trim();
            }
            if (effect.character_id) {
              params.character_id = effect.character_id;
            }
          } else if (effect.type === 'storage_damage') {
            if (effect.inventory_damage_percent !== undefined) {
              params.inventory_damage_percent = effect.inventory_damage_percent;
            }
            if (effect.storage_destruction_percent !== undefined) {
              params.storage_destruction_percent = effect.storage_destruction_percent;
            }
          } else if (effect.type === 'production_quality_change') {
            if (effect.change !== undefined) {
              params.productionQualityChange = effect.change;
            }
          } else if (effect.type === 'transport_speed_change') {
            if (effect.percent !== undefined) {
              params.transportSpeedChangePercent = effect.percent;
            }
          } else if (effect.type === 'storage_capacity_change') {
            if (effect.percent !== undefined) {
              params.storageCapacityChangePercent = effect.percent;
            }
          }
        }
      }
      
      // Fallback: Charakternamen aus Notification-Spalte
      if (!params.characterName && n.characterName) {
        params.characterName = n.characterName;
      }
      if (!params.characterName && n.character_id) {
        params.characterName = `#${n.character_id}`;
      }
      
      return params;
    },
    
    extractParams(n) {
      const params = {};
      
      // Parameter aus effects extrahieren (alte Struktur)
      if (n.effects && Array.isArray(n.effects)) {
        for (const effect of n.effects) {
          if (effect.type === 'money_change') {
            if (effect.absolute !== undefined) {
              params.amount = effect.absolute;
            } else if (effect.percent !== undefined) {
              params.percent = effect.percent;
            }
          } else if (effect.type === 'character_health_change') {
            if (effect.character_id) {
              params.character_id = effect.character_id;
              params.characterName = params.characterName || n.characterName || `#${effect.character_id}`;
            }
            if (effect.change !== undefined) {
              params.change = effect.change;
            }
          } else if (effect.type === 'character_death') {
            if (effect.character_id) {
              params.character_id = effect.character_id;
              params.characterName = params.characterName || n.characterName || `#${effect.character_id}`;
            }
          } else if (effect.type === 'storage_damage') {
            if (effect.inventory_damage_percent !== undefined) {
              params.inventory_damage_percent = effect.inventory_damage_percent;
            }
            if (effect.storage_destruction_percent !== undefined) {
              params.storage_destruction_percent = effect.storage_destruction_percent;
            }
          }
        }
      }
      
      // Weitere Parameter aus der Notification selbst
      if (n.region_id && n.regionName) {
        params.regionName = n.regionName;
      }
      if (n.character_id && n.characterName) {
        params.characterName = n.characterName;
      }
      if (n.amount !== undefined) {
        params.amount = n.amount;
      }
      
      return params;
    },
    
    formatDescriptionWithEffects(baseDescription, effects, params) {
      if (!effects || !Array.isArray(effects) || effects.length === 0) {
        return baseDescription;
      }
      
      let description = baseDescription;
      const effectDetails = [];
      
      for (const effect of effects) {
        if (effect.type === 'character_health_change') {
          const charName = effect.character_first_name && effect.character_last_name 
            ? `${effect.character_first_name} ${effect.character_last_name}`.trim()
            : params.characterName || `#${effect.character_id}`;
          const change = effect.change > 0 ? `+${effect.change}` : `${effect.change}`;
          effectDetails.push(`${charName} hat ${change} Gesundheit verloren.`);
        } else if (effect.type === 'character_death') {
          const charName = effect.character_first_name && effect.character_last_name 
            ? `${effect.character_first_name} ${effect.character_last_name}`.trim()
            : params.characterName || `#${effect.character_id}`;
          effectDetails.push(`${charName} ist verstorben.`);
        } else if (effect.type === 'production_quality_change') {
          const change = effect.change > 0 ? `+${effect.change}` : `${effect.change}`;
          effectDetails.push(`Produktionsqualität: ${change}.`);
        } else if (effect.type === 'transport_speed_change') {
          const percent = effect.percent > 0 ? `+${effect.percent.toFixed(1)}%` : `${effect.percent.toFixed(1)}%`;
          effectDetails.push(`Transportgeschwindigkeit: ${percent}.`);
        } else if (effect.type === 'storage_damage') {
          const stockType = effect.stock_type || 'Lager';
          const inventoryDamage = effect.inventory_damage_percent ? `${effect.inventory_damage_percent.toFixed(1)}%` : '0%';
          const storageDestruction = effect.storage_destruction_percent ? `${effect.storage_destruction_percent.toFixed(1)}%` : '0%';
          const affected = effect.affected_stocks ? effect.affected_stocks.length : 0;
          const destroyed = effect.destroyed_stocks ? effect.destroyed_stocks.length : 0;
          effectDetails.push(`${stockType}: ${inventoryDamage} Lagerbestand beschädigt, ${storageDestruction} Lager zerstört (${affected} betroffen, ${destroyed} zerstört).`);
        } else if (effect.type === 'storage_capacity_change') {
          const percent = effect.percent > 0 ? `+${effect.percent.toFixed(1)}%` : `${effect.percent.toFixed(1)}%`;
          const affected = effect.affected_stocks ? effect.affected_stocks.length : 0;
          effectDetails.push(`Lagerkapazität: ${percent} (${affected} betroffen).`);
        }
      }
      
      if (effectDetails.length > 0) {
        description += ' ' + effectDetails.join(' ');
      }
      
      return description;
    },
    
    interpolateString(str, params) {
      if (!str || typeof str !== 'string') return str;
      let result = str;
      for (const [key, value] of Object.entries(params)) {
        if (value !== undefined && value !== null && value !== '') {
          result = result.replace(new RegExp(`\\{${key}\\}`, 'g'), String(value));
        } else {
          // Entferne Platzhalter, wenn kein Wert vorhanden ist
          result = result.replace(new RegExp(`\\s*\\{${key}\\}\\s*`, 'g'), '');
        }
      }
      // Entferne doppelte Leerzeichen und trimme
      result = result.replace(/\s+/g, ' ').trim();
      return result;
    },
    
    formatMoney(amount) {
      return new Intl.NumberFormat(navigator.language, { 
        minimumFractionDigits: 2, 
        maximumFractionDigits: 2 
      }).format(amount);
    }
  },
  computed: {
    totalPages() {
      return Math.max(1, Math.ceil(this.total / this.size));
  },
  canPrev() { return this.page > 1; },
  canNext() { return this.page < this.totalPages; }
  }
};
</script>

<style scoped>
.messages {
  list-style: none;
  padding: 0;
  margin: 0;
}
.messages > li { border: 1px solid #7BBE55; margin-bottom: .25em; padding: .5em; }
.messages > li.unread { font-weight: bold; }
.messages > li .body { display: flex; flex-direction: column; gap: 0.25em; }
.messages > li .notification-title { font-weight: bold; font-size: 1.05em; }
.messages > li .notification-description { color: #555; }
.messages > li .footer { color: #f9a22c; font-size: .8em; margin-top: .3em; display: flex; }
.messages > li .footer span:first-child { flex: 1; }
.empty { text-align: center; color: #777; padding: 1em; }
.pagination {
  display: flex;
  justify-content: center;
  gap: .5em;
  margin-top: .5em;
}
.pagination button { padding: .25em .6em; }
.pagination input[type="number"] { width: 4em; text-align: right; }
</style>

