import fs from 'fs/promises'
import path from 'path'
import { readSpielplanData, validateSeasonSlug } from '../../utils/spielplan-data.js'
import { info as loggerInfo, error as loggerError } from '../../utils/logger.js'

export default defineEventHandler(async (event) => {
  try {
    const query = getQuery(event)
    const team = query.team
    if (query.season && !validateSeasonSlug(query.season)) {
      loggerError('Ungueltiger Saison-Slug angefragt (PDF)', { season: query.season })
      throw createError({ statusCode: 400, statusMessage: 'Ungueltiger Saison-Slug' })
    }
    
    if (!team) {
      throw createError({
        statusCode: 400,
        statusMessage: 'Team-Parameter fehlt'
      })
    }
    
    const spielplan = await readSpielplanData({ season: query.season })
    if (!spielplan.data.length || !spielplan.headers.length) {
      throw createError({
        statusCode: 404,
        statusMessage: 'Spielplandaten nicht gefunden'
      })
    }

    const dataRows = spielplan.data
    
    // Filtere Daten basierend auf Team
    let filteredData = dataRows
    
    if (team !== 'all') {
      filteredData = dataRows.filter(row => {
        const heimMannschaft = (row.HeimMannschaft || '').toLowerCase()
        const gastMannschaft = (row.GastMannschaft || '').toLowerCase()
        const heimAltersklasse = (row.HeimMannschaftAltersklasse || '').toLowerCase()
        const gastAltersklasse = (row.GastMannschaftAltersklasse || '').toLowerCase()
        
        // Prüfe ob eine der Mannschaften Harheimer TC ist
        const isHarheimerHeim = heimMannschaft.includes('harheimer tc')
        const isHarheimerGast = gastMannschaft.includes('harheimer tc')
        
        if (!isHarheimerHeim && !isHarheimerGast) {
          return false // Kein Harheimer TC Spiel
        }
        
        // Mapping zwischen Team-Namen und CSV-Daten
        const mannschaftMapping = {
          'erwachsene': ['harheimer tc'], // Alle Erwachsenen-Mannschaften
          'nachwuchs': ['harheimer tc'], // Alle Jugend-Mannschaften
          'erwachsene_1': ['harheimer tc'], // Nur ohne römische Zahl
          'erwachsene_2': ['harheimer tc ii'],
          'erwachsene_3': ['harheimer tc iii'],
          'erwachsene_4': ['harheimer tc iv'],
          'erwachsene_5': ['harheimer tc v'],
          'jugendmannschaft': ['harheimer tc'] // Jugend hat keine römische Zahl
        }
        
        const csvVariants = mannschaftMapping[team] || []
        
        if (csvVariants.length === 0) {
          return false
        }
        
        // Prüfe Mannschafts-Zuordnung UND Altersklasse
        const mannschaftMatch = csvVariants.some(variant => {
          // Strikte Übereinstimmung: Prüfe exakte Mannschaftsnamen
          if (isHarheimerHeim) {
            // Für "harheimer tc" (Erwachsene 1): Nur wenn KEINE römische Zahl folgt
            if (variant === 'harheimer tc') {
              return heimMannschaft === 'harheimer tc' || 
                     heimMannschaft.startsWith('harheimer tc ') && 
                     !heimMannschaft.match(/harheimer tc\s+[ivx]+/i)
            }
            // Für andere Mannschaften: Exakte Übereinstimmung
            return heimMannschaft === variant || heimMannschaft.startsWith(variant + ' ')
          }
          if (isHarheimerGast) {
            // Für "harheimer tc" (Erwachsene 1): Nur wenn KEINE römische Zahl folgt
            if (variant === 'harheimer tc') {
              return gastMannschaft === 'harheimer tc' || 
                     gastMannschaft.startsWith('harheimer tc ') && 
                     !gastMannschaft.match(/harheimer tc\s+[ivx]+/i)
            }
            // Für andere Mannschaften: Exakte Übereinstimmung
            return gastMannschaft === variant || gastMannschaft.startsWith(variant + ' ')
          }
          return false
        })
        
        if (!mannschaftMatch) {
          return false
        }
        
        // Zusätzliche Altersklassen-Prüfung für spezifische Mannschaften
        if (team.startsWith('erwachsene')) {
          // Erwachsenen-Mannschaften: MUSS Erwachsene sein, DARF NICHT Jugend sein
          const isErwachsenenHeim = isHarheimerHeim && 
            heimAltersklasse.includes('erwachsene') && 
            !heimAltersklasse.includes('jugend')
          const isErwachsenenGast = isHarheimerGast && 
            gastAltersklasse.includes('erwachsene') && 
            !gastAltersklasse.includes('jugend')
          
          return isErwachsenenHeim || isErwachsenenGast
        } else if (team === 'jugendmannschaft' || team === 'nachwuchs') {
          // Jugend-Mannschaft: MUSS Jugend sein
          const isJugendHeim = isHarheimerHeim && 
            (heimAltersklasse.includes('jugend') || heimMannschaft.includes('jugend'))
          const isJugendGast = isHarheimerGast && 
            (gastAltersklasse.includes('jugend') || gastMannschaft.includes('jugend'))
          
          return isJugendHeim || isJugendGast
        }
        
        return true // Fallback für unbekannte Mannschaften
      })
    }
    
    // Filtere nach Wettbewerb (Standard: Punktrunde)
    const wettbewerb = query.wettbewerb || 'punktrunde'
    if (wettbewerb !== 'alle') {
      filteredData = filteredData.filter(row => {
        const runde = (row.Runde || '').toLowerCase()
        
        if (wettbewerb === 'punktrunde') {
          return runde === 'vr' || 
                 runde.includes('vorrunde') || 
                 runde === 'rr' || 
                 runde.includes('rückrunde') ||
                 runde.includes('verbandsrunde')
        } else if (wettbewerb === 'pokal') {
          return runde === 'pokal' || runde.includes('pokal')
        }
        
        return true
      })
    }
    
    // Sammle Halle-Informationen für die jeweilige Mannschaft
    const hallenMap = new Map()
    
    // Debug: Zeige verfügbare Spalten
    loggerInfo('Verfügbare Spalten in gefilterten Daten', { columns: Object.keys(filteredData[0] || {}) })
    
    filteredData.forEach((row, index) => {
      // Suche Halle-Spalten mit verschiedenen möglichen Namen
      const halleName = row.HalleName || row.halleName || row.Halle || row.halle || ''
      const halleStrasse = row.HalleStrasse || row.halleStrasse || row.HalleStrasse || row.halleStrasse || ''
      const hallePLZ = row.HallePLZ || row.hallePLZ || row.HallePLZ || row.hallePLZ || ''
      const halleOrt = row.HalleOrt || row.halleOrt || row.HalleOrt || row.halleOrt || ''
      const heimMannschaft = row.HeimMannschaft || ''
      
      // Debug: Zeige Halle-Daten für erste paar Zeilen
        if (index < 3) {
          loggerInfo('Spielplan-Zeile Halle-Daten', { index, halleName, halleStrasse, hallePLZ, halleOrt, heimMannschaft })
        }
      
      if (halleName && halleStrasse && hallePLZ && halleOrt) {
        const halleKey = `${halleName}|${halleStrasse}|${hallePLZ}|${halleOrt}`
        if (!hallenMap.has(halleKey)) {
          hallenMap.set(halleKey, {
            name: halleName,
            strasse: halleStrasse,
            plz: hallePLZ,
            ort: halleOrt,
            mannschaften: new Set()
          })
        }
        
        // Füge Heimmannschaft hinzu (unabhängig von Harheimer TC)
        hallenMap.get(halleKey).mannschaften.add(heimMannschaft)
      }
    })
    
    const hallenListe = Array.from(hallenMap.values())
    loggerInfo('Gefundene Hallen', { count: hallenListe.length, hallen: hallenListe })
    
    // Generiere LaTeX-Code für PDF
    const teamName = team.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())
    const currentDate = new Date().toLocaleDateString('de-DE')
    
    let latexContent = `
\\documentclass[9pt,a4paper]{article}
\\usepackage[utf8]{inputenc}
\\usepackage[ngerman]{babel}
\\usepackage{geometry}
\\usepackage{array}
\\usepackage{longtable}
\\usepackage{helvet}
\\renewcommand{\\familydefault}{\\sfdefault}

\\geometry{margin=2cm}

\\title{Spielplan ${teamName}}
\\author{Harheimer TC}
\\date{Saison 2025/26 - Stand: ${currentDate}}

% PDF-Metadaten für Sicherheit
\\usepackage[pdftex]{hyperref}
\\hypersetup{
  pdfauthor={Harheimer TC},
  pdftitle={Spielplan ${teamName} - Saison 2025/26},
  pdfsubject={Vereinsspielplan},
  pdfkeywords={Tischtennis, Spielplan, Harheimer TC, ${teamName}},
  pdfcreator={Harheimer TC CMS},
  pdfproducer={LaTeX mit pdflatex},
  pdfcreationdate={${new Date().toISOString()}},
  pdfmoddate={${new Date().toISOString()}},
  colorlinks=false,
  pdfborder={0 0 0}
}

\\begin{document}
\\maketitle

\\section*{Spielplan ${teamName}}
\\vspace{0.5cm}

${filteredData.length > 0 ? `
\\renewcommand{\\arraystretch}{1.3}
\\begin{longtable}{|p{1.8cm}|p{1.1cm}|p{6.5cm}|p{6.5cm}|}
\\hline
\\textbf{Datum} & \\textbf{Uhrzeit} & \\textbf{Heim} & \\textbf{Gast} \\\\
\\hline
\\endhead

${filteredData.map(row => {
  const termin = row.Termin || ''
  const datum = termin.includes(' ') ? termin.split(' ')[0] : termin
  const uhrzeit = termin.includes(' ') ? termin.split(' ')[1] : ''
  const heim = (row.HeimMannschaft || '').replace(/&/g, '\\&')
  const gast = (row.GastMannschaft || '').replace(/&/g, '\\&')
  const heimAltersklasse = (row.HeimMannschaftAltersklasse || '').toLowerCase()
  const gastAltersklasse = (row.GastMannschaftAltersklasse || '').toLowerCase()
  
  // Prüfe ob es Jugend-Mannschaften sind
  const isHeimJugend = heimAltersklasse.includes('jugend') || heim.toLowerCase().includes('jugend')
  const isGastJugend = gastAltersklasse.includes('jugend') || gast.toLowerCase().includes('jugend')
  
  // Füge "(J) " vor Jugendmannschaften hinzu (nur bei Gesamtspielplan)
  let heimFormatted = heim
  let gastFormatted = gast
  
  if (team === 'all') {
    if (isHeimJugend) {
      heimFormatted = `(J) ${heim}`
    }
    if (isGastJugend) {
      gastFormatted = `(J) ${gast}`
    }
  }
  
  const heimBold = heimFormatted.toLowerCase().includes('harheimer tc') ? `\\textbf{${heimFormatted}}` : heimFormatted
  const gastBold = gastFormatted.toLowerCase().includes('harheimer tc') ? `\\textbf{${gastFormatted}}` : gastFormatted
  
  return `${datum} & ${uhrzeit} & ${heimBold} & ${gastBold} \\\\ \\hline`
}).join('\n')}

\\end{longtable}
` : `
\\begin{center}
\\textit{Keine Spiele für ${teamName} gefunden.}
\\end{center}
`}

${hallenListe.length > 0 ? `
\\newpage
\\section*{Spielstätten}
\\vspace{0.5cm}

\\begin{longtable}{|p{5cm}|p{4cm}|p{8cm}|}
\\hline
\\textbf{Heimmannschaft} & \\textbf{Halle} & \\textbf{Adresse} \\\\
\\hline
\\endhead

${hallenListe.map(halle => {
  const halleName = halle.name.replace(/&/g, '\\&')
  const adresse = `${halle.strasse.replace(/&/g, '\\&')}, ${halle.plz} ${halle.ort.replace(/&/g, '\\&')}`
  const mannschaften = Array.from(halle.mannschaften).map(m => m.replace(/&/g, '\\&')).join(', ')
  return `${mannschaften} & ${halleName} & ${adresse} \\\\ \\hline`
}).join('\n')}

\\end{longtable}
` : ''}

\\vfill
\\begin{center}
\\small Generiert am ${currentDate} | Harheimer TC
\\end{center}

\\end{document}`

    // Schreibe LaTeX-Datei temporär
    const tempDir = path.join(process.cwd(), 'temp')
    try {
      await fs.mkdir(tempDir, { recursive: true })
    } catch (_error) {
      // Verzeichnis existiert bereits
    }
    
    // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
    const tempTexFile = path.join(tempDir, `spielplan_${team}_${Date.now()}.tex`)
    await fs.writeFile(tempTexFile, latexContent, 'utf-8')
    
    // Kompiliere LaTeX zu PDF
    const { exec } = await import('child_process')
    const { promisify } = await import('util')
    const execAsync = promisify(exec)
    
    try {
      const { stdout, stderr } = await execAsync(`pdflatex -interaction=nonstopmode -output-directory=${tempDir} "${tempTexFile}"`)
      
      // PDF-Datei lesen
      const pdfFile = tempTexFile.replace('.tex', '.pdf')
      const pdfBuffer = await fs.readFile(pdfFile)
      
      // Cleanup: Lösche temporäre Dateien
      setTimeout(async () => {
        try {
          await fs.unlink(tempTexFile)
          await fs.unlink(pdfFile)
          await fs.unlink(tempTexFile.replace('.tex', '.log'))
          await fs.unlink(tempTexFile.replace('.tex', '.aux'))
        } catch (_error) {
            loggerError('Fehler beim Löschen temporärer Dateien:', { error: _error })
        }
      }, 5000)
      
      // Setze PDF-Headers
      setHeader(event, 'Content-Type', 'application/pdf')
      setHeader(event, 'Content-Disposition', `attachment; filename="spielplan_${team}.pdf"`)
      setHeader(event, 'Content-Length', pdfBuffer.length.toString())
      
      // Füge Sicherheits-Header hinzu (global auch via server/middleware/security-headers.js)
      setHeader(event, 'X-Content-Type-Options', 'nosniff')
      setHeader(event, 'X-Frame-Options', 'SAMEORIGIN')
      setHeader(event, 'X-XSS-Protection', '0')
      setHeader(event, 'Cache-Control', 'no-cache, no-store, must-revalidate')
      setHeader(event, 'Pragma', 'no-cache')
      setHeader(event, 'Expires', '0')
      
      return pdfBuffer
      
    } catch (compileError) {
    loggerError('LaTeX-Kompilierung fehlgeschlagen:', { error: compileError })
      
      // Fallback: HTML-Response mit Fehlermeldung
      const errorHtml = `
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>PDF-Generierung fehlgeschlagen</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; background-color: #f5f5f5; }
        .container { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        .error { color: #d32f2f; font-size: 24px; margin-bottom: 20px; }
        .message { color: #333; font-size: 16px; line-height: 1.6; }
    </style>
</head>
<body>
    <div class="container">
        <div class="error">❌ PDF-Generierung fehlgeschlagen</div>
        <div class="message">
            Die PDF-Generierung für <strong>"${teamName}"</strong> ist fehlgeschlagen.<br>
            Bitte kontaktieren Sie den Administrator.
        </div>
    </div>
</body>
</html>`
      
      setHeader(event, 'Content-Type', 'text/html; charset=utf-8')
      return errorHtml
    }
    
  } catch (error) {
  loggerError('Fehler beim Generieren des Spielplans:', { error })
    
    if (error.statusCode) {
      throw error
    }
    
    throw createError({
      statusCode: 500,
      statusMessage: 'Fehler beim Generieren des Spielplans'
    })
  }
})
