/**
 * TASKMATE - Project Routes
 * =========================
 * CRUD für Projekte
 */

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

/**
 * GET /api/projects
 * Alle Projekte abrufen
 */
router.get('/', (req, res) => {
  try {
    const db = getDb();
    const includeArchived = req.query.archived === 'true';

    let query = `
      SELECT p.*, u.display_name as creator_name,
        (SELECT COUNT(*) FROM tasks t WHERE t.project_id = p.id AND t.archived = 0) as task_count,
        (SELECT COUNT(*) FROM tasks t WHERE t.project_id = p.id AND t.archived = 0 AND t.column_id IN
          (SELECT c.id FROM columns c WHERE c.project_id = p.id ORDER BY c.position DESC LIMIT 1)) as completed_count
      FROM projects p
      LEFT JOIN users u ON p.created_by = u.id
    `;

    if (!includeArchived) {
      query += ' WHERE p.archived = 0';
    }

    query += ' ORDER BY p.created_at DESC';

    const projects = db.prepare(query).all();

    res.json(projects.map(p => ({
      id: p.id,
      name: p.name,
      description: p.description,
      archived: !!p.archived,
      createdAt: p.created_at,
      createdBy: p.created_by,
      creatorName: p.creator_name,
      taskCount: p.task_count,
      completedCount: p.completed_count
    })));
  } catch (error) {
    logger.error('Fehler beim Abrufen der Projekte:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * GET /api/projects/:id
 * Einzelnes Projekt mit Spalten und Aufgaben
 */
router.get('/:id', (req, res) => {
  try {
    const db = getDb();
    const projectId = req.params.id;

    // Projekt abrufen
    const project = db.prepare(`
      SELECT p.*, u.display_name as creator_name
      FROM projects p
      LEFT JOIN users u ON p.created_by = u.id
      WHERE p.id = ?
    `).get(projectId);

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

    // Spalten abrufen
    const columns = db.prepare(`
      SELECT * FROM columns WHERE project_id = ? ORDER BY position
    `).all(projectId);

    // Labels abrufen
    const labels = db.prepare(`
      SELECT * FROM labels WHERE project_id = ?
    `).all(projectId);

    res.json({
      id: project.id,
      name: project.name,
      description: project.description,
      archived: !!project.archived,
      createdAt: project.created_at,
      createdBy: project.created_by,
      creatorName: project.creator_name,
      columns: columns.map(c => ({
        id: c.id,
        name: c.name,
        position: c.position,
        color: c.color
      })),
      labels: labels.map(l => ({
        id: l.id,
        name: l.name,
        color: l.color
      }))
    });
  } catch (error) {
    logger.error('Fehler beim Abrufen des Projekts:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * POST /api/projects
 * Neues Projekt erstellen
 */
router.post('/', (req, res) => {
  try {
    const { name, description } = req.body;

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

    const db = getDb();

    // Projekt erstellen
    const result = db.prepare(`
      INSERT INTO projects (name, description, created_by)
      VALUES (?, ?, ?)
    `).run(name, description || null, req.user.id);

    const projectId = result.lastInsertRowid;

    // Standard-Spalten erstellen
    const insertColumn = db.prepare(`
      INSERT INTO columns (project_id, name, position) VALUES (?, ?, ?)
    `);

    insertColumn.run(projectId, 'Offen', 0);
    insertColumn.run(projectId, 'In Arbeit', 1);
    insertColumn.run(projectId, 'Erledigt', 2);

    // Standard-Labels erstellen
    const insertLabel = db.prepare(`
      INSERT INTO labels (project_id, name, color) VALUES (?, ?, ?)
    `);

    insertLabel.run(projectId, 'Bug', '#DC2626');
    insertLabel.run(projectId, 'Feature', '#059669');
    insertLabel.run(projectId, 'Dokumentation', '#3182CE');

    // Projekt mit Spalten und Labels zurückgeben
    const project = db.prepare('SELECT * FROM projects WHERE id = ?').get(projectId);
    const columns = db.prepare('SELECT * FROM columns WHERE project_id = ? ORDER BY position').all(projectId);
    const labels = db.prepare('SELECT * FROM labels WHERE project_id = ?').all(projectId);

    logger.info(`Projekt erstellt: ${name} (ID: ${projectId}) von ${req.user.username}`);

    // WebSocket: Andere Clients benachrichtigen
    const io = req.app.get('io');
    io.emit('project:created', {
      id: projectId,
      name: project.name,
      description: project.description,
      createdBy: req.user.id
    });

    res.status(201).json({
      id: project.id,
      name: project.name,
      description: project.description,
      archived: false,
      createdAt: project.created_at,
      createdBy: project.created_by,
      columns: columns.map(c => ({ id: c.id, name: c.name, position: c.position, color: c.color })),
      labels: labels.map(l => ({ id: l.id, name: l.name, color: l.color }))
    });
  } catch (error) {
    logger.error('Fehler beim Erstellen des Projekts:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * PUT /api/projects/:id
 * Projekt aktualisieren
 */
router.put('/:id', (req, res) => {
  try {
    const projectId = req.params.id;
    const { name, description } = req.body;

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

    const db = getDb();

    // Prüfen ob Projekt existiert
    const existing = db.prepare('SELECT * FROM projects WHERE id = ?').get(projectId);
    if (!existing) {
      return res.status(404).json({ error: 'Projekt nicht gefunden' });
    }

    // Aktualisieren
    db.prepare(`
      UPDATE projects
      SET name = COALESCE(?, name), description = COALESCE(?, description)
      WHERE id = ?
    `).run(name || null, description !== undefined ? description : null, projectId);

    const project = db.prepare('SELECT * FROM projects WHERE id = ?').get(projectId);

    logger.info(`Projekt aktualisiert: ${project.name} (ID: ${projectId})`);

    // WebSocket
    const io = req.app.get('io');
    io.emit('project:updated', {
      id: project.id,
      name: project.name,
      description: project.description
    });

    res.json({
      id: project.id,
      name: project.name,
      description: project.description,
      archived: !!project.archived,
      createdAt: project.created_at
    });
  } catch (error) {
    logger.error('Fehler beim Aktualisieren des Projekts:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * PUT /api/projects/:id/archive
 * Projekt archivieren/wiederherstellen
 */
router.put('/:id/archive', (req, res) => {
  try {
    const projectId = req.params.id;
    const { archived } = req.body;

    const db = getDb();

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

    db.prepare('UPDATE projects SET archived = ? WHERE id = ?')
      .run(archived ? 1 : 0, projectId);

    logger.info(`Projekt ${archived ? 'archiviert' : 'wiederhergestellt'}: ${existing.name}`);

    // WebSocket
    const io = req.app.get('io');
    io.emit('project:archived', { id: projectId, archived: !!archived });

    res.json({ message: archived ? 'Projekt archiviert' : 'Projekt wiederhergestellt' });
  } catch (error) {
    logger.error('Fehler beim Archivieren:', { error: error.message });
    res.status(500).json({ error: 'Interner Serverfehler' });
  }
});

/**
 * DELETE /api/projects/:id
 * Projekt löschen
 * Query param: force=true um alle zugehörigen Aufgaben mitzulöschen
 */
router.delete('/:id', (req, res) => {
  try {
    const projectId = req.params.id;
    const forceDelete = req.query.force === 'true';
    const db = getDb();

    const project = db.prepare('SELECT * FROM projects WHERE id = ?').get(projectId);
    if (!project) {
      return res.status(404).json({ error: 'Projekt nicht gefunden' });
    }

    // Anzahl der Aufgaben ermitteln
    const taskCount = db.prepare(
      'SELECT COUNT(*) as count FROM tasks WHERE project_id = ?'
    ).get(projectId).count;

    // Ohne force: Prüfen ob noch aktive Aufgaben existieren
    if (!forceDelete && taskCount > 0) {
      return res.status(400).json({
        error: 'Projekt enthält noch Aufgaben. Verwende force=true um alles zu löschen.',
        taskCount: taskCount
      });
    }

    // Bei force=true: Explizit alle zugehörigen Daten löschen
    if (forceDelete && taskCount > 0) {
      // Alle Task-IDs für das Projekt holen
      const taskIds = db.prepare('SELECT id FROM tasks WHERE project_id = ?')
        .all(projectId)
        .map(t => t.id);

      if (taskIds.length > 0) {
        const placeholders = taskIds.map(() => '?').join(',');

        // Anhänge löschen
        db.prepare(`DELETE FROM attachments WHERE task_id IN (${placeholders})`).run(...taskIds);
        // Kommentare löschen
        db.prepare(`DELETE FROM comments WHERE task_id IN (${placeholders})`).run(...taskIds);
        // Task-Labels löschen
        db.prepare(`DELETE FROM task_labels WHERE task_id IN (${placeholders})`).run(...taskIds);
        // Task-Assignees löschen (Mehrfachzuweisung)
        db.prepare(`DELETE FROM task_assignees WHERE task_id IN (${placeholders})`).run(...taskIds);
        // Unteraufgaben löschen
        db.prepare(`DELETE FROM subtasks WHERE task_id IN (${placeholders})`).run(...taskIds);
        // Links löschen
        db.prepare(`DELETE FROM links WHERE task_id IN (${placeholders})`).run(...taskIds);
        // Historie löschen
        db.prepare(`DELETE FROM history WHERE task_id IN (${placeholders})`).run(...taskIds);
        // Tasks löschen
        db.prepare(`DELETE FROM tasks WHERE project_id = ?`).run(projectId);
      }

      logger.info(`${taskCount} Aufgaben gelöscht für Projekt: ${project.name}`);
    }

    // Labels des Projekts löschen
    db.prepare('DELETE FROM labels WHERE project_id = ?').run(projectId);

    // Spalten löschen
    db.prepare('DELETE FROM columns WHERE project_id = ?').run(projectId);

    // Projekt löschen
    db.prepare('DELETE FROM projects WHERE id = ?').run(projectId);

    logger.info(`Projekt gelöscht: ${project.name} (ID: ${projectId}), ${taskCount} Aufgaben entfernt`);

    // WebSocket
    const io = req.app.get('io');
    io.emit('project:deleted', { id: projectId });

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

module.exports = router;
