/**
 * TASKMATE - Knowledge Management Routes
 * ======================================
 * CRUD für Wissensmanagement: Kategorien, Einträge, Anhänge
 */

const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
const multer = require('multer');
const { getDb } = require('../database');
const logger = require('../utils/logger');
const { validators, stripHtml } = require('../middleware/validation');
const notificationService = require('../services/notificationService');

/**
 * Sanitize Notes - entfernt gefaehrliche Tags/Attribute, laesst Markdown durch
 */
function sanitizeNotes(text) {
  if (!text) return text;
  // Entferne script, iframe, object, embed, form, style Tags inkl. Inhalt
  let clean = text.replace(/<\s*(script|iframe|object|embed|form|style|link|meta|base)\b[^>]*>[\s\S]*?<\s*\/\s*\1\s*>/gi, '');
  // Entferne selbstschliessende gefaehrliche Tags
  clean = clean.replace(/<\s*(script|iframe|object|embed|form|style|link|meta|base)\b[^>]*\/?>/gi, '');
  // Entferne on*-Event-Attribute
  clean = clean.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, '');
  // Entferne javascript: URLs
  clean = clean.replace(/href\s*=\s*(?:"javascript:[^"]*"|'javascript:[^']*')/gi, 'href="#"');
  clean = clean.replace(/src\s*=\s*(?:"javascript:[^"]*"|'javascript:[^']*')/gi, 'src=""');
  return clean;
}

// Upload-Konfiguration für Knowledge-Anhänge
const UPLOAD_DIR = path.join(__dirname, '..', 'uploads', 'knowledge');

// Sicherstellen, dass das Upload-Verzeichnis existiert
if (!fs.existsSync(UPLOAD_DIR)) {
  fs.mkdirSync(UPLOAD_DIR, { recursive: true });
}

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, UPLOAD_DIR);
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    const ext = path.extname(file.originalname);
    cb(null, `knowledge-${uniqueSuffix}${ext}`);
  }
});

const upload = multer({
  storage,
  limits: {
    fileSize: 50 * 1024 * 1024 // 50MB max
  }
});

// =====================
// KATEGORIEN
// =====================

/**
 * GET /api/knowledge/categories
 * Alle Kategorien abrufen
 */
router.get('/categories', (req, res) => {
  try {
    const db = getDb();
    const categories = db.prepare(`
      SELECT kc.*,
        (SELECT COUNT(*) FROM knowledge_entries WHERE category_id = kc.id) as entry_count,
        u.display_name as creator_name
      FROM knowledge_categories kc
      LEFT JOIN users u ON kc.created_by = u.id
      ORDER BY kc.position, kc.created_at
    `).all();

    res.json(categories.map(c => ({
      id: c.id,
      name: c.name,
      description: c.description,
      color: c.color,
      icon: c.icon,
      position: c.position,
      entryCount: c.entry_count,
      createdBy: c.created_by,
      creatorName: c.creator_name,
      createdAt: c.created_at
    })));
  } catch (error) {
    logger.error('Fehler beim Abrufen der Knowledge-Kategorien:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * POST /api/knowledge/categories
 * Neue Kategorie erstellen
 */
router.post('/categories', (req, res) => {
  try {
    const { name, description, color, icon } = req.body;

    // Validierung
    const nameError = validators.required(name, 'Name') ||
      validators.maxLength(name, 50, 'Name');
    if (nameError) {
      return res.status(400).json({ error: nameError });
    }

    if (color) {
      const colorError = validators.hexColor(color, 'Farbe');
      if (colorError) {
        return res.status(400).json({ error: colorError });
      }
    }

    const db = getDb();

    // Duplikat-Prüfung
    const existing = db.prepare(
      'SELECT id FROM knowledge_categories WHERE LOWER(name) = LOWER(?)'
    ).get(name);

    if (existing) {
      return res.status(400).json({ error: 'Eine Kategorie mit diesem Namen existiert bereits' });
    }

    // Alle bestehenden Kategorien um 1 nach unten verschieben
    db.prepare(`
      UPDATE knowledge_categories 
      SET position = position + 1
    `).run();

    // Neue Kategorie an Position 0 (ganz oben) einfügen
    const result = db.prepare(`
      INSERT INTO knowledge_categories (name, description, color, icon, position, created_by)
      VALUES (?, ?, ?, ?, ?, ?)
    `).run(
      stripHtml(name),
      description ? stripHtml(description) : null,
      color || '#3B82F6',
      icon || null,
      0, // Neue Kategorien immer an Position 0 (oben)
      req.user.id
    );

    const category = db.prepare('SELECT * FROM knowledge_categories WHERE id = ?')
      .get(result.lastInsertRowid);

    logger.info(`Knowledge-Kategorie erstellt: ${name}`);

    res.status(201).json({
      id: category.id,
      name: category.name,
      description: category.description,
      color: category.color,
      icon: category.icon,
      position: category.position,
      entryCount: 0,
      createdBy: category.created_by,
      createdAt: category.created_at
    });
  } catch (error) {
    logger.error('Fehler beim Erstellen der Knowledge-Kategorie:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * PUT /api/knowledge/categories/:id
 * Kategorie aktualisieren
 */
router.put('/categories/:id', (req, res) => {
  try {
    const categoryId = req.params.id;
    const { name, description, color, icon } = req.body;

    const db = getDb();

    const existing = db.prepare('SELECT * FROM knowledge_categories WHERE id = ?').get(categoryId);
    if (!existing) {
      return res.status(404).json({ error: 'Kategorie nicht gefunden' });
    }

    // Validierung
    if (name) {
      const nameError = validators.maxLength(name, 50, 'Name');
      if (nameError) {
        return res.status(400).json({ error: nameError });
      }

      // Duplikat-Prüfung (ausser eigene)
      const duplicate = db.prepare(
        'SELECT id FROM knowledge_categories WHERE LOWER(name) = LOWER(?) AND id != ?'
      ).get(name, categoryId);

      if (duplicate) {
        return res.status(400).json({ error: 'Eine Kategorie mit diesem Namen existiert bereits' });
      }
    }

    if (color) {
      const colorError = validators.hexColor(color, 'Farbe');
      if (colorError) {
        return res.status(400).json({ error: colorError });
      }
    }

    db.prepare(`
      UPDATE knowledge_categories SET
        name = COALESCE(?, name),
        description = COALESCE(?, description),
        color = COALESCE(?, color),
        icon = COALESCE(?, icon)
      WHERE id = ?
    `).run(
      name ? stripHtml(name) : null,
      description !== undefined ? (description ? stripHtml(description) : '') : null,
      color || null,
      icon !== undefined ? icon : null,
      categoryId
    );

    const category = db.prepare('SELECT * FROM knowledge_categories WHERE id = ?').get(categoryId);

    logger.info(`Knowledge-Kategorie aktualisiert: ${category.name}`);

    res.json({
      id: category.id,
      name: category.name,
      description: category.description,
      color: category.color,
      icon: category.icon,
      position: category.position,
      createdBy: category.created_by,
      createdAt: category.created_at
    });
  } catch (error) {
    logger.error('Fehler beim Aktualisieren der Knowledge-Kategorie:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * PUT /api/knowledge/categories/:id/position
 * Kategorie-Position ändern
 */
router.put('/categories/:id/position', (req, res) => {
  try {
    const categoryId = req.params.id;
    const { newPosition } = req.body;

    const db = getDb();

    const category = db.prepare('SELECT * FROM knowledge_categories WHERE id = ?').get(categoryId);
    if (!category) {
      return res.status(404).json({ error: 'Kategorie nicht gefunden' });
    }

    const oldPosition = category.position;

    if (newPosition > oldPosition) {
      db.prepare(`
        UPDATE knowledge_categories SET position = position - 1
        WHERE position > ? AND position <= ?
      `).run(oldPosition, newPosition);
    } else if (newPosition < oldPosition) {
      db.prepare(`
        UPDATE knowledge_categories SET position = position + 1
        WHERE position >= ? AND position < ?
      `).run(newPosition, oldPosition);
    }

    db.prepare('UPDATE knowledge_categories SET position = ? WHERE id = ?').run(newPosition, categoryId);

    const categories = db.prepare(
      'SELECT * FROM knowledge_categories ORDER BY position'
    ).all();

    res.json({
      categories: categories.map(c => ({
        id: c.id,
        name: c.name,
        position: c.position
      }))
    });
  } catch (error) {
    logger.error('Fehler beim Verschieben der Knowledge-Kategorie:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * DELETE /api/knowledge/categories/:id
 * Kategorie löschen (inkl. aller Einträge und Anhänge)
 */
router.delete('/categories/:id', (req, res) => {
  try {
    const categoryId = req.params.id;
    const db = getDb();

    const category = db.prepare('SELECT * FROM knowledge_categories WHERE id = ?').get(categoryId);
    if (!category) {
      return res.status(404).json({ error: 'Kategorie nicht gefunden' });
    }

    // Anhänge von allen Einträgen dieser Kategorie löschen
    const entries = db.prepare('SELECT id FROM knowledge_entries WHERE category_id = ?').all(categoryId);
    for (const entry of entries) {
      const attachments = db.prepare('SELECT * FROM knowledge_attachments WHERE entry_id = ?').all(entry.id);
      for (const attachment of attachments) {
        const filePath = path.join(UPLOAD_DIR, attachment.filename);
        if (fs.existsSync(filePath)) {
          fs.unlinkSync(filePath);
        }
      }
    }

    // Kategorie löschen (CASCADE löscht Einträge und Anhänge aus DB)
    db.prepare('DELETE FROM knowledge_categories WHERE id = ?').run(categoryId);

    // Positionen neu nummerieren
    const remaining = db.prepare(
      'SELECT id FROM knowledge_categories ORDER BY position'
    ).all();
    remaining.forEach((c, idx) => {
      db.prepare('UPDATE knowledge_categories SET position = ? WHERE id = ?').run(idx, c.id);
    });

    logger.info(`Knowledge-Kategorie gelöscht: ${category.name}`);

    res.json({ message: 'Kategorie gelöscht' });
  } catch (error) {
    logger.error('Fehler beim Löschen der Knowledge-Kategorie:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

// =====================
// EINTRÄGE
// =====================

/**
 * GET /api/knowledge/entries
 * Einträge abrufen (optional gefiltert nach Kategorie)
 */
router.get('/entries', (req, res) => {
  try {
    const { categoryId } = req.query;
    const db = getDb();

    let query = `
      SELECT ke.*,
        kc.name as category_name,
        kc.color as category_color,
        u.display_name as creator_name,
        (SELECT COUNT(*) FROM knowledge_attachments WHERE entry_id = ke.id) as attachment_count
      FROM knowledge_entries ke
      LEFT JOIN knowledge_categories kc ON ke.category_id = kc.id
      LEFT JOIN users u ON ke.created_by = u.id
    `;

    const params = [];
    if (categoryId) {
      query += ' WHERE ke.category_id = ?';
      params.push(categoryId);
    }

    query += ' ORDER BY ke.position, ke.created_at DESC';

    const entries = db.prepare(query).all(...params);

    res.json(entries.map(e => ({
      id: e.id,
      categoryId: e.category_id,
      categoryName: e.category_name,
      categoryColor: e.category_color,
      title: e.title,
      url: e.url,
      notes: e.notes,
      position: e.position,
      attachmentCount: e.attachment_count,
      createdBy: e.created_by,
      creatorName: e.creator_name,
      createdAt: e.created_at,
      updatedAt: e.updated_at
    })));
  } catch (error) {
    logger.error('Fehler beim Abrufen der Knowledge-Einträge:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * GET /api/knowledge/entries/:id
 * Einzelnen Eintrag abrufen (mit Anhängen)
 */
router.get('/entries/:id', (req, res) => {
  try {
    const entryId = req.params.id;
    const db = getDb();

    const entry = db.prepare(`
      SELECT ke.*,
        kc.name as category_name,
        kc.color as category_color,
        u.display_name as creator_name
      FROM knowledge_entries ke
      LEFT JOIN knowledge_categories kc ON ke.category_id = kc.id
      LEFT JOIN users u ON ke.created_by = u.id
      WHERE ke.id = ?
    `).get(entryId);

    if (!entry) {
      return res.status(404).json({ error: 'Eintrag nicht gefunden' });
    }

    const attachments = db.prepare(`
      SELECT ka.*, u.display_name as uploader_name
      FROM knowledge_attachments ka
      LEFT JOIN users u ON ka.uploaded_by = u.id
      WHERE ka.entry_id = ?
      ORDER BY ka.uploaded_at DESC
    `).all(entryId);

    res.json({
      id: entry.id,
      categoryId: entry.category_id,
      categoryName: entry.category_name,
      categoryColor: entry.category_color,
      title: entry.title,
      url: entry.url,
      notes: entry.notes,
      position: entry.position,
      createdBy: entry.created_by,
      creatorName: entry.creator_name,
      createdAt: entry.created_at,
      updatedAt: entry.updated_at,
      attachments: attachments.map(a => ({
        id: a.id,
        filename: a.filename,
        originalName: a.original_name,
        mimeType: a.mime_type,
        sizeBytes: a.size_bytes,
        uploadedBy: a.uploaded_by,
        uploaderName: a.uploader_name,
        uploadedAt: a.uploaded_at
      }))
    });
  } catch (error) {
    logger.error('Fehler beim Abrufen des Knowledge-Eintrags:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * POST /api/knowledge/entries
 * Neuen Eintrag erstellen
 */
router.post('/entries', (req, res) => {
  try {
    const { categoryId, title, url, notes } = req.body;

    // Validierung
    const categoryError = validators.required(categoryId, 'Kategorie');
    if (categoryError) {
      return res.status(400).json({ error: categoryError });
    }

    const titleError = validators.required(title, 'Titel') ||
      validators.maxLength(title, 200, 'Titel');
    if (titleError) {
      return res.status(400).json({ error: titleError });
    }

    if (url) {
      const urlError = validators.url(url, 'URL');
      if (urlError) {
        return res.status(400).json({ error: urlError });
      }
    }

    const db = getDb();

    // Kategorie prüfen
    const category = db.prepare('SELECT * FROM knowledge_categories WHERE id = ?').get(categoryId);
    if (!category) {
      return res.status(404).json({ error: 'Kategorie nicht gefunden' });
    }

    // Alle bestehenden Einträge um 1 nach unten verschieben
    db.prepare(`
      UPDATE knowledge_entries 
      SET position = position + 1 
      WHERE category_id = ?
    `).run(categoryId);

    // Neuen Eintrag an Position 0 (ganz oben) einfügen
    const result = db.prepare(`
      INSERT INTO knowledge_entries (category_id, title, url, notes, position, created_by)
      VALUES (?, ?, ?, ?, ?, ?)
    `).run(
      categoryId,
      stripHtml(title),
      url || null,
      notes ? sanitizeNotes(notes) : null,
      0, // Neue Einträge immer an Position 0 (oben)
      req.user.id
    );

    const entry = db.prepare('SELECT * FROM knowledge_entries WHERE id = ?')
      .get(result.lastInsertRowid);

    logger.info(`Knowledge-Eintrag erstellt: ${title}`);

    // Benachrichtigung an alle Nutzer senden
    const io = req.app.get('io');
    if (io) {
      // Alle Nutzer abrufen (außer dem Ersteller)
      const users = db.prepare(`
        SELECT id FROM users 
        WHERE id != ?
      `).all(req.user.id);

      // Benachrichtigung für jeden Nutzer erstellen
      users.forEach(user => {
        notificationService.create(
          user.id,
          'knowledge:new_entry',
          {
            entryId: entry.id,
            entryTitle: entry.title,
            categoryName: category.name,
            categoryId: category.id,
            projectId: null,
            actorId: req.user.id
          },
          io,
          true // persistent, damit die Benachrichtigung in der Inbox bleibt
        );
      });

      // Socket.io Event für Echtzeit-Update senden
      io.emit('knowledge:created', {
        entry: {
          id: entry.id,
          categoryId: entry.category_id,
          categoryName: category.name,
          categoryColor: category.color,
          title: entry.title,
          url: entry.url,
          notes: entry.notes,
          position: entry.position,
          attachmentCount: 0,
          createdBy: entry.created_by,
          creatorName: req.user.display_name,
          createdAt: entry.created_at,
          updatedAt: entry.updated_at
        }
      });
    }

    res.status(201).json({
      id: entry.id,
      categoryId: entry.category_id,
      title: entry.title,
      url: entry.url,
      notes: entry.notes,
      position: entry.position,
      attachmentCount: 0,
      createdBy: entry.created_by,
      createdAt: entry.created_at,
      updatedAt: entry.updated_at
    });
  } catch (error) {
    logger.error('Fehler beim Erstellen des Knowledge-Eintrags:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * PUT /api/knowledge/entries/:id
 * Eintrag aktualisieren
 */
router.put('/entries/:id', (req, res) => {
  try {
    const entryId = req.params.id;
    const { categoryId, title, url, notes } = req.body;

    const db = getDb();

    const existing = db.prepare('SELECT * FROM knowledge_entries WHERE id = ?').get(entryId);
    if (!existing) {
      return res.status(404).json({ error: 'Eintrag nicht gefunden' });
    }

    // Validierung
    if (title) {
      const titleError = validators.maxLength(title, 200, 'Titel');
      if (titleError) {
        return res.status(400).json({ error: titleError });
      }
    }

    if (url) {
      const urlError = validators.url(url, 'URL');
      if (urlError) {
        return res.status(400).json({ error: urlError });
      }
    }

    if (categoryId) {
      const category = db.prepare('SELECT * FROM knowledge_categories WHERE id = ?').get(categoryId);
      if (!category) {
        return res.status(404).json({ error: 'Kategorie nicht gefunden' });
      }
    }

    db.prepare(`
      UPDATE knowledge_entries SET
        category_id = COALESCE(?, category_id),
        title = COALESCE(?, title),
        url = ?,
        notes = ?,
        updated_at = CURRENT_TIMESTAMP
      WHERE id = ?
    `).run(
      categoryId || null,
      title ? stripHtml(title) : null,
      url !== undefined ? url : existing.url,
      notes !== undefined ? (notes ? sanitizeNotes(notes) : notes) : existing.notes,
      entryId
    );

    const entry = db.prepare(`
      SELECT ke.*, kc.name as category_name, kc.color as category_color
      FROM knowledge_entries ke
      LEFT JOIN knowledge_categories kc ON ke.category_id = kc.id
      WHERE ke.id = ?
    `).get(entryId);

    logger.info(`Knowledge-Eintrag aktualisiert: ${entry.title}`);

    res.json({
      id: entry.id,
      categoryId: entry.category_id,
      categoryName: entry.category_name,
      categoryColor: entry.category_color,
      title: entry.title,
      url: entry.url,
      notes: entry.notes,
      position: entry.position,
      createdBy: entry.created_by,
      createdAt: entry.created_at,
      updatedAt: entry.updated_at
    });
  } catch (error) {
    logger.error('Fehler beim Aktualisieren des Knowledge-Eintrags:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * PUT /api/knowledge/entries/:id/position
 * Eintrag-Position ändern (oder in andere Kategorie verschieben)
 */
router.put('/entries/:id/position', (req, res) => {
  try {
    const entryId = req.params.id;
    const { newPosition, newCategoryId } = req.body;

    const db = getDb();

    const entry = db.prepare('SELECT * FROM knowledge_entries WHERE id = ?').get(entryId);
    if (!entry) {
      return res.status(404).json({ error: 'Eintrag nicht gefunden' });
    }

    const oldPosition = entry.position;
    const oldCategoryId = entry.category_id;
    const targetCategoryId = newCategoryId || oldCategoryId;

    // Wenn Kategorie wechselt
    if (targetCategoryId !== oldCategoryId) {
      // Alte Kategorie: Positionen nach dem entfernten Eintrag reduzieren
      db.prepare(`
        UPDATE knowledge_entries SET position = position - 1
        WHERE category_id = ? AND position > ?
      `).run(oldCategoryId, oldPosition);

      // Neue Kategorie: Platz für neuen Eintrag schaffen
      db.prepare(`
        UPDATE knowledge_entries SET position = position + 1
        WHERE category_id = ? AND position >= ?
      `).run(targetCategoryId, newPosition);

      // Eintrag verschieben
      db.prepare(`
        UPDATE knowledge_entries SET category_id = ?, position = ?
        WHERE id = ?
      `).run(targetCategoryId, newPosition, entryId);
    } else {
      // Innerhalb der gleichen Kategorie
      if (newPosition > oldPosition) {
        db.prepare(`
          UPDATE knowledge_entries SET position = position - 1
          WHERE category_id = ? AND position > ? AND position <= ?
        `).run(oldCategoryId, oldPosition, newPosition);
      } else if (newPosition < oldPosition) {
        db.prepare(`
          UPDATE knowledge_entries SET position = position + 1
          WHERE category_id = ? AND position >= ? AND position < ?
        `).run(oldCategoryId, newPosition, oldPosition);
      }

      db.prepare('UPDATE knowledge_entries SET position = ? WHERE id = ?').run(newPosition, entryId);
    }

    res.json({ message: 'Position aktualisiert' });
  } catch (error) {
    logger.error('Fehler beim Verschieben des Knowledge-Eintrags:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * DELETE /api/knowledge/entries/:id
 * Eintrag löschen
 */
router.delete('/entries/:id', (req, res) => {
  try {
    const entryId = req.params.id;
    const db = getDb();

    const entry = db.prepare('SELECT * FROM knowledge_entries WHERE id = ?').get(entryId);
    if (!entry) {
      return res.status(404).json({ error: 'Eintrag nicht gefunden' });
    }

    // Anhänge vom Dateisystem löschen
    const attachments = db.prepare('SELECT * FROM knowledge_attachments WHERE entry_id = ?').all(entryId);
    for (const attachment of attachments) {
      const filePath = path.join(UPLOAD_DIR, attachment.filename);
      if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
      }
    }

    const categoryId = entry.category_id;

    // Eintrag löschen
    db.prepare('DELETE FROM knowledge_entries WHERE id = ?').run(entryId);

    // Positionen neu nummerieren
    const remaining = db.prepare(
      'SELECT id FROM knowledge_entries WHERE category_id = ? ORDER BY position'
    ).all(categoryId);
    remaining.forEach((e, idx) => {
      db.prepare('UPDATE knowledge_entries SET position = ? WHERE id = ?').run(idx, e.id);
    });

    logger.info(`Knowledge-Eintrag gelöscht: ${entry.title}`);

    res.json({ message: 'Eintrag gelöscht' });
  } catch (error) {
    logger.error('Fehler beim Löschen des Knowledge-Eintrags:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

// =====================
// ANHÄNGE
// =====================

/**
 * GET /api/knowledge/attachments/:entryId
 * Anhänge eines Eintrags abrufen
 */
router.get('/attachments/:entryId', (req, res) => {
  try {
    const entryId = req.params.entryId;
    const db = getDb();

    const entry = db.prepare('SELECT * FROM knowledge_entries WHERE id = ?').get(entryId);
    if (!entry) {
      return res.status(404).json({ error: 'Eintrag nicht gefunden' });
    }

    const attachments = db.prepare(`
      SELECT ka.*, u.display_name as uploader_name
      FROM knowledge_attachments ka
      LEFT JOIN users u ON ka.uploaded_by = u.id
      WHERE ka.entry_id = ?
      ORDER BY ka.uploaded_at DESC
    `).all(entryId);

    res.json(attachments.map(a => ({
      id: a.id,
      entryId: a.entry_id,
      filename: a.filename,
      originalName: a.original_name,
      mimeType: a.mime_type,
      sizeBytes: a.size_bytes,
      uploadedBy: a.uploaded_by,
      uploaderName: a.uploader_name,
      uploadedAt: a.uploaded_at
    })));
  } catch (error) {
    logger.error('Fehler beim Abrufen der Knowledge-Anhänge:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * POST /api/knowledge/attachments/:entryId
 * Anhang hochladen
 */
router.post('/attachments/:entryId', upload.single('files'), (req, res) => {
  try {
    const entryId = req.params.entryId;
    const db = getDb();

    const entry = db.prepare('SELECT * FROM knowledge_entries WHERE id = ?').get(entryId);
    if (!entry) {
      // Hochgeladene Datei löschen
      if (req.file) {
        fs.unlinkSync(req.file.path);
      }
      return res.status(404).json({ error: 'Eintrag nicht gefunden' });
    }

    if (!req.file) {
      return res.status(400).json({ error: 'Keine Datei hochgeladen' });
    }

    const result = db.prepare(`
      INSERT INTO knowledge_attachments (entry_id, filename, original_name, mime_type, size_bytes, uploaded_by)
      VALUES (?, ?, ?, ?, ?, ?)
    `).run(
      entryId,
      req.file.filename,
      req.file.originalname,
      req.file.mimetype,
      req.file.size,
      req.user.id
    );

    // Eintrag updated_at aktualisieren
    db.prepare('UPDATE knowledge_entries SET updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(entryId);

    const attachment = db.prepare('SELECT * FROM knowledge_attachments WHERE id = ?')
      .get(result.lastInsertRowid);

    logger.info(`Knowledge-Anhang hochgeladen: ${req.file.originalname} für Eintrag ${entry.title}`);

    res.status(201).json({
      id: attachment.id,
      entryId: attachment.entry_id,
      filename: attachment.filename,
      originalName: attachment.original_name,
      mimeType: attachment.mime_type,
      sizeBytes: attachment.size_bytes,
      uploadedBy: attachment.uploaded_by,
      uploadedAt: attachment.uploaded_at
    });
  } catch (error) {
    logger.error('Fehler beim Hochladen des Knowledge-Anhangs:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * GET /api/knowledge/attachments/download/:id
 * Anhang herunterladen
 */
router.get('/attachments/download/:id', (req, res) => {
  try {
    const attachmentId = req.params.id;
    const db = getDb();

    const attachment = db.prepare('SELECT * FROM knowledge_attachments WHERE id = ?').get(attachmentId);
    if (!attachment) {
      return res.status(404).json({ error: 'Anhang nicht gefunden' });
    }

    const filePath = path.join(UPLOAD_DIR, attachment.filename);
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({ error: 'Datei nicht gefunden' });
    }

    res.download(filePath, attachment.original_name);
  } catch (error) {
    logger.error('Fehler beim Herunterladen des Knowledge-Anhangs:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * DELETE /api/knowledge/attachments/:id
 * Anhang löschen
 */
router.delete('/attachments/:id', (req, res) => {
  try {
    const attachmentId = req.params.id;
    const db = getDb();

    const attachment = db.prepare('SELECT * FROM knowledge_attachments WHERE id = ?').get(attachmentId);
    if (!attachment) {
      return res.status(404).json({ error: 'Anhang nicht gefunden' });
    }

    // Datei vom Dateisystem löschen
    const filePath = path.join(UPLOAD_DIR, attachment.filename);
    if (fs.existsSync(filePath)) {
      fs.unlinkSync(filePath);
    }

    // Aus Datenbank löschen
    db.prepare('DELETE FROM knowledge_attachments WHERE id = ?').run(attachmentId);

    // Eintrag updated_at aktualisieren
    db.prepare('UPDATE knowledge_entries SET updated_at = CURRENT_TIMESTAMP WHERE id = ?')
      .run(attachment.entry_id);

    logger.info(`Knowledge-Anhang gelöscht: ${attachment.original_name}`);

    res.json({ message: 'Anhang gelöscht' });
  } catch (error) {
    logger.error('Fehler beim Löschen des Knowledge-Anhangs:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

// =====================
// SUCHE
// =====================

/**
 * GET /api/knowledge/search
 * Wissensmanagement durchsuchen
 */
router.get('/search', (req, res) => {
  try {
    const { q } = req.query;

    if (!q || q.trim().length < 2) {
      return res.json({ categories: [], entries: [] });
    }

    const searchTerm = `%${q.toLowerCase()}%`;
    const db = getDb();

    // Kategorien durchsuchen (kein FTS noetig - wenige Datensaetze)
    const categories = db.prepare(`
      SELECT kc.*,
        (SELECT COUNT(*) FROM knowledge_entries WHERE category_id = kc.id) as entry_count
      FROM knowledge_categories kc
      WHERE LOWER(kc.name) LIKE ? OR LOWER(kc.description) LIKE ?
      ORDER BY kc.position
    `).all(searchTerm, searchTerm);

    // Eintraege durchsuchen - FTS5 mit Fallback auf LIKE
    let entries;
    try {
      // FTS5 Suche: Sonderzeichen escapen und Prefix-Suche
      const ftsQuery = q.trim().replace(/['"*()]/g, '').split(/\s+/).map(t => `"${t}"*`).join(' ');
      entries = db.prepare(`
        SELECT ke.*,
          kc.name as category_name,
          kc.color as category_color,
          (SELECT COUNT(*) FROM knowledge_attachments WHERE entry_id = ke.id) as attachment_count
        FROM knowledge_fts fts
        JOIN knowledge_entries ke ON ke.id = fts.rowid
        LEFT JOIN knowledge_categories kc ON ke.category_id = kc.id
        WHERE knowledge_fts MATCH ?
        ORDER BY rank
        LIMIT 50
      `).all(ftsQuery);
    } catch (ftsError) {
      // Fallback auf LIKE wenn FTS nicht verfuegbar
      logger.warn('FTS5-Suche fehlgeschlagen, Fallback auf LIKE:', ftsError.message);
      entries = db.prepare(`
        SELECT ke.*,
          kc.name as category_name,
          kc.color as category_color,
          (SELECT COUNT(*) FROM knowledge_attachments WHERE entry_id = ke.id) as attachment_count
        FROM knowledge_entries ke
        LEFT JOIN knowledge_categories kc ON ke.category_id = kc.id
        WHERE LOWER(ke.title) LIKE ? OR LOWER(ke.notes) LIKE ? OR LOWER(ke.url) LIKE ?
        ORDER BY
          CASE
            WHEN LOWER(ke.title) LIKE ? THEN 1
            ELSE 2
          END,
          ke.created_at DESC
        LIMIT 50
      `).all(searchTerm, searchTerm, searchTerm, searchTerm);
    }

    res.json({
      categories: categories.map(c => ({
        id: c.id,
        name: c.name,
        description: c.description,
        color: c.color,
        icon: c.icon,
        entryCount: c.entry_count
      })),
      entries: entries.map(e => ({
        id: e.id,
        categoryId: e.category_id,
        categoryName: e.category_name,
        categoryColor: e.category_color,
        title: e.title,
        url: e.url,
        notes: e.notes,
        attachmentCount: e.attachment_count,
        createdAt: e.created_at
      }))
    });
  } catch (error) {
    logger.error('Fehler bei der Knowledge-Suche:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

module.exports = router;
