/**
 * Recovery-Skript für gelöschte/neu erstellte Symbole
 *
 * Stellt sicher, dass alle Icons aus public/signaturen/ als IconAssets
 * in der DB vorhanden sind und für alle Tenants aktiviert sind.
 *
 * Unterstützt Dry-Run und Apply-Modus.
 *
 * Ausführung:
 *   Analyse:  node prisma/recover-symbols.js --dry-run
 *   Anwenden: node prisma/recover-symbols.js --apply
 */

const { PrismaClient } = require('@prisma/client')
const fs = require('fs')
const path = require('path')

const prisma = new PrismaClient()

const IS_DRY_RUN = process.argv.includes('--dry-run')
const IS_APPLY = process.argv.includes('--apply')
const IS_PROD = process.env.NODE_ENV === 'production'

// ─── Safety Guards ─────────────────────────────────────────────────────────

if (!IS_DRY_RUN && !IS_APPLY) {
  console.error('❌ Fehler: Bitte --dry-run oder --apply angeben')
  console.error('')
  console.error('  Analyse:  node prisma/recover-symbols.js --dry-run')
  console.error('  Anwenden: node prisma/recover-symbols.js --apply')
  process.exit(1)
}

if (IS_DRY_RUN && IS_APPLY) {
  console.error('❌ Fehler: --dry-run und --apply können nicht zusammen verwendet werden')
  process.exit(1)
}

if (IS_APPLY && IS_PROD) {
  console.log('⚠️  Production-Umgebung erkannt. Fortfahren in 3 Sekunden...')
  await new Promise(r => setTimeout(r, 3000))
}

console.log(IS_DRY_RUN ? '🔍 DRY-RUN MODUS' : '🔧 APPLY-MODUS')

// ─── Kategorie-Definitionen ────────────────────────────────────────────────

const catDefs = [
  { name: 'Feuer / Brand', description: 'Feuer, Brand, Brandschutz', sortOrder: 1,
    patterns: ['Feuer', 'Brand', 'Explosion', 'Entrauchung', 'Rauch', 'Kamin', 'Luefter', 'Sprinkler'] },
  { name: 'Wasser', description: 'Wasser, Hydranten, Leitungen', sortOrder: 2,
    patterns: ['Wasser', 'Hydrant', 'Reservoir', 'Druckleitung', 'Druckleistung', 'Transportleitung',
               'Schieber', 'Wasserloeschposten', 'Wasserversorgung', 'Wasserleitung', 'Ueberschwemmung',
               'Offener_Wasserverlauf', 'Moeglicher_Wasserbezugsort', 'Stehendes_Gewaesser',
               'Kleinloeschgeraet', 'Gefahr_durch_Loeschen_mit_Wasser'] },
  { name: 'Gefahren / Stoffe', description: 'Gefahrstoffe, Chemie, ABC', sortOrder: 3,
    patterns: ['Gefaehrlich', 'Chemie', 'Chemikalien', 'Biologisch', 'Radioaktiv', 'Gas', 'Elektri',
               'Elektrotableau', 'Achtung', 'Leitungsdaehte'] },
  { name: 'Rettung / Personen', description: 'Rettung, Sanität, Personen', sortOrder: 4,
    patterns: ['Rettung', 'Retten', 'Sanitaet', 'Patienten', 'Sammelplatz', 'Sammelstelle',
               'Totensammelstelle', 'Sprungretter', 'Helikopterlandeplatz'] },
  { name: 'Leitern / Geräte', description: 'Leitern, Fahrzeuge, Geräte', sortOrder: 5,
    patterns: ['Leiter', 'Anhaengeleiter', 'Strebenleiter', 'ADL', 'TLF', 'HRF', 'SWHP'] },
  { name: 'Gebäude / Schäden', description: 'Gebäude, Zerstörung, Schäden', sortOrder: 6,
    patterns: ['Beschaedigung', 'Teilzerstoerung', 'Totalzerstoerung', 'Decke_eingestuerzt',
               'Umfassungswaende', 'AnzahlGeschosse', 'Eingang', 'Treppen', 'Lift', 'Bruecke',
               'Rutschgebiet', 'Strasse', 'Bahnlin'] },
  { name: 'Einsatzführung', description: 'Führung, Organisation, Kommunikation', sortOrder: 7,
    patterns: ['Einsatzleiter', 'KP_Font', 'Offizier', 'Beobachtungsposten', 'Kontrollstelle',
               'Funk', 'Informationszentrum', 'Medienkontaktstelle', 'Fernsignaltableau',
               'Materialdepot', 'Schluesseldepot', 'Abschnitt', 'Absperrung'] },
  { name: 'Organisationen', description: 'Feuerwehr, Polizei, Armee, Zivilschutz', sortOrder: 8,
    patterns: ['Feuerwehr', 'Polizei', 'Armee', 'Zivilschutz', 'Chemiewehr', 'MS_de', 'Anmarsch'] },
  { name: 'Entwicklung / Taktik', description: 'Entwicklungsgrenzen, Ausbreitung', sortOrder: 9,
    patterns: ['Entwicklungsgrenze', 'Horizontale_Entwicklung', 'Vertikale_Entwicklung',
               'VertikaleEntwicklung', 'Unfall'] },
  { name: 'Verschiedenes', description: 'Weitere Signaturen', sortOrder: 10,
    patterns: ['Massstab', 'Nordrichtung', 'Windrichtung'] },
]

function findCategory(filename) {
  for (const def of catDefs) {
    for (const pattern of def.patterns) {
      if (filename.includes(pattern)) return def.name
    }
  }
  return 'Verschiedenes'
}

// ─── Main ──────────────────────────────────────────────────────────────────

async function recover() {
  console.log('\n🚨 SYMBOL RECOVERY')
  console.log('────────────────────────────────────────')

  const SVG_DIR = path.join(__dirname, '..', 'public', 'signaturen')
  if (!fs.existsSync(SVG_DIR)) {
    console.error('❌ SVG-Verzeichnis nicht gefunden:', SVG_DIR)
    process.exit(1)
  }

  const files = fs.readdirSync(SVG_DIR).filter(f => f.endsWith('.svg')).sort()
  console.log(`\n📁 ${files.length} SVG-Dateien in public/signaturen/ gefunden`)

  // ─── 1. Kategorien Upserten ───
  console.log('\n[1/4] Kategorien...')
  const catMap = {}
  for (const def of catDefs) {
    const catId = def.name.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase()
    if (IS_APPLY) {
      const cat = await prisma.iconCategory.upsert({
        where: { id: catId },
        update: { name: def.name, description: def.description, sortOrder: def.sortOrder, isGlobal: true },
        create: { id: catId, name: def.name, description: def.description, sortOrder: def.sortOrder, isGlobal: true, tenantId: null },
      })
      catMap[def.name] = cat.id
    } else {
      catMap[def.name] = catId
      console.log(`   📝 ${def.name} (ID: ${catId})`)
    }
  }
  if (IS_APPLY) console.log(`   ✅ ${catDefs.length} Kategorien upserted`)

  // ─── 2. IconAssets Upserten ───
  console.log('\n[2/4] IconAssets...')
  const iconMap = {} // fileKey -> { id, name }
  let created = 0
  let updated = 0

  for (const file of files) {
    let name = file.replace('.svg', '')
    name = name.replace(/_de$/i, '').replace(/_DE$/i, '').replace(/-de$/i, '')
    name = name.replace(/[_-]/g, ' ').replace(/\s+/g, ' ').trim()

    const fileKey = `signaturen/${file}` // WICHTIG: Gleiches Format wie Seed!
    const category = findCategory(file)
    const categoryId = catMap[category]

    if (IS_APPLY) {
      const existing = await prisma.iconAsset.findFirst({ where: { fileKey } })
      if (existing) {
        await prisma.iconAsset.update({
          where: { id: existing.id },
          data: { name, categoryId, mimeType: 'image/svg+xml', isSystem: true, isActive: true, width: 48, height: 48 },
        })
        iconMap[fileKey] = { id: existing.id, name }
        updated++
      } else {
        const icon = await prisma.iconAsset.create({
          data: { name, categoryId, fileKey, mimeType: 'image/svg+xml', isSystem: true, width: 48, height: 48 },
        })
        iconMap[fileKey] = { id: icon.id, name }
        created++
      }
    } else {
      // Dry-Run: Simuliere Lookup
      const existing = await prisma.iconAsset.findFirst({ where: { fileKey }, select: { id: true, name: true } })
      if (existing) {
        iconMap[fileKey] = { id: existing.id, name: existing.name }
        updated++
      } else {
        iconMap[fileKey] = { id: `(neu: ${fileKey})`, name }
        created++
      }
    }
  }
  console.log(`   ${IS_APPLY ? '✅' : '📝'} ${created} neu, ${updated} aktualisiert, ${files.length} total`)

  // ─── 3. TenantSymbols erstellen ───
  console.log('\n[3/4] TenantSymbols...')
  const tenants = await prisma.tenant.findMany({ select: { id: true, name: true } })
  let tsCreated = 0
  let tsExisting = 0

  for (const tenant of tenants) {
    let tenantNew = 0
    let tenantExist = 0

    for (const [fileKey, icon] of Object.entries(iconMap)) {
      if (IS_APPLY) {
        // Prüfe ob bereits existiert
        const existing = await prisma.tenantSymbol.findFirst({
          where: { tenantId: tenant.id, iconId: icon.id },
        })
        if (existing) {
          tenantExist++
          tsExisting++
        } else {
          await prisma.tenantSymbol.create({
            data: { tenantId: tenant.id, iconId: icon.id, isActive: true },
          })
          tenantNew++
          tsCreated++
        }
      } else {
        // Dry-Run: Prüfe Existenz
        const existing = await prisma.tenantSymbol.findFirst({
          where: { tenantId: tenant.id, iconId: icon.id },
          select: { id: true },
        })
        if (existing) {
          tenantExist++
          tsExisting++
        } else {
          tenantNew++
          tsCreated++
        }
      }
    }
    console.log(`   ${IS_APPLY ? '✅' : '📝'} ${tenant.name}: ${tenantNew} neu, ${tenantExist} bereits vorhanden`)
  }
  console.log(`   Gesamt: ${tsCreated} neu, ${tsExisting} bereits vorhanden`)

  // ─── 4. Feature-Analyse ───
  console.log('\n[4/4] Feature-Analyse (Zeichnungen)...')
  const features = await prisma.feature.findMany({
    where: { type: 'symbol' },
    select: { id: true, properties: true, projectId: true },
  })

  const validIconIds = new Set(Object.values(iconMap).map(i => i.id))
  let validRefs = 0
  let brokenRefs = 0

  for (const f of features) {
    const iconId = f.properties?.iconId
    if (!iconId) {
      validRefs++ // Keine Referenz = nicht kaputt
    } else if (validIconIds.has(iconId)) {
      validRefs++
    } else {
      brokenRefs++
    }
  }

  console.log(`   📊 ${features.length} symbol-Features gefunden`)
  console.log(`   ✅ ${validRefs} gültige/keine Referenzen`)
  console.log(`   ❌ ${brokenRefs} kaputte Referenzen (nicht reparierbar ohne Backup)`)

  if (brokenRefs > 0) {
    console.log('\n   ⚠️  HINWEIS: Kaputte Features können NICHT automatisch repariert werden.')
    console.log('      Die alten iconId-UUIDs sind verloren.')
    console.log('      Verwende: npm run repair:features:dry-run')
  }

  console.log('\n✅ RECOVERY ABgeschlossen')
  if (IS_DRY_RUN) {
    console.log('   Zum Anwenden: node prisma/recover-symbols.js --apply')
  }
}

recover()
  .then(async () => { await prisma.$disconnect() })
  .catch(async (e) => {
    console.error('❌ Fehler:', e)
    await prisma.$disconnect()
    process.exit(1)
  })
