/**
 * TASKMATE - Label Routes
 * =======================
 * CRUD für Labels/Tags
 */

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

/**
 * GET /api/labels/:projectId
 * Alle Labels eines Projekts
 */
router.get('/:projectId', (req, res) => {
  try {
    const db = getDb();
    const labels = db.prepare(`
      SELECT l.*,
        (SELECT COUNT(*) FROM task_labels tl WHERE tl.label_id = l.id) as task_count
      FROM labels l
      WHERE l.project_id = ?
      ORDER BY l.name
    `).all(req.params.projectId);

    res.json(labels.map(l => ({
      id: l.id,
      projectId: l.project_id,
      name: l.name,
      color: l.color,
      taskCount: l.task_count
    })));
  } catch (error) {
    logger.error('Fehler beim Abrufen der Labels:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * POST /api/labels
 * Neues Label erstellen
 */
router.post('/', (req, res) => {
  try {
    const { projectId, name, color } = req.body;

    // Validierung
    const errors = [];
    errors.push(validators.required(projectId, 'Projekt-ID'));
    errors.push(validators.required(name, 'Name'));
    errors.push(validators.maxLength(name, 30, 'Name'));
    errors.push(validators.required(color, 'Farbe'));
    errors.push(validators.hexColor(color, 'Farbe'));

    const firstError = errors.find(e => e !== null);
    if (firstError) {
      return res.status(400).json({ error: firstError });
    }

    const db = getDb();

    // Prüfen ob Label-Name bereits existiert
    const existing = db.prepare(
      'SELECT id FROM labels WHERE project_id = ? AND LOWER(name) = LOWER(?)'
    ).get(projectId, name);

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

    const result = db.prepare(`
      INSERT INTO labels (project_id, name, color)
      VALUES (?, ?, ?)
    `).run(projectId, name, color);

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

    logger.info(`Label erstellt: ${name} in Projekt ${projectId}`);

    // WebSocket
    const io = req.app.get('io');
    io.to(`project:${projectId}`).emit('label:created', {
      id: label.id,
      projectId: label.project_id,
      name: label.name,
      color: label.color
    });

    res.status(201).json({
      id: label.id,
      projectId: label.project_id,
      name: label.name,
      color: label.color,
      taskCount: 0
    });
  } catch (error) {
    logger.error('Fehler beim Erstellen des Labels:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * PUT /api/labels/:id
 * Label aktualisieren
 */
router.put('/:id', (req, res) => {
  try {
    const labelId = req.params.id;
    const { name, color } = req.body;

    // Validierung
    if (name) {
      const nameError = validators.maxLength(name, 30, '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();

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

    // Prüfen ob neuer Name bereits existiert
    if (name && name.toLowerCase() !== existing.name.toLowerCase()) {
      const duplicate = db.prepare(
        'SELECT id FROM labels WHERE project_id = ? AND LOWER(name) = LOWER(?) AND id != ?'
      ).get(existing.project_id, name, labelId);

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

    db.prepare(`
      UPDATE labels SET
        name = COALESCE(?, name),
        color = COALESCE(?, color)
      WHERE id = ?
    `).run(name || null, color || null, labelId);

    const label = db.prepare('SELECT * FROM labels WHERE id = ?').get(labelId);

    logger.info(`Label aktualisiert: ${label.name} (ID: ${labelId})`);

    // WebSocket
    const io = req.app.get('io');
    io.to(`project:${label.project_id}`).emit('label:updated', {
      id: label.id,
      name: label.name,
      color: label.color
    });

    res.json({
      id: label.id,
      projectId: label.project_id,
      name: label.name,
      color: label.color
    });
  } catch (error) {
    logger.error('Fehler beim Aktualisieren des Labels:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * DELETE /api/labels/:id
 * Label löschen
 */
router.delete('/:id', (req, res) => {
  try {
    const labelId = req.params.id;
    const db = getDb();

    const label = db.prepare('SELECT * FROM labels WHERE id = ?').get(labelId);
    if (!label) {
      return res.status(404).json({ error: 'Label nicht gefunden' });
    }

    // Label wird von task_labels durch CASCADE gelöscht
    db.prepare('DELETE FROM labels WHERE id = ?').run(labelId);

    logger.info(`Label gelöscht: ${label.name} (ID: ${labelId})`);

    // WebSocket
    const io = req.app.get('io');
    io.to(`project:${label.project_id}`).emit('label:deleted', { id: labelId });

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

module.exports = router;
