import { readSubscribers, writeSubscribers } from '../../utils/newsletter.js'
import fs from 'fs/promises'
import path from 'path'
import { assertRateLimit, getClientIp, registerRateLimitFailure, registerRateLimitSuccess } from '../../utils/rate-limit.js'

// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
// filename is always a hardcoded constant (e.g., 'newsletter-subscribers.json'), never user input
const getDataPath = (filename) => {
  const cwd = process.cwd()
  if (cwd.endsWith('.output')) {
    // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
    return path.join(cwd, '../server/data', filename)
  }
    // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
  return path.join(cwd, 'server/data', filename)
}

const NEWSLETTER_GROUPS_FILE = getDataPath('newsletter-groups.json')

async function readGroups() {
  try {
    const data = await fs.readFile(NEWSLETTER_GROUPS_FILE, 'utf-8')
    return JSON.parse(data)
  } catch (error) {
    if (error.code === 'ENOENT') {
      return []
    }
    throw error
  }
}

export default defineEventHandler(async (event) => {
  try {
    const body = await readBody(event)
    const { email, groupId } = body

    if (!email || !email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
      throw createError({
        statusCode: 400,
        statusMessage: 'Ungültige E-Mail-Adresse'
      })
    }

    const ip = getClientIp(event)
    const emailKey = String(email || '').trim().toLowerCase()
    assertRateLimit(event, {
      name: 'newsletter:unsubscribe:ip',
      keyParts: [ip],
      windowMs: 10 * 60 * 1000,
      maxAttempts: 30,
      lockoutMs: 15 * 60 * 1000
    })
    assertRateLimit(event, {
      name: 'newsletter:unsubscribe:email',
      keyParts: [emailKey],
      windowMs: 10 * 60 * 1000,
      maxAttempts: 8,
      lockoutMs: 30 * 60 * 1000
    })

    if (!groupId) {
      throw createError({
        statusCode: 400,
        statusMessage: 'Newsletter-Gruppe muss angegeben werden'
      })
    }

    // Prüfe ob Gruppe existiert
    const groups = await readGroups()
    const group = groups.find(g => g.id === groupId)
    
    if (!group) {
      throw createError({
        statusCode: 404,
        statusMessage: 'Newsletter-Gruppe nicht gefunden'
      })
    }

    if (group.type !== 'subscription') {
      throw createError({
        statusCode: 400,
        statusMessage: 'Diese Funktion ist nur für Abonnenten-Newsletter verfügbar'
      })
    }

    const subscribers = await readSubscribers()
    const emailLower = email.toLowerCase()
    
    const subscriber = subscribers.find(s => {
      const sEmail = (s.email || '').toLowerCase()
      return sEmail === emailLower
    })

    if (!subscriber) {
      // Nicht gefunden - aber trotzdem Erfolg zurückgeben (keine Information preisgeben)
      await registerRateLimitFailure(event, { name: 'newsletter:unsubscribe:ip', keyParts: [ip] })
      await registerRateLimitFailure(event, { name: 'newsletter:unsubscribe:email', keyParts: [emailKey] })
      return {
        success: true,
        message: 'Sie wurden erfolgreich vom Newsletter abgemeldet'
      }
    }

    // Stelle sicher, dass groupIds existiert
    if (!subscriber.groupIds || !Array.isArray(subscriber.groupIds)) {
      subscriber.groupIds = []
    }

    // Prüfe ob für diese Gruppe angemeldet
    if (!subscriber.groupIds.includes(groupId)) {
      // Nicht für diese Gruppe angemeldet - aber trotzdem Erfolg zurückgeben
      await registerRateLimitFailure(event, { name: 'newsletter:unsubscribe:ip', keyParts: [ip] })
      await registerRateLimitFailure(event, { name: 'newsletter:unsubscribe:email', keyParts: [emailKey] })
      return {
        success: true,
        message: 'Sie wurden erfolgreich vom Newsletter abgemeldet'
      }
    }

    // Entferne Gruppe aus groupIds
    const index = subscriber.groupIds.indexOf(groupId)
    subscriber.groupIds.splice(index, 1)

    // Wenn keine Gruppen mehr vorhanden, als abgemeldet markieren
    if (subscriber.groupIds.length === 0) {
      subscriber.unsubscribedAt = new Date().toISOString()
      subscriber.confirmed = false
    }

    await writeSubscribers(subscribers)

    registerRateLimitSuccess(event, { name: 'newsletter:unsubscribe:email', keyParts: [emailKey] })
    return {
      success: true,
      message: 'Sie wurden erfolgreich vom Newsletter abgemeldet'
    }
  } catch (error) {
    console.error('Fehler bei Newsletter-Abmeldung:', error)
    if (error.statusCode) {
      throw error
    }
    throw createError({
      statusCode: 500,
      statusMessage: 'Fehler bei der Newsletter-Abmeldung'
    })
  }
})

