/**
 * TASKMATE - Comment Routes
 * =========================
 * CRUD für Kommentare
 */

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

/**
 * GET /api/comments/:taskId
 * Alle Kommentare einer Aufgabe
 */
router.get('/:taskId', (req, res) => {
  try {
    const db = getDb();
    const comments = db.prepare(`
      SELECT c.*, u.display_name, u.color
      FROM comments c
      JOIN users u ON c.user_id = u.id
      WHERE c.task_id = ?
      ORDER BY c.created_at ASC
    `).all(req.params.taskId);

    res.json(comments.map(c => ({
      id: c.id,
      taskId: c.task_id,
      userId: c.user_id,
      userName: c.display_name,
      userColor: c.color,
      content: c.content,
      createdAt: c.created_at
    })));
  } catch (error) {
    logger.error('Fehler beim Abrufen der Kommentare:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * POST /api/comments
 * Neuen Kommentar erstellen
 */
router.post('/', (req, res) => {
  try {
    const { taskId, content } = req.body;

    // Validierung
    const contentError = validators.required(content, 'Inhalt') ||
      validators.maxLength(content, 5000, 'Inhalt');
    if (contentError) {
      return res.status(400).json({ error: contentError });
    }

    const db = getDb();

    // Task prüfen
    const task = db.prepare('SELECT * FROM tasks WHERE id = ?').get(taskId);
    if (!task) {
      return res.status(404).json({ error: 'Aufgabe nicht gefunden' });
    }

    // Inhalt bereinigen (Markdown erlaubt)
    const sanitizedContent = sanitizeMarkdown(content);

    // @Erwähnungen verarbeiten
    const mentions = content.match(/@(\w+)/g);
    const mentionedUsers = [];

    if (mentions) {
      mentions.forEach(mention => {
        const username = mention.substring(1);
        const user = db.prepare('SELECT id, display_name FROM users WHERE username = ?').get(username);
        if (user) {
          mentionedUsers.push(user);
        }
      });
    }

    // Kommentar erstellen
    const result = db.prepare(`
      INSERT INTO comments (task_id, user_id, content)
      VALUES (?, ?, ?)
    `).run(taskId, req.user.id, sanitizedContent);

    // Task updated_at aktualisieren
    db.prepare('UPDATE tasks SET updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(taskId);

    // Historie
    db.prepare(`
      INSERT INTO history (task_id, user_id, action, new_value)
      VALUES (?, ?, 'commented', ?)
    `).run(taskId, req.user.id, sanitizedContent.substring(0, 100));

    const comment = db.prepare(`
      SELECT c.*, u.display_name, u.color
      FROM comments c
      JOIN users u ON c.user_id = u.id
      WHERE c.id = ?
    `).get(result.lastInsertRowid);

    logger.info(`Kommentar erstellt in Task ${taskId} von ${req.user.username}`);

    // WebSocket
    const io = req.app.get('io');
    io.to(`project:${task.project_id}`).emit('comment:created', {
      taskId,
      comment: {
        id: comment.id,
        taskId: comment.task_id,
        userId: comment.user_id,
        userName: comment.display_name,
        userColor: comment.color,
        content: comment.content,
        createdAt: comment.created_at
      },
      mentionedUsers
    });

    // Benachrichtigungen senden
    // 1. Benachrichtigung an zugewiesene Mitarbeiter der Aufgabe
    const assignees = db.prepare('SELECT user_id FROM task_assignees WHERE task_id = ?').all(taskId);
    const mentionedUserIds = mentionedUsers.map(u => u.id);

    assignees.forEach(a => {
      // Nicht an Kommentator und nicht an erwähnte Benutzer (die bekommen separate Benachrichtigung)
      if (a.user_id !== req.user.id && !mentionedUserIds.includes(a.user_id)) {
        notificationService.create(a.user_id, 'comment:created', {
          taskId: parseInt(taskId),
          taskTitle: task.title,
          projectId: task.project_id,
          actorId: req.user.id,
          actorName: req.user.display_name || req.user.username
        }, io);
      }
    });

    // 2. Benachrichtigung an erwähnte Benutzer
    mentionedUsers.forEach(user => {
      if (user.id !== req.user.id) {
        notificationService.create(user.id, 'comment:mention', {
          taskId: parseInt(taskId),
          taskTitle: task.title,
          projectId: task.project_id,
          actorId: req.user.id,
          actorName: req.user.display_name || req.user.username
        }, io);
      }
    });

    res.status(201).json({
      id: comment.id,
      taskId: comment.task_id,
      userId: comment.user_id,
      userName: comment.display_name,
      userColor: comment.color,
      content: comment.content,
      createdAt: comment.created_at
    });
  } catch (error) {
    logger.error('Fehler beim Erstellen des Kommentars:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * PUT /api/comments/:id
 * Kommentar bearbeiten (nur eigene)
 */
router.put('/:id', (req, res) => {
  try {
    const commentId = req.params.id;
    const { content } = req.body;

    // Validierung
    const contentError = validators.required(content, 'Inhalt') ||
      validators.maxLength(content, 5000, 'Inhalt');
    if (contentError) {
      return res.status(400).json({ error: contentError });
    }

    const db = getDb();

    const comment = db.prepare('SELECT * FROM comments WHERE id = ?').get(commentId);
    if (!comment) {
      return res.status(404).json({ error: 'Kommentar nicht gefunden' });
    }

    // Nur eigene Kommentare bearbeiten
    if (comment.user_id !== req.user.id) {
      return res.status(403).json({ error: 'Nur eigene Kommentare können bearbeitet werden' });
    }

    const sanitizedContent = sanitizeMarkdown(content);

    db.prepare('UPDATE comments SET content = ? WHERE id = ?')
      .run(sanitizedContent, commentId);

    const updated = db.prepare(`
      SELECT c.*, u.display_name, u.color
      FROM comments c
      JOIN users u ON c.user_id = u.id
      WHERE c.id = ?
    `).get(commentId);

    const task = db.prepare('SELECT project_id FROM tasks WHERE id = ?').get(comment.task_id);

    // WebSocket
    const io = req.app.get('io');
    io.to(`project:${task.project_id}`).emit('comment:updated', {
      taskId: comment.task_id,
      comment: {
        id: updated.id,
        taskId: updated.task_id,
        userId: updated.user_id,
        userName: updated.display_name,
        userColor: updated.color,
        content: updated.content,
        createdAt: updated.created_at
      }
    });

    res.json({
      id: updated.id,
      taskId: updated.task_id,
      userId: updated.user_id,
      userName: updated.display_name,
      userColor: updated.color,
      content: updated.content,
      createdAt: updated.created_at
    });
  } catch (error) {
    logger.error('Fehler beim Aktualisieren des Kommentars:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * DELETE /api/comments/:id
 * Kommentar löschen (nur eigene)
 */
router.delete('/:id', (req, res) => {
  try {
    const commentId = req.params.id;
    const db = getDb();

    const comment = db.prepare('SELECT * FROM comments WHERE id = ?').get(commentId);
    if (!comment) {
      return res.status(404).json({ error: 'Kommentar nicht gefunden' });
    }

    // Nur eigene Kommentare löschen
    if (comment.user_id !== req.user.id) {
      return res.status(403).json({ error: 'Nur eigene Kommentare können gelöscht werden' });
    }

    db.prepare('DELETE FROM comments WHERE id = ?').run(commentId);

    const task = db.prepare('SELECT project_id FROM tasks WHERE id = ?').get(comment.task_id);

    // WebSocket
    const io = req.app.get('io');
    io.to(`project:${task.project_id}`).emit('comment:deleted', {
      taskId: comment.task_id,
      commentId
    });

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

module.exports = router;
