(() => {
const API_URL = 'https://fb.srv.medeba-media.de/api';
const LOGIN_PAGE = 'login.html';

const PROVIDER_MODELS = {
  gemini: [
    { value: '', label: 'Standard (gemini-2.0-flash-exp)' },
    { value: 'gemini-2.0-flash-exp', label: 'Gemini 2.0 Flash' },
    { value: 'gemini-1.5-flash', label: 'Gemini 1.5 Flash' },
    { value: 'gemini-1.5-pro', label: 'Gemini 1.5 Pro' }
  ],
  claude: [
    { value: '', label: 'Standard (claude-3-5-haiku)' },
    { value: 'claude-3-5-haiku-20241022', label: 'Claude 3.5 Haiku (schnell)' },
    { value: 'claude-3-5-sonnet-20241022', label: 'Claude 3.5 Sonnet (beste Qualität)' },
    { value: 'claude-3-opus-20240229', label: 'Claude 3 Opus' }
  ],
  openai: [
    { value: '', label: 'Standard (gpt-3.5-turbo)' },
    { value: 'gpt-3.5-turbo', label: 'GPT-3.5 Turbo (günstig)' },
    { value: 'gpt-4o-mini', label: 'GPT-4o Mini' },
    { value: 'gpt-4o', label: 'GPT-4o' },
    { value: 'gpt-4-turbo', label: 'GPT-4 Turbo' }
  ]
};

const PROVIDER_INFO = {
  gemini: {
    name: 'Google Gemini',
    apiKeyLink: 'https://aistudio.google.com/app/apikey',
    apiKeyHelp: 'API-Schlüssel erforderlich. Erstelle ihn im Google AI Studio.'
  },
  claude: {
    name: 'Anthropic Claude',
    apiKeyLink: 'https://console.anthropic.com/settings/keys',
    apiKeyHelp: 'API-Schlüssel erforderlich. Erstelle ihn in der Anthropic Console.'
  },
  openai: {
    name: 'OpenAI',
    apiKeyLink: 'https://platform.openai.com/api-keys',
    apiKeyHelp: 'Für lokale OpenAI-kompatible Server (z.B. Ollama) kannst du den Schlüssel leer lassen.'
  }
};

let credentials = [];
let currentSettings = null;
let hiddenSettings = { auto_purge_enabled: true, retention_days: 90 };
const SPORT_WEIGHT_FIELDS = [
  { key: 'scoreline', id: 'sportWeightScoreline' },
  { key: 'scoreEmoji', id: 'sportWeightScoreEmoji' },
  { key: 'sportEmoji', id: 'sportWeightSportEmoji' },
  { key: 'sportVerb', id: 'sportWeightSportVerb' },
  { key: 'sportNoun', id: 'sportWeightSportNoun' },
  { key: 'hashtag', id: 'sportWeightHashtag' },
  { key: 'teamToken', id: 'sportWeightTeamToken' },
  { key: 'competition', id: 'sportWeightCompetition' },
  { key: 'celebration', id: 'sportWeightCelebration' },
  { key: 'location', id: 'sportWeightLocation' }
];
const SPORT_TERM_FIELDS = [
  { key: 'nouns', id: 'sportTermsNouns', placeholder: 'auswärtssieg, liga, tor ...' },
  { key: 'verbs', id: 'sportTermsVerbs', placeholder: 'gewinnen, punkten ...' },
  { key: 'competitions', id: 'sportTermsCompetitions', placeholder: 'bundesliga, cup ...' },
  { key: 'celebrations', id: 'sportTermsCelebrations', placeholder: 'sieg, tabellenführung ...' },
  { key: 'locations', id: 'sportTermsLocations', placeholder: 'auswärts, stadion ...' },
  { key: 'negatives', id: 'sportTermsNegatives', placeholder: 'rezept, politik ...' }
];
let moderationSettings = {
  sports_scoring_enabled: true,
  sports_score_threshold: 5,
  sports_score_weights: {},
  sports_terms: {},
  sports_auto_hide_enabled: false
};
let similaritySettings = {
  text_threshold: 0.85,
  image_distance_threshold: 6
};

function handleUnauthorized(response) {
  if (response && response.status === 401) {
    if (typeof redirectToLogin === 'function') {
      redirectToLogin();
    } else {
      window.location.href = LOGIN_PAGE;
    }
    return true;
  }
  return false;
}

function apiFetch(url, options = {}) {
  return fetch(url, {...options, credentials: 'include'}).then((response) => {
    if (handleUnauthorized(response)) {
      throw new Error('Nicht angemeldet');
    }
    return response;
  });
}

function showToast(message, type = 'info') {
  const toast = document.createElement('div');
  toast.style.cssText = `
    position: fixed;
    bottom: 84px;
    right: 24px;
    background: ${type === 'error' ? '#e74c3c' : type === 'success' ? '#42b72a' : '#1877f2'};
    color: white;
    padding: 12px 20px;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    font-size: 14px;
    z-index: 999999;
    max-width: 350px;
    animation: slideIn 0.3s ease-out;
    pointer-events: none;
  `;
  toast.textContent = message;

  if (!document.getElementById('settings-toast-styles')) {
    const style = document.createElement('style');
    style.id = 'settings-toast-styles';
    style.textContent = `
      @keyframes slideIn {
        from {
          transform: translateX(400px);
          opacity: 0;
        }
        to {
          transform: translateX(0);
          opacity: 1;
        }
      }
      @keyframes slideOut {
        from {
          transform: translateX(0);
          opacity: 1;
        }
        to {
          transform: translateX(400px);
          opacity: 0;
        }
      }
    `;
    document.head.appendChild(style);
  }

  document.body.appendChild(toast);

  setTimeout(() => {
    toast.style.animation = 'slideOut 0.3s ease-out';
    setTimeout(() => toast.remove(), 300);
  }, 3000);
}

function showError(msg) { showToast(msg, 'error'); }
function showSuccess(msg) { showToast(msg, 'success'); }

async function loadCredentials() {
  const res = await apiFetch(`${API_URL}/ai-credentials`);
  if (!res.ok) throw new Error('Failed to load credentials');
  credentials = await res.json();
  renderCredentials();
  updateActiveCredentialSelect();
}

async function loadSettings() {
  const res = await apiFetch(`${API_URL}/ai-settings`);
  if (!res.ok) throw new Error('Failed to load settings');
  currentSettings = await res.json();
  document.getElementById('aiEnabled').checked = currentSettings.enabled === 1;
  document.getElementById('activeCredential').value = currentSettings.active_credential_id || '';
  document.getElementById('aiPromptPrefix').value = currentSettings.prompt_prefix || 
    'Schreibe einen freundlichen, authentischen Kommentar auf Deutsch zu folgendem Facebook-Post. Der Kommentar soll natürlich wirken und maximal 2-3 Sätze lang sein:\n\n';
}

async function loadHiddenSettings() {
  const res = await apiFetch(`${API_URL}/hidden-settings`);
  if (!res.ok) throw new Error('Failed to load hidden settings');
  hiddenSettings = await res.json();
  applyHiddenSettingsUI();
}

function applyHiddenSettingsUI() {
  const autoToggle = document.getElementById('autoPurgeHiddenToggle');
  const retentionInput = document.getElementById('hiddenRetentionDays');
  if (autoToggle) {
    autoToggle.checked = !!hiddenSettings.auto_purge_enabled;
  }
  if (retentionInput) {
    retentionInput.value = hiddenSettings.retention_days || 90;
    retentionInput.disabled = !autoToggle?.checked;
  }
}

function normalizeRetentionInput(value) {
  const parsed = parseInt(value, 10);
  if (Number.isNaN(parsed) || parsed <= 0) {
    return 90;
  }
  return Math.min(365, Math.max(1, parsed));
}

async function saveHiddenSettings(event, { silent = false } = {}) {
  if (event && typeof event.preventDefault === 'function') {
    event.preventDefault();
  }
  const autoToggle = document.getElementById('autoPurgeHiddenToggle');
  const retentionInput = document.getElementById('hiddenRetentionDays');
  const autoEnabled = autoToggle ? autoToggle.checked : true;
  const retention = normalizeRetentionInput(retentionInput ? retentionInput.value : hiddenSettings.retention_days);

  try {
    const res = await apiFetch(`${API_URL}/hidden-settings`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        auto_purge_enabled: autoEnabled,
        retention_days: retention
      })
    });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Fehler beim Speichern');
    }
    hiddenSettings = await res.json();
    applyHiddenSettingsUI();
    if (!silent) {
      showSuccess('✅ Einstellungen für versteckte Beiträge gespeichert');
    }
    return true;
  } catch (err) {
    if (!silent) {
      showError('❌ ' + err.message);
    }
    return false;
  }
}

async function purgeHiddenNow() {
  const btn = document.getElementById('purgeHiddenNowBtn');
  const originalText = btn ? btn.textContent : '';
  if (btn) {
    btn.disabled = true;
    btn.textContent = 'Bereinige...';
  }
  try {
    const res = await apiFetch(`${API_URL}/search-posts`, { method: 'DELETE' });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Fehler beim Bereinigen');
    }
    showSuccess('🧹 Versteckte Beiträge wurden zurückgesetzt');
  } catch (err) {
    showError('❌ ' + err.message);
  } finally {
    if (btn) {
      btn.disabled = false;
      btn.textContent = originalText || 'Jetzt bereinigen';
    }
  }
}

function normalizeSportsScoreThresholdInput(value) {
  const parsed = parseFloat(value);
  if (Number.isNaN(parsed) || parsed < 0) {
    return 5;
  }
  return Math.min(50, Math.max(0, parsed));
}

function normalizeSportWeightInput(value, fallback = 1) {
  const parsed = parseFloat(value);
  if (Number.isNaN(parsed) || parsed < 0) {
    return fallback;
  }
  return Math.min(10, Math.max(0, parsed));
}

function applyWeightInputs(enabled) {
  SPORT_WEIGHT_FIELDS.forEach(({ id }) => {
    const input = document.getElementById(id);
    if (input) {
      input.disabled = !enabled;
    }
  });
}

function applyTermInputs(enabled) {
  SPORT_TERM_FIELDS.forEach(({ id }) => {
    const input = document.getElementById(id);
    if (input) {
      input.disabled = !enabled;
    }
  });
}

function serializeTermListInput(value) {
  if (!value || typeof value !== 'string') return [];
  return value
    .split(',')
    .map((entry) => entry.trim())
    .filter((entry) => entry)
    .slice(0, 200);
}

function renderTermList(list) {
  if (!Array.isArray(list) || !list.length) return '';
  return list.join(', ');
}

function applyModerationSettingsUI() {
  const enabledToggle = document.getElementById('sportsScoringEnabled');
  const thresholdInput = document.getElementById('sportsScoreThreshold');
  const autoHideToggle = document.getElementById('sportsAutoHideEnabled');
  if (enabledToggle) {
    enabledToggle.checked = !!moderationSettings.sports_scoring_enabled;
  }
  if (thresholdInput) {
    thresholdInput.value = moderationSettings.sports_score_threshold ?? 5;
    thresholdInput.disabled = !enabledToggle?.checked;
  }
  if (autoHideToggle) {
    autoHideToggle.checked = !!moderationSettings.sports_auto_hide_enabled;
    autoHideToggle.disabled = !enabledToggle?.checked;
  }
  SPORT_WEIGHT_FIELDS.forEach(({ key, id }) => {
    const input = document.getElementById(id);
    if (input) {
      const value = moderationSettings.sports_score_weights?.[key];
      input.value = typeof value === 'number' ? value : '';
      input.disabled = !enabledToggle?.checked;
    }
  });
  SPORT_TERM_FIELDS.forEach(({ key, id }) => {
    const input = document.getElementById(id);
    if (input) {
      input.value = renderTermList(moderationSettings.sports_terms?.[key]);
      input.disabled = !enabledToggle?.checked;
    }
  });
}

async function loadModerationSettings() {
  const res = await apiFetch(`${API_URL}/moderation-settings`);
  if (!res.ok) throw new Error('Konnte Moderations-Einstellungen nicht laden');
  const data = await res.json();
  moderationSettings = {
    sports_scoring_enabled: !!data.sports_scoring_enabled,
    sports_score_threshold: normalizeSportsScoreThresholdInput(data.sports_score_threshold),
    sports_score_weights: data.sports_score_weights || {},
    sports_terms: data.sports_terms || {},
    sports_auto_hide_enabled: !!data.sports_auto_hide_enabled
  };
  applyModerationSettingsUI();
}

async function saveModerationSettings(event, { silent = false } = {}) {
  if (event && typeof event.preventDefault === 'function') {
    event.preventDefault();
  }
  const enabledToggle = document.getElementById('sportsScoringEnabled');
  const thresholdInput = document.getElementById('sportsScoreThreshold');
  const autoHideToggle = document.getElementById('sportsAutoHideEnabled');
  const enabled = enabledToggle ? enabledToggle.checked : true;
  const threshold = thresholdInput
    ? normalizeSportsScoreThresholdInput(thresholdInput.value)
    : moderationSettings.sports_score_threshold;
  const autoHide = autoHideToggle ? autoHideToggle.checked : false;
  const weights = {};
  SPORT_WEIGHT_FIELDS.forEach(({ key, id }) => {
    const input = document.getElementById(id);
    weights[key] = normalizeSportWeightInput(input ? input.value : moderationSettings.sports_score_weights?.[key], moderationSettings.sports_score_weights?.[key] ?? 1);
  });
  const terms = {};
  SPORT_TERM_FIELDS.forEach(({ key, id }) => {
    const input = document.getElementById(id);
    terms[key] = serializeTermListInput(input ? input.value : moderationSettings.sports_terms?.[key]);
  });

  try {
    const res = await apiFetch(`${API_URL}/moderation-settings`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        sports_scoring_enabled: enabled,
        sports_score_threshold: threshold,
        sports_auto_hide_enabled: autoHide,
        sports_score_weights: weights,
        sports_terms: terms
      })
    });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Fehler beim Speichern');
    }
    moderationSettings = await res.json();
    applyModerationSettingsUI();
    if (!silent) {
      showSuccess('✅ Sport-Scoring gespeichert');
    }
    return true;
  } catch (err) {
    if (!silent) {
      showError('❌ ' + err.message);
    }
    return false;
  }
}

function normalizeSimilarityTextThresholdInput(value) {
  const parsed = parseFloat(value);
  if (Number.isNaN(parsed)) {
    return 0.85;
  }
  return Math.min(0.99, Math.max(0.5, parsed));
}

function normalizeSimilarityImageThresholdInput(value) {
  const parsed = parseInt(value, 10);
  if (Number.isNaN(parsed)) {
    return 6;
  }
  return Math.min(64, Math.max(0, parsed));
}

function applySimilaritySettingsUI() {
  const textInput = document.getElementById('similarityTextThreshold');
  const imageInput = document.getElementById('similarityImageThreshold');
  if (textInput) {
    textInput.value = similaritySettings.text_threshold ?? 0.85;
  }
  if (imageInput) {
    imageInput.value = similaritySettings.image_distance_threshold ?? 6;
  }
}

async function loadSimilaritySettings() {
  const res = await apiFetch(`${API_URL}/similarity-settings`);
  if (!res.ok) throw new Error('Konnte Ähnlichkeits-Einstellungen nicht laden');
  const data = await res.json();
  similaritySettings = {
    text_threshold: normalizeSimilarityTextThresholdInput(data.text_threshold),
    image_distance_threshold: normalizeSimilarityImageThresholdInput(data.image_distance_threshold)
  };
  applySimilaritySettingsUI();
}

async function saveSimilaritySettings(event, { silent = false } = {}) {
  if (event && typeof event.preventDefault === 'function') {
    event.preventDefault();
  }
  const textInput = document.getElementById('similarityTextThreshold');
  const imageInput = document.getElementById('similarityImageThreshold');
  const textThreshold = textInput
    ? normalizeSimilarityTextThresholdInput(textInput.value)
    : similaritySettings.text_threshold;
  const imageThreshold = imageInput
    ? normalizeSimilarityImageThresholdInput(imageInput.value)
    : similaritySettings.image_distance_threshold;

  try {
    const res = await apiFetch(`${API_URL}/similarity-settings`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        text_threshold: textThreshold,
        image_distance_threshold: imageThreshold
      })
    });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Fehler beim Speichern');
    }
    similaritySettings = await res.json();
    applySimilaritySettingsUI();
    if (!silent) {
      showSuccess('✅ Ähnlichkeitsregeln gespeichert');
    }
    return true;
  } catch (err) {
    if (!silent) {
      showError('❌ ' + err.message);
    }
    return false;
  }
}

function shorten(text, maxLength = 80) {
  if (typeof text !== 'string') {
    return '';
  }
  if (text.length <= maxLength) {
    return text;
  }
  return `${text.slice(0, maxLength - 3)}...`;
}

function escapeHtmlAttr(text) {
  return escapeHtml(text || '').replace(/"/g, '&quot;');
}

function formatTimeLabel(iso) {
  if (!iso) return '';
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return '';
  return date.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' });
}

function formatRelativePast(iso) {
  if (!iso) return '';
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return '';
  const diffMs = Date.now() - date.getTime();
  if (diffMs < 0) return 'gerade eben';
  const diffMinutes = Math.round(diffMs / 60000);
  if (diffMinutes <= 1) return 'gerade eben';
  if (diffMinutes < 60) return `vor ${diffMinutes} Min`;
  const diffHours = Math.round(diffMinutes / 60);
  if (diffHours < 24) return `vor ${diffHours} Std`;
  const diffDays = Math.round(diffHours / 24);
  if (diffDays === 1) return 'gestern';
  if (diffDays < 7) return `vor ${diffDays} Tagen`;
  return date.toLocaleDateString('de-DE');
}

function formatRelativeFuture(iso) {
  if (!iso) return '';
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return '';
  const diffMs = date.getTime() - Date.now();
  if (diffMs <= 0) return 'gleich';
  const diffMinutes = Math.round(diffMs / 60000);
  if (diffMinutes < 1) return 'gleich';
  if (diffMinutes < 60) return `in ${diffMinutes} Min`;
  const diffHours = Math.round(diffMinutes / 60);
  if (diffHours < 24) return `in ${diffHours} Std`;
  return date.toLocaleString('de-DE', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });
}

function buildCredentialBadges(credential) {
  const badges = [];
  if (!credential.is_active) {
    badges.push({
      label: 'Deaktiviert',
      className: 'status-badge--muted',
      title: 'Dieser Login ist derzeit deaktiviert'
    });
  } else if (credential.auto_disabled) {
    const untilText = credential.auto_disabled_until ? formatRelativeFuture(credential.auto_disabled_until) : 'läuft';
    const untilTime = credential.auto_disabled_until ? formatTimeLabel(credential.auto_disabled_until) : '';
    const reason = credential.auto_disabled_reason ? credential.auto_disabled_reason.replace(/^AUTO:/, '').trim() : 'Automatisch deaktiviert';
    badges.push({
      label: `Cooldown ${untilText}${untilTime ? ` (${untilTime})` : ''}`.trim(),
      className: 'status-badge--warning',
      title: reason || 'Automatisch deaktiviert'
    });
  } else {
    badges.push({
      label: 'Aktiv',
      className: 'status-badge--success',
      title: 'Login ist aktiv'
    });
  }

  if (credential.last_error_message) {
    badges.push({
      label: `Fehler ${formatRelativePast(credential.last_error_at)}`.trim(),
      className: 'status-badge--danger',
      title: credential.last_error_message
    });
  }

  if (credential.usage_24h_count) {
    const resetHint = credential.usage_24h_reset_at ? `Reset ${formatRelativeFuture(credential.usage_24h_reset_at)}` : '24h Nutzung';
    badges.push({
      label: `24h: ${credential.usage_24h_count}`,
      className: 'status-badge--info',
      title: resetHint
    });
  }

  if (credential.last_rate_limit_remaining) {
    badges.push({
      label: `Limit: ${credential.last_rate_limit_remaining}`,
      className: 'status-badge--neutral',
      title: 'Letzter „rate limit remaining“-Wert'
    });
  }

  return badges;
}

function buildCredentialMetaLines(credential) {
  const lines = [];
  if (credential.last_success_at) {
    lines.push(`Zuletzt erfolgreich: ${formatRelativePast(credential.last_success_at)}`);
  }
  if (!credential.last_success_at && credential.last_used_at) {
    lines.push(`Zuletzt genutzt: ${formatRelativePast(credential.last_used_at)}`);
  }
  if (credential.rate_limit_reset_at && !credential.auto_disabled) {
    lines.push(`Limit-Reset ${formatRelativeFuture(credential.rate_limit_reset_at)}`);
  }
  if (credential.latest_event && credential.latest_event.type) {
    const typeLabel = credential.latest_event.type.replace(/_/g, ' ');
    const eventTime = credential.latest_event.created_at ? formatRelativePast(credential.latest_event.created_at) : '';
    const message = credential.latest_event.message ? shorten(credential.latest_event.message, 90) : '';
    const parts = [`Letztes Event (${typeLabel})`];
    if (eventTime) parts.push(eventTime);
    if (message) parts.push(`– ${message}`);
    lines.push(parts.join(' '));
  }
  return lines;
}

function renderCredentials() {
  const list = document.getElementById('credentialsList');
  if (!credentials.length) {
    list.innerHTML = '<p class="empty-state">Noch keine Anmeldedaten gespeichert</p>';
    return;
  }
  list.innerHTML = credentials.map((c, index) => {
    const providerName = escapeHtml(PROVIDER_INFO[c.provider]?.name || c.provider);
    const modelLabel = c.model ? ` · ${escapeHtml(c.model)}` : '';
    const endpointLabel = c.base_url ? ` · ${escapeHtml(c.base_url)}` : '';
    const badges = buildCredentialBadges(c);
    const badgesHtml = badges.length
      ? `<div class="credential-item__status">${badges.map(badge => `<span class="credential-status ${badge.className}"${badge.title ? ` title="${escapeHtmlAttr(badge.title)}"` : ''}>${escapeHtml(badge.label)}</span>`).join('')}</div>`
      : '';
    const metaLines = buildCredentialMetaLines(c);
    const metaHtml = metaLines.length
      ? `<div class="credential-item__meta">${metaLines.map(line => `<div>${escapeHtml(line)}</div>`).join('')}</div>`
      : '';

    return `
    <div class="credential-item" draggable="true" data-credential-id="${c.id}" data-index="${index}">
      <div class="credential-item__drag-handle" title="Ziehen zum Sortieren">⋮⋮</div>
      <div class="credential-item__info">
        <label class="form-label" style="display: flex; align-items: center; gap: 8px; margin: 0;">
          <input type="checkbox" class="form-checkbox"
            ${c.is_active ? 'checked' : ''}
            onchange="toggleCredentialActive(${c.id}, this.checked)">
          <div>
            <div class="credential-item__name">${escapeHtml(c.name)}</div>
            <div class="credential-item__provider">${providerName}${modelLabel}${endpointLabel}</div>
            ${badgesHtml}
            ${metaHtml}
          </div>
        </label>
      </div>
      <div class="credential-item__actions">
        <button onclick="editCredential(${c.id})" class="btn-icon" title="Bearbeiten">✏️</button>
        <button onclick="deleteCredential(${c.id})" class="btn-icon" title="Löschen">🗑️</button>
      </div>
    </div>
  `;
  }).join('');

  // Add drag and drop event listeners
  setupDragAndDrop();
}

function updateActiveCredentialSelect() {
  const select = document.getElementById('activeCredential');
  select.innerHTML = '<option value="">-- Bitte wählen --</option>' + 
    credentials.map(c => `<option value="${c.id}">${escapeHtml(c.name)} (${PROVIDER_INFO[c.provider]?.name})</option>`).join('');
  if (currentSettings?.active_credential_id) {
    select.value = currentSettings.active_credential_id;
  }
}

function updateModelOptions(provider) {
  const modelInput = document.getElementById('credentialModel');
  const modelList = document.getElementById('credentialModelOptions');
  const apiKeyInput = document.getElementById('credentialApiKey');
  const baseUrlGroup = document.getElementById('credentialBaseUrlGroup');
  const baseUrlHelp = document.getElementById('credentialBaseUrlHelp');
  const baseUrlInput = document.getElementById('credentialBaseUrl');
  const info = PROVIDER_INFO[provider];

  const models = PROVIDER_MODELS[provider] || [];
  if (modelList) {
    modelList.innerHTML = models.map(m => `<option value="${m.value}">${m.label}</option>`).join('');
  }

  if (modelInput) {
    const firstSuggestion = models.find(m => m.value)?.value;
    modelInput.placeholder = firstSuggestion
      ? `z.B. ${firstSuggestion}`
      : 'Modell-ID (z.B. llama3.1)';
  }

  const help = document.getElementById('credentialApiKeyHelp');
  if (help) {
    if (info) {
      const parts = [];
      if (info.apiKeyHelp) {
        parts.push(info.apiKeyHelp);
      }
      if (info.apiKeyLink) {
        parts.push(`<a href="${info.apiKeyLink}" target="_blank">API-Schlüssel erstellen</a>`);
      }
      help.innerHTML = parts.join(' ');
    } else {
      help.textContent = '';
    }
  }

  if (apiKeyInput) {
    if (provider === 'openai') {
      apiKeyInput.placeholder = 'sk-... oder leer für lokale Server';
    } else {
      apiKeyInput.placeholder = 'API-Schlüssel';
    }
  }

  if (baseUrlGroup && baseUrlHelp) {
    if (provider === 'openai') {
      baseUrlGroup.style.display = 'block';
      baseUrlHelp.textContent = 'Leer lassen für die offizielle OpenAI-API. Für lokale OpenAI/Ollama-Server gib die Basis-URL an, z.B. http://localhost:11434/v1';
      if (baseUrlInput) {
        baseUrlInput.placeholder = 'https://api.openai.com/v1 oder http://localhost:11434/v1';
      }
    } else {
      baseUrlGroup.style.display = 'none';
      baseUrlHelp.textContent = '';
      if (baseUrlInput) {
        baseUrlInput.placeholder = '';
      }
    }
  }

  const modelHelp = document.getElementById('credentialModelHelp');
  if (modelHelp) {
    modelHelp.textContent = 'Trage die Modell-ID ein. Du kannst einen Vorschlag auswählen oder einen eigenen Wert eingeben.';
  }
}

function openCredentialModal(credential = null) {
  const modal = document.getElementById('credentialModal');
  const form = document.getElementById('credentialForm');
  const apiKeyInput = document.getElementById('credentialApiKey');
  const baseUrlInput = document.getElementById('credentialBaseUrl');
  
  if (credential) {
    document.getElementById('credentialModalTitle').textContent = 'Anmeldedaten bearbeiten';
    document.getElementById('credentialId').value = credential.id;
    document.getElementById('credentialName').value = credential.name;
    document.getElementById('credentialProvider').value = credential.provider;
    updateModelOptions(credential.provider);
    document.getElementById('credentialModel').value = credential.model || '';
    if (baseUrlInput) {
      baseUrlInput.value = credential.base_url || '';
    }
    if (apiKeyInput) {
      apiKeyInput.value = '';
      apiKeyInput.placeholder = credential.provider === 'openai'
        ? 'Leer lassen, um den bestehenden Schlüssel zu behalten'
        : 'Leer lassen, um den bestehenden Schlüssel zu behalten';
    }
  } else {
    document.getElementById('credentialModalTitle').textContent = 'Anmeldedaten hinzufügen';
    form.reset();
    updateModelOptions('gemini');
    document.getElementById('credentialId').value = '';
    if (apiKeyInput) {
      apiKeyInput.value = '';
      apiKeyInput.placeholder = 'API-Schlüssel';
    }
    if (baseUrlInput) {
      baseUrlInput.value = '';
    }
  }
  
  modal.removeAttribute('hidden');
}

function closeCredentialModal() {
  document.getElementById('credentialModal').setAttribute('hidden', '');
}

async function saveCredential(e) {
  e.preventDefault();

  try {
    const id = document.getElementById('credentialId').value;
    const name = document.getElementById('credentialName').value.trim();
    const provider = document.getElementById('credentialProvider').value;
    const apiKey = document.getElementById('credentialApiKey').value.trim();
    const model = document.getElementById('credentialModel').value.trim();
    const baseUrlRaw = document.getElementById('credentialBaseUrl')?.value.trim() || '';

    if (!name) {
      throw new Error('Bitte einen Namen angeben');
    }

    const data = {
      name,
      provider,
      model: model || null,
      base_url: provider === 'openai' ? baseUrlRaw : ''
    };

    if (!id) {
      if (!apiKey && !(provider === 'openai' && baseUrlRaw)) {
        throw new Error('API-Schlüssel ist erforderlich (oder Basis-URL für lokale OpenAI-kompatible Server angeben)');
      }
      data.api_key = apiKey;
    } else if (apiKey) {
      data.api_key = apiKey;
    }

    const url = id ? `${API_URL}/ai-credentials/${id}` : `${API_URL}/ai-credentials`;
    const method = id ? 'PUT' : 'POST';

    const res = await apiFetch(url, {
      method,
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify(data)
    });

    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Fehler beim Speichern der Anmeldedaten');
    }

    await loadCredentials();
    closeCredentialModal();
    showSuccess('✅ Anmeldedaten erfolgreich gespeichert');
  } catch (err) {
    showError('❌ ' + err.message);
  }
}

async function editCredential(id) {
  const cred = credentials.find(c => c.id === id);
  if (!cred) {
    showError('Anmeldedaten nicht gefunden');
    return;
  }

  openCredentialModal(cred);
}

async function toggleCredentialActive(id, isActive) {
  try {
    const res = await apiFetch(`${API_URL}/ai-credentials/${id}`, {
      method: 'PATCH',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({ is_active: isActive ? 1 : 0 })
    });

    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Fehler beim Aktualisieren');
    }

    await loadCredentials();
    showSuccess(`✅ Login ${isActive ? 'aktiviert' : 'deaktiviert'}`);
  } catch (err) {
    showError('❌ ' + err.message);
    await loadCredentials(); // Reload to reset checkbox
  }
}

async function deleteCredential(id) {
  if (!confirm('Wirklich löschen?')) return;

  const res = await apiFetch(`${API_URL}/ai-credentials/${id}`, {method: 'DELETE'});
  if (!res.ok) {
    const err = await res.json();
    throw new Error(err.error || 'Failed to delete');
  }

  await loadCredentials();
  showSuccess('Anmeldedaten gelöscht');
}

// Make functions globally accessible for inline handlers
window.toggleCredentialActive = toggleCredentialActive;
window.editCredential = editCredential;
window.deleteCredential = deleteCredential;

// ============================================================================
// DRAG AND DROP
// ============================================================================

let draggedElement = null;

function setupDragAndDrop() {
  const items = document.querySelectorAll('.credential-item');

  items.forEach(item => {
    item.addEventListener('dragstart', handleDragStart);
    item.addEventListener('dragover', handleDragOver);
    item.addEventListener('drop', handleDrop);
    item.addEventListener('dragend', handleDragEnd);
    item.addEventListener('dragenter', handleDragEnter);
    item.addEventListener('dragleave', handleDragLeave);
  });
}

function handleDragStart(e) {
  draggedElement = this;
  this.style.opacity = '0.4';
  e.dataTransfer.effectAllowed = 'move';
  e.dataTransfer.setData('text/html', this.innerHTML);
}

function handleDragOver(e) {
  if (e.preventDefault) {
    e.preventDefault();
  }
  e.dataTransfer.dropEffect = 'move';
  return false;
}

function handleDragEnter(e) {
  if (this !== draggedElement) {
    this.classList.add('drag-over');
  }
}

function handleDragLeave(e) {
  this.classList.remove('drag-over');
}

function handleDrop(e) {
  if (e.stopPropagation) {
    e.stopPropagation();
  }

  if (draggedElement !== this) {
    // Get the container
    const container = this.parentNode;
    const allItems = [...container.querySelectorAll('.credential-item')];

    // Get indices
    const draggedIndex = allItems.indexOf(draggedElement);
    const targetIndex = allItems.indexOf(this);

    // Reorder in DOM
    if (draggedIndex < targetIndex) {
      this.parentNode.insertBefore(draggedElement, this.nextSibling);
    } else {
      this.parentNode.insertBefore(draggedElement, this);
    }

    // Update backend
    saveCredentialOrder();
  }

  this.classList.remove('drag-over');
  return false;
}

function handleDragEnd(e) {
  this.style.opacity = '1';

  // Remove all drag-over classes
  document.querySelectorAll('.credential-item').forEach(item => {
    item.classList.remove('drag-over');
  });
}

async function saveCredentialOrder() {
  try {
    const items = document.querySelectorAll('.credential-item');
    const order = Array.from(items).map(item => parseInt(item.dataset.credentialId));

    const res = await apiFetch(`${API_URL}/ai-credentials/reorder`, {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({ order })
    });

    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Fehler beim Speichern der Reihenfolge');
    }

    credentials = await res.json();
    showSuccess('✅ Reihenfolge gespeichert');
  } catch (err) {
    showError('❌ ' + err.message);
    await loadCredentials(); // Reload to restore original order
  }
}

async function saveSettings(e, { silent = false } = {}) {
  if (e && typeof e.preventDefault === 'function') {
    e.preventDefault();
  }

  try {
    const data = {
      enabled: document.getElementById('aiEnabled').checked,
      active_credential_id: parseInt(document.getElementById('activeCredential').value) || null,
      prompt_prefix: document.getElementById('aiPromptPrefix').value
    };

    const res = await apiFetch(`${API_URL}/ai-settings`, {
      method: 'PUT',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify(data)
    });

    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Fehler beim Speichern der Einstellungen');
    }

    currentSettings = await res.json();
    if (!silent) {
      showSuccess('✅ Einstellungen erfolgreich gespeichert');
    }
    return true;
  } catch (err) {
    if (!silent) {
      showError('❌ ' + err.message);
    }
    return false;
  }
}

async function testComment() {
  const modal = document.getElementById('testModal');
  modal.removeAttribute('hidden');
  document.getElementById('testResult').style.display = 'none';
  document.getElementById('testError').style.display = 'none';

  // Load last test data from localStorage
  const lastTest = localStorage.getItem('lastTestComment');
  if (lastTest) {
    try {
      const data = JSON.parse(lastTest);
      document.getElementById('testPostText').value = data.postText || '';
      document.getElementById('testProfileNumber').value = data.profileNumber || '1';
    } catch (e) {
      console.error('Failed to load last test comment:', e);
    }
  }
}

async function generateTest() {
  const text = document.getElementById('testPostText').value;
  const profileNumber = parseInt(document.getElementById('testProfileNumber').value);

  if (!text) return;

  document.getElementById('testLoading').style.display = 'block';
  document.getElementById('testResult').style.display = 'none';
  document.getElementById('testError').style.display = 'none';

  try {
    const res = await apiFetch(`${API_URL}/ai/generate-comment`, {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({postText: text, profileNumber})
    });

    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Failed');
    }

    const data = await res.json();
    document.getElementById('testComment').textContent = data.comment;
    document.getElementById('testResult').style.display = 'block';

    // Save test data to localStorage
    localStorage.setItem('lastTestComment', JSON.stringify({
      postText: text,
      profileNumber: profileNumber,
      comment: data.comment,
      timestamp: new Date().toISOString()
    }));
  } catch (err) {
    document.getElementById('testError').textContent = err.message;
    document.getElementById('testError').style.display = 'block';
  } finally {
    document.getElementById('testLoading').style.display = 'none';
  }
}

function escapeHtml(text) {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
}

async function saveAllSettings(event) {
  if (event && typeof event.preventDefault === 'function') {
    event.preventDefault();
  }

  const saveBtn = document.getElementById('saveAllFloatingBtn');
  const labelEl = saveBtn ? saveBtn.querySelector('.label') : null;
  const spinnerEl = saveBtn ? saveBtn.querySelector('.spinner') : null;
  const defaultLabel = saveBtn
    ? (saveBtn.dataset.defaultLabel || (labelEl && labelEl.textContent.trim()) || 'Einstellungen speichern')
    : 'Einstellungen speichern';
  if (saveBtn) {
    saveBtn.dataset.defaultLabel = defaultLabel;
  }
  if (saveBtn) {
    saveBtn.disabled = true;
    saveBtn.classList.add('is-saving');
    if (labelEl) {
      labelEl.textContent = 'Speichern...';
    } else {
      saveBtn.textContent = 'Speichern...';
    }
    if (spinnerEl) {
      spinnerEl.style.display = 'inline-block';
      spinnerEl.classList.add('spin');
    }
  }

  const results = await Promise.all([
    saveSettings(null, { silent: true }),
    saveHiddenSettings(null, { silent: true }),
    saveModerationSettings(null, { silent: true }),
    saveSimilaritySettings(null, { silent: true }),
    saveAllFriends({ silent: true })
  ]);

  const allOk = results.every(Boolean);
  if (allOk) {
    showSuccess('Gespeichert');
  } else {
    showError('❌ Nicht alle Einstellungen konnten gespeichert werden');
  }

  if (saveBtn) {
    saveBtn.disabled = false;
    saveBtn.classList.remove('is-saving');
    const label = saveBtn.querySelector('.label');
    const spinner = saveBtn.querySelector('.spinner');
    if (label) {
      label.textContent = saveBtn.dataset.defaultLabel || 'Einstellungen speichern';
    } else {
      saveBtn.textContent = 'Einstellungen speichern';
    }
    if (spinner) {
      spinner.style.display = 'none';
      spinner.classList.remove('spin');
    }
  }
}

// ============================================================================
// PROFILE FRIENDS
// ============================================================================

let profileFriends = {};

async function loadProfileFriends() {
  const list = document.getElementById('profileFriendsList');
  list.innerHTML = '';

  for (let i = 1; i <= 5; i++) {
    const res = await apiFetch(`${API_URL}/profile-friends/${i}`);
    const data = await res.json();
    profileFriends[i] = data.friend_names || '';

    const div = document.createElement('div');
    div.className = 'form-group';
    div.innerHTML = `
      <label for="friends${i}" class="form-label">Profil ${i}</label>
      <input type="text" id="friends${i}" class="form-input"
        placeholder="z.B. Anna, Max, Lisa"
        value="${escapeHtml(profileFriends[i])}">
      <p class="form-help">Kommagetrennte Liste von Freundesnamen für Profil ${i}</p>
    `;
    list.appendChild(div);

    document.getElementById(`friends${i}`).addEventListener('blur', async (e) => {
      const newValue = e.target.value.trim();
      if (newValue !== profileFriends[i]) {
        await saveFriends(i, newValue);
      }
    });
  }
}

async function saveFriends(profileNumber, friendNames, { silent = false } = {}) {
  try {
    const res = await apiFetch(`${API_URL}/profile-friends/${profileNumber}`, {
      method: 'PUT',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({ friend_names: friendNames })
    });

    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'Fehler beim Speichern');
    }

    profileFriends[profileNumber] = friendNames;
    if (!silent) {
      showSuccess(`✅ Freunde für Profil ${profileNumber} gespeichert`);
    }
    return true;
  } catch (err) {
    if (!silent) {
      showError('❌ ' + err.message);
    }
    return false;
  }
}

async function saveAllFriends({ silent = false } = {}) {
  let success = true;
  for (let i = 1; i <= 5; i++) {
    const input = document.getElementById(`friends${i}`);
    if (!input) {
      continue;
    }
    const newValue = input.value.trim();
    if (newValue !== profileFriends[i]) {
      const result = await saveFriends(i, newValue, { silent });
      success = success && result;
    }
  }
  return success;
}

// Event listeners
document.getElementById('addCredentialBtn').addEventListener('click', () => openCredentialModal());
document.getElementById('credentialModalClose').addEventListener('click', closeCredentialModal);
document.getElementById('credentialCancelBtn').addEventListener('click', closeCredentialModal);
document.getElementById('credentialForm').addEventListener('submit', saveCredential);
document.getElementById('credentialProvider').addEventListener('change', e => updateModelOptions(e.target.value));
document.getElementById('aiSettingsForm').addEventListener('submit', (e) => {
  e.preventDefault();
  saveSettings(e);
});
document.getElementById('testBtn').addEventListener('click', testComment);
document.getElementById('testModalClose').addEventListener('click', () => document.getElementById('testModal').setAttribute('hidden', ''));
document.getElementById('generateTestComment').addEventListener('click', generateTest);
document.getElementById('purgeHiddenNowBtn').addEventListener('click', purgeHiddenNow);
document.getElementById('saveAllFloatingBtn').addEventListener('click', saveAllSettings);

const autoPurgeHiddenToggle = document.getElementById('autoPurgeHiddenToggle');
if (autoPurgeHiddenToggle) {
  autoPurgeHiddenToggle.addEventListener('change', () => {
    const retentionInput = document.getElementById('hiddenRetentionDays');
    if (retentionInput) {
      retentionInput.disabled = !autoPurgeHiddenToggle.checked;
    }
  });
}

const sportsScoringToggle = document.getElementById('sportsScoringEnabled');
const sportsScoreInput = document.getElementById('sportsScoreThreshold');
if (sportsScoringToggle && sportsScoreInput) {
  sportsScoringToggle.addEventListener('change', () => {
    sportsScoreInput.disabled = !sportsScoringToggle.checked;
    applyWeightInputs(sportsScoringToggle.checked);
    applyTermInputs(sportsScoringToggle.checked);
    const autoHideToggle = document.getElementById('sportsAutoHideEnabled');
    if (autoHideToggle) {
      autoHideToggle.disabled = !sportsScoringToggle.checked;
    }
  });
  sportsScoreInput.addEventListener('blur', () => {
    sportsScoreInput.value = normalizeSportsScoreThresholdInput(sportsScoreInput.value);
  });
  SPORT_WEIGHT_FIELDS.forEach(({ id }) => {
    const input = document.getElementById(id);
    if (input) {
      input.addEventListener('blur', () => {
        input.value = normalizeSportWeightInput(input.value);
      });
    }
  });
  SPORT_TERM_FIELDS.forEach(({ id }) => {
    const input = document.getElementById(id);
    if (input) {
      input.addEventListener('blur', () => {
        input.value = renderTermList(serializeTermListInput(input.value));
      });
    }
  });
  const moderationForm = document.getElementById('moderationSettingsForm');
  if (moderationForm) {
    moderationForm.addEventListener('submit', (e) => saveModerationSettings(e));
  }
}

const similarityForm = document.getElementById('similaritySettingsForm');
if (similarityForm) {
  const textInput = document.getElementById('similarityTextThreshold');
  const imageInput = document.getElementById('similarityImageThreshold');
  if (textInput) {
    textInput.addEventListener('blur', () => {
      textInput.value = normalizeSimilarityTextThresholdInput(textInput.value);
    });
  }
  if (imageInput) {
    imageInput.addEventListener('blur', () => {
      imageInput.value = normalizeSimilarityImageThresholdInput(imageInput.value);
    });
  }
  similarityForm.addEventListener('submit', (e) => saveSimilaritySettings(e));
}

// Initialize
Promise.all([
  loadCredentials(),
  loadSettings(),
  loadHiddenSettings(),
  loadModerationSettings(),
  loadSimilaritySettings(),
  loadProfileFriends()
]).catch(err => showError(err.message));
})();
