const adminConfig = require('./adminConfig');
const requestLogStore = require('./requestLogStore');

const SIGNIFICANT_STATUS_CODES = new Set([408, 425, 429, 500, 502, 503, 504]);

function createMaintenanceError(message) {
  const error = new Error(message || 'Wartungsmodus aktiv');
  error.code = 'MAINTENANCE_MODE_ACTIVE';
  error.statusCode = 503;
  return error;
}

function getSnapshot() {
  const settings = adminConfig.readSettings();
  return {
    active: !!settings.maintenanceModeActive,
    autoEnabled: !!settings.maintenanceModeAutoEnabled,
    activatedAt: settings.maintenanceModeActivatedAt || null,
    reason: settings.maintenanceModeReason || '',
    errorThreshold: Number(settings.maintenanceModeErrorThreshold) || 8,
    errorWindowMinutes: Number(settings.maintenanceModeErrorWindowMinutes) || 10
  };
}

function isActive() {
  return getSnapshot().active;
}

function isSignificantOutboundApiError(entry) {
  if (entry?.direction !== 'outgoing' || entry?.target !== 'foodsharing.de') {
    return false;
  }
  const status = Number(entry?.status);
  if (Number.isFinite(status)) {
    return SIGNIFICANT_STATUS_CODES.has(status);
  }
  return Boolean(entry?.error);
}

function activate({ reason } = {}) {
  const snapshot = getSnapshot();
  if (snapshot.active) {
    return snapshot;
  }
  const next = adminConfig.writeSettings({
    maintenanceModeActive: true,
    maintenanceModeActivatedAt: new Date().toISOString(),
    maintenanceModeReason: reason || 'Automatisch aktiviert'
  });
  console.warn(`[MAINTENANCE] Wartungsmodus aktiviert: ${next.maintenanceModeReason || 'ohne Grundangabe'}`);
  return {
    active: !!next.maintenanceModeActive,
    autoEnabled: !!next.maintenanceModeAutoEnabled,
    activatedAt: next.maintenanceModeActivatedAt || null,
    reason: next.maintenanceModeReason || '',
    errorThreshold: Number(next.maintenanceModeErrorThreshold) || 8,
    errorWindowMinutes: Number(next.maintenanceModeErrorWindowMinutes) || 10
  };
}

function activateAutomatically({ reason } = {}) {
  const snapshot = activate({ reason });
  if (!snapshot.active) {
    return snapshot;
  }
  try {
    const notificationService = require('./notificationService');
    Promise.resolve(
      notificationService.sendAdminMaintenanceModeNotification({
        reason: snapshot.reason,
        activatedAt: snapshot.activatedAt,
        errorThreshold: snapshot.errorThreshold,
        errorWindowMinutes: snapshot.errorWindowMinutes
      })
    ).catch((error) => {
      console.error('[MAINTENANCE] Admin-Benachrichtigung konnte nicht versendet werden:', error.message);
    });
  } catch (error) {
    console.error('[MAINTENANCE] Notification-Service konnte nicht geladen werden:', error.message);
  }
  return snapshot;
}

function deactivate() {
  const next = adminConfig.writeSettings({
    maintenanceModeActive: false,
    maintenanceModeActivatedAt: null,
    maintenanceModeReason: ''
  });
  console.warn('[MAINTENANCE] Wartungsmodus deaktiviert.');
  return next;
}

function ensureInactive(message) {
  if (!isActive()) {
    return;
  }
  throw createMaintenanceError(message);
}

function recordOutboundFailure(entry) {
  if (!isSignificantOutboundApiError(entry)) {
    return getSnapshot();
  }
  const snapshot = getSnapshot();
  if (!snapshot.autoEnabled || snapshot.active) {
    return snapshot;
  }
  const cutoff = Date.now() - snapshot.errorWindowMinutes * 60 * 1000;
  const logs = requestLogStore.list();
  const recentFailures = logs.filter(
    (item) => Number(item?.timestamp) >= cutoff && isSignificantOutboundApiError(item)
  );
  if (recentFailures.length < snapshot.errorThreshold) {
    return snapshot;
  }
  const statusSummary = recentFailures
    .slice(0, 5)
    .map((item) => item.status || item.error || 'unbekannt')
    .join(', ');
  return activateAutomatically({
    reason: `${recentFailures.length} relevante Outbound-API-Fehler in ${snapshot.errorWindowMinutes} Minuten (z. B. ${statusSummary})`
  });
}

module.exports = {
  activate,
  activateAutomatically,
  createMaintenanceError,
  deactivate,
  ensureInactive,
  getSnapshot,
  isActive,
  recordOutboundFailure
};
