import fs from 'fs/promises'
import path from 'path'
import { getUserFromToken, hasAnyRole } from '../../utils/auth.js'
import {
  createSpielplanJsonFromCsv,
  getCurrentSeasonSlug,
  getSpielplanSeasonJsonPathForCsvPath,
  inferSeasonSlugFromRows
} from '../../utils/spielplan-data.js'

export default defineEventHandler(async (event) => {
  try {
    let token = getCookie(event, 'auth_token')

    if (!token) {
      const authHeader = getHeader(event, 'authorization')
      if (authHeader && authHeader.startsWith('Bearer ')) {
        token = authHeader.substring(7).trim()
      }
    }

    const currentUser = token ? await getUserFromToken(token) : null

    if (!currentUser) {
      throw createError({
        statusCode: 401,
        statusMessage: 'Nicht authentifiziert'
      })
    }

    if (!hasAnyRole(currentUser, 'admin', 'vorstand')) {
      throw createError({
        statusCode: 403,
        statusMessage: 'Keine Berechtigung'
      })
    }

    const { filename, content } = await readBody(event)
    
    if (!filename || !content) {
      throw createError({
        statusCode: 400,
        statusMessage: 'Filename und Content sind erforderlich'
      })
    }
    
    // Sicherheitsprüfung: Nur bestimmte Dateien erlauben
    const allowedFiles = [
      'vereinsmeisterschaften.csv',
      'mannschaften.csv',
      'termine.csv',
      'spielplan.csv'
    ]
    const isSeasonalMannschaftenFile = /^mannschaften_\d{2}--\d{2}\.csv$/.test(String(filename))
    
    if (!allowedFiles.includes(filename) && !isSeasonalMannschaftenFile) {
      throw createError({
        statusCode: 403,
        statusMessage: 'Datei nicht erlaubt'
      })
    }
    
  // Neuer Ablauf (Option B): Schreibe CSVs ausschließlich in internes Datenverzeichnis,
  // damit keine direkten Schreibzugriffe auf `public/` stattfinden.
  // Später kann ein kontrollierter Deploy-/Sync-Prozess die Daten aus `server/data/public-data`
  // in die öffentlich ausgelieferte `public/`-Location übernehmen.
    const cwd = process.cwd()

    const writeFileAtomicAndVerify = async (targetPath, data) => {
      const dataDir = path.dirname(targetPath)
      await fs.mkdir(dataDir, { recursive: true })

      // Atomar schreiben: erst temp-Datei in *gleichem Verzeichnis*, dann rename.
      // So vermeiden wir:
      // - halb geschriebene Dateien (Reader sieht "Partial Transfer")
      // - Erfolgsmeldungen, obwohl die Datei effektiv kaputt ist
      const tmpPath = `${targetPath}.tmp-${process.pid}-${Date.now()}`
      try {
        await fs.writeFile(tmpPath, data, 'utf8')
        await fs.rename(tmpPath, targetPath)

        const expectedSize = Buffer.byteLength(data, 'utf8')
        const st = await fs.stat(targetPath)
        if (st.size !== expectedSize) {
          throw new Error(`Size mismatch after write. expected=${expectedSize} actual=${st.size}`)
        }

        // Wenn beim Build pre-komprimierte Assets erzeugt wurden, können für CSVs
        // noch alte `.gz`/`.br` Dateien liegen bleiben. Nach einem Update würden dann
        // ggf. inkonsistente Inhalte ausgeliefert (Browser meldet Partial Transfer).
        // Daher: nach erfolgreichem Schreiben alte Varianten entfernen.
        for (const ext of ['.gz', '.br']) {
          try { await fs.unlink(`${targetPath}${ext}`) } catch (_e3) { /* no-op */ }
        }
      } catch (e) {
        // best-effort cleanup
        try { await fs.unlink(tmpPath) } catch (_e2) { /* no-op */ }
        throw e
      }
    }

    // Ziel: internes Datenverzeichnis unter `server/data/public-data` (persistente, interne Quelle)
    const dataTargetsByFile = {
      'vereinsmeisterschaften.csv': [`${cwd}/server/data/public-data/vereinsmeisterschaften.csv`, `${cwd}/../server/data/public-data/vereinsmeisterschaften.csv`],
      'mannschaften.csv': [`${cwd}/server/data/public-data/mannschaften.csv`, `${cwd}/../server/data/public-data/mannschaften.csv`],
      'termine.csv': [`${cwd}/server/data/public-data/termine.csv`, `${cwd}/../server/data/public-data/termine.csv`],
      'spielplan.csv': [`${cwd}/server/data/public-data/spielplan.csv`, `${cwd}/../server/data/public-data/spielplan.csv`]
    }
    const internalPaths = isSeasonalMannschaftenFile
      ? [`${cwd}/server/data/public-data/${filename}`, `${cwd}/../server/data/public-data/${filename}`]
      : (dataTargetsByFile[filename] || [])

    const uniquePaths = [...new Set([...internalPaths])]
    const writeResults = []
    const writeErrors = []
    const jsonWriteResults = []

    for (const targetPath of uniquePaths) {
      try {
        await writeFileAtomicAndVerify(targetPath, content)
        writeResults.push(targetPath)
        if (filename === 'spielplan.csv') {
          const spielplanJson = createSpielplanJsonFromCsv(content)
          const seasonSlug = inferSeasonSlugFromRows(spielplanJson.data) || getCurrentSeasonSlug()
          const jsonContent = `${JSON.stringify(spielplanJson, null, 2)}\n`
          const jsonPath = getSpielplanSeasonJsonPathForCsvPath(targetPath, seasonSlug)
          await writeFileAtomicAndVerify(jsonPath, jsonContent)
          jsonWriteResults.push(jsonPath)
        }
      } catch (e) {
        writeErrors.push({ targetPath, error: e?.message || String(e) })
      }
    }

    if (writeResults.length === 0) {
      console.error('Konnte CSV-Datei in keinen Zielpfad schreiben:', writeErrors)
      throw createError({
        statusCode: 500,
        statusMessage: 'Fehler beim Speichern der Datei'
      })
    }
    
    return {
      success: true,
      message: 'Datei erfolgreich gespeichert',
      writtenTo: writeResults,
      jsonWrittenTo: jsonWriteResults
    }
    
  } catch (error) {
    console.error('Fehler beim Speichern der CSV-Datei:', error)
    if (error.statusCode) {
      throw error
    }
    throw createError({
      statusCode: 500,
      statusMessage: 'Fehler beim Speichern der Datei'
    })
  }
})
