/**
 * TASKMATE - Git Route
 * =====================
 * API-Endpoints für Git-Operationen
 */

const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
const os = require('os');
const { getDb } = require('../database');
const logger = require('../utils/logger');
const gitService = require('../services/gitService');
const giteaService = require('../services/giteaService');
const multer = require('multer');

// Fester Pfad für Server-Modus (TaskMate Source-Code)
const SERVER_SOURCE_PATH = '/app/taskmate-source';

// Temporäres Verzeichnis für Browser-Uploads
const TEMP_UPLOAD_DIR = path.join(os.tmpdir(), 'taskmate-git-uploads');

// Multer-Konfiguration für Git-Uploads (beliebige Dateitypen)
const gitUploadStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    // Erstelle eindeutiges temporäres Verzeichnis pro Upload-Session
    const sessionId = req.body.sessionId || Date.now().toString();
    const sessionDir = path.join(TEMP_UPLOAD_DIR, sessionId);

    // Relativen Pfad aus dem Dateinamen extrahieren (wird vom Frontend gesendet)
    const relativePath = file.originalname;
    const fileDir = path.join(sessionDir, path.dirname(relativePath));

    fs.mkdirSync(fileDir, { recursive: true });
    cb(null, fileDir);
  },
  filename: (req, file, cb) => {
    // Nur den Dateinamen ohne Pfad
    cb(null, path.basename(file.originalname));
  }
});

const gitUpload = multer({
  storage: gitUploadStorage,
  limits: {
    fileSize: 50 * 1024 * 1024, // 50MB pro Datei
    files: 500 // Maximal 500 Dateien
  }
});

/**
 * Hilfsfunktion: Anwendung für Projekt abrufen
 */
function getApplicationForProject(projectId) {
  const db = getDb();
  return db.prepare('SELECT * FROM applications WHERE project_id = ?').get(projectId);
}

/**
 * POST /api/git/clone
 * Repository klonen
 */
router.post('/clone', async (req, res) => {
  try {
    const { projectId, repoUrl, localPath, branch } = req.body;

    if (!localPath) {
      return res.status(400).json({ error: 'localPath ist erforderlich' });
    }

    if (!repoUrl) {
      return res.status(400).json({ error: 'repoUrl ist erforderlich' });
    }

    // Clone ausführen
    const result = await gitService.cloneRepository(repoUrl, localPath, { branch });

    if (result.success && projectId) {
      // Anwendung aktualisieren
      const db = getDb();
      db.prepare('UPDATE applications SET last_sync = CURRENT_TIMESTAMP WHERE project_id = ?').run(projectId);
    }

    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Klonen:', error);
    res.status(500).json({ error: 'Serverfehler', details: error.message });
  }
});

/**
 * GET /api/git/status/:projectId
 * Git-Status für ein Projekt abrufen
 */
router.get('/status/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    const result = gitService.getStatus(application.local_path);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Abrufen des Status:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/pull/:projectId
 * Pull für ein Projekt ausführen
 */
router.post('/pull/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const { branch } = req.body;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    // Fetch zuerst
    gitService.fetchRemote(application.local_path);

    // Dann Pull
    const result = gitService.pullChanges(application.local_path, { branch });

    if (result.success) {
      // Sync-Zeitpunkt aktualisieren
      const db = getDb();
      db.prepare('UPDATE applications SET last_sync = CURRENT_TIMESTAMP WHERE project_id = ?').run(projectId);
    }

    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Pull:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/push/:projectId
 * Push für ein Projekt ausführen
 */
router.post('/push/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const { branch } = req.body;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    // Prüfe ob Remote existiert
    if (!gitService.hasRemote(application.local_path)) {
      return res.json({
        success: false,
        error: 'Kein Remote konfiguriert. Bitte Repository zuerst vorbereiten.'
      });
    }

    // Versuche normalen Push, falls das fehlschlägt wegen fehlendem Upstream, push mit -u
    let result = gitService.pushChanges(application.local_path, { branch });

    // Falls Push wegen fehlendem Upstream fehlschlägt, versuche mit -u
    if (!result.success && result.error && result.error.includes('no upstream')) {
      const currentBranch = branch || 'main';
      result = gitService.pushWithUpstream(application.local_path, currentBranch);
    }

    if (result.success) {
      // Sync-Zeitpunkt aktualisieren
      const db = getDb();
      db.prepare('UPDATE applications SET last_sync = CURRENT_TIMESTAMP WHERE project_id = ?').run(projectId);
    }

    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Push:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/commit/:projectId
 * Commit für ein Projekt erstellen
 */
router.post('/commit/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const { message, stageAll } = req.body;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    if (!message) {
      return res.status(400).json({ error: 'Commit-Nachricht ist erforderlich' });
    }

    // Optional: Alle Änderungen stagen
    if (stageAll !== false) {
      const stageResult = gitService.stageAll(application.local_path);
      if (!stageResult.success) {
        return res.json(stageResult);
      }
    }

    // Autor aus eingeloggtem Benutzer
    const author = req.user ? {
      name: req.user.display_name || req.user.username,
      email: req.user.email || `${req.user.username.toLowerCase()}@taskmate.local`
    } : null;

    // Commit erstellen mit Autor
    const result = gitService.commit(application.local_path, message, author);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Commit:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * GET /api/git/commits/:projectId
 * Commit-Historie für ein Projekt abrufen
 */
router.get('/commits/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const limit = parseInt(req.query.limit) || 20;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    const result = gitService.getCommitHistory(application.local_path, limit);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Abrufen der Commits:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * GET /api/git/branches/:projectId
 * Branches für ein Projekt abrufen
 */
router.get('/branches/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    const result = gitService.getBranches(application.local_path);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Abrufen der Branches:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/checkout/:projectId
 * Branch wechseln
 */
router.post('/checkout/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const { branch } = req.body;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    if (!branch) {
      return res.status(400).json({ error: 'Branch ist erforderlich' });
    }

    const result = gitService.checkoutBranch(application.local_path, branch);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Branch-Wechsel:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/fetch/:projectId
 * Fetch von Remote ausführen
 */
router.post('/fetch/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    const result = gitService.fetchRemote(application.local_path);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Fetch:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/stage/:projectId
 * Alle Änderungen stagen
 */
router.post('/stage/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    const result = gitService.stageAll(application.local_path);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Stagen:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * GET /api/git/remote/:projectId
 * Remote-URL abrufen
 */
router.get('/remote/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    const result = gitService.getRemoteUrl(application.local_path);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Abrufen der Remote-URL:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/validate-path
 * Pfad validieren
 */
router.post('/validate-path', (req, res) => {
  try {
    const { path } = req.body;

    if (!path) {
      return res.status(400).json({ error: 'Pfad ist erforderlich' });
    }

    const isAccessible = gitService.isPathAccessible(path);
    const isRepo = isAccessible ? gitService.isGitRepository(path) : false;
    const hasRemote = isRepo ? gitService.hasRemote(path) : false;

    res.json({
      valid: isAccessible,
      isRepository: isRepo,
      hasRemote: hasRemote,
      containerPath: gitService.windowsToContainerPath(path)
    });
  } catch (error) {
    logger.error('Fehler bei der Pfad-Validierung:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/prepare/:projectId
 * Repository für Gitea vorbereiten (init, remote hinzufügen)
 */
router.post('/prepare/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const { repoUrl, branch } = req.body;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    if (!repoUrl) {
      return res.status(400).json({ error: 'repoUrl ist erforderlich' });
    }

    const result = gitService.prepareForGitea(application.local_path, repoUrl, { branch });

    if (result.success) {
      logger.info(`Repository vorbereitet für Projekt ${projectId}: ${repoUrl}`);
    }

    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Vorbereiten des Repositories:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/set-remote/:projectId
 * Remote für ein Projekt setzen/aktualisieren
 */
router.post('/set-remote/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const { repoUrl } = req.body;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    if (!repoUrl) {
      return res.status(400).json({ error: 'repoUrl ist erforderlich' });
    }

    // Prüfe ob Git-Repo existiert
    if (!gitService.isGitRepository(application.local_path)) {
      // Initialisiere Repository
      const initResult = gitService.initRepository(application.local_path);
      if (!initResult.success) {
        return res.json(initResult);
      }
    }

    // Remote setzen
    const result = gitService.setRemote(application.local_path, repoUrl);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Setzen des Remotes:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/init-push/:projectId
 * Initialen Push mit Upstream-Tracking
 * Body: { targetBranch?: string, force?: boolean }
 * - targetBranch: Optional - Ziel-Branch auf Remote (z.B. "main" auch wenn lokal "master")
 * - force: Optional - Force-Push um Remote zu überschreiben
 */
router.post('/init-push/:projectId', async (req, res) => {
  try {
    const { projectId } = req.params;
    const { targetBranch, force } = req.body;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    // targetBranch kann null sein - dann wird der lokale Branch-Name verwendet
    // force: boolean - überschreibt Remote-Branch bei Konflikten
    const result = gitService.pushWithUpstream(application.local_path, targetBranch || null, 'origin', force === true);

    if (result.success) {
      // Sync-Zeitpunkt aktualisieren
      const db = getDb();
      db.prepare('UPDATE applications SET last_sync = CURRENT_TIMESTAMP WHERE project_id = ?').run(projectId);

      // Default-Branch in Gitea aktualisieren wenn der gepushte Branch abweicht
      if (application.gitea_repo_url && result.branch) {
        try {
          // Owner/Repo aus URL extrahieren (z.B. https://gitea.../AegisSight/TaskMate.git)
          const urlMatch = application.gitea_repo_url.match(/\/([^\/]+)\/([^\/]+?)(?:\.git)?$/);
          if (urlMatch) {
            const owner = urlMatch[1];
            const repoName = urlMatch[2];
            const actualBranch = result.branch;

            // Default-Branch in Gitea setzen
            const updateResult = await giteaService.updateRepository(owner, repoName, {
              defaultBranch: actualBranch
            });

            if (updateResult.success) {
              logger.info(`Default-Branch in Gitea auf '${actualBranch}' gesetzt für ${owner}/${repoName}`);
              result.giteaUpdated = true;
              result.defaultBranch = actualBranch;
            } else {
              logger.warn(`Konnte Default-Branch in Gitea nicht aktualisieren: ${updateResult.error}`);
              result.giteaUpdated = false;
            }
          }
        } catch (giteaError) {
          logger.warn('Fehler beim Aktualisieren des Default-Branch in Gitea:', giteaError);
          result.giteaUpdated = false;
        }
      }
    }

    res.json(result);
  } catch (error) {
    logger.error('Fehler beim initialen Push:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/rename-branch/:projectId
 * Branch umbenennen
 * Body: { oldName: string, newName: string }
 */
router.post('/rename-branch/:projectId', (req, res) => {
  try {
    const { projectId } = req.params;
    const { oldName, newName } = req.body;
    const application = getApplicationForProject(projectId);

    if (!application) {
      return res.status(404).json({ error: 'Keine Anwendung für dieses Projekt konfiguriert' });
    }

    if (!oldName || !newName) {
      return res.status(400).json({ error: 'oldName und newName sind erforderlich' });
    }

    const result = gitService.renameBranch(application.local_path, oldName, newName);
    res.json(result);
  } catch (error) {
    logger.error('Fehler beim Umbenennen des Branches:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

// ============================================
// SERVER-MODUS ENDPOINTS
// Für direkte Git-Operationen auf dem TaskMate Source-Code
// ============================================

/**
 * GET /api/git/server/status
 * Git-Status für Server-Dateien abrufen
 */
router.get('/server/status', (req, res) => {
  try {
    // Prüfe ob der Pfad existiert und ein Git-Repo ist
    if (!gitService.isPathAccessible(SERVER_SOURCE_PATH)) {
      return res.status(500).json({
        success: false,
        error: 'Server-Verzeichnis nicht erreichbar'
      });
    }

    if (!gitService.isGitRepository(SERVER_SOURCE_PATH)) {
      return res.status(500).json({
        success: false,
        error: 'Server-Verzeichnis ist kein Git-Repository'
      });
    }

    const result = gitService.getStatus(SERVER_SOURCE_PATH);
    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Status:', error);
    res.status(500).json({ error: 'Serverfehler', details: error.message });
  }
});

/**
 * GET /api/git/server/branches
 * Branches für Server-Dateien abrufen
 */
router.get('/server/branches', (req, res) => {
  try {
    const result = gitService.getBranches(SERVER_SOURCE_PATH);
    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Abrufen der Branches:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * GET /api/git/server/commits
 * Commit-Historie für Server-Dateien abrufen
 */
router.get('/server/commits', (req, res) => {
  try {
    const limit = parseInt(req.query.limit) || 20;
    const result = gitService.getCommitHistory(SERVER_SOURCE_PATH, limit);
    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Abrufen der Commits:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * GET /api/git/server/remote
 * Remote-URL für Server-Dateien abrufen
 */
router.get('/server/remote', (req, res) => {
  try {
    const result = gitService.getRemoteUrl(SERVER_SOURCE_PATH);
    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Abrufen der Remote-URL:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/server/stage
 * Alle Änderungen für Server-Dateien stagen
 */
router.post('/server/stage', (req, res) => {
  try {
    const result = gitService.stageAll(SERVER_SOURCE_PATH);
    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Stagen:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/server/commit
 * Commit für Server-Dateien erstellen
 */
router.post('/server/commit', (req, res) => {
  try {
    const { message, stageAll } = req.body;

    if (!message) {
      return res.status(400).json({ error: 'Commit-Nachricht ist erforderlich' });
    }

    // Optional: Alle Änderungen stagen
    if (stageAll !== false) {
      const stageResult = gitService.stageAll(SERVER_SOURCE_PATH);
      if (!stageResult.success) {
        return res.json(stageResult);
      }
    }

    // Autor aus eingeloggtem Benutzer
    const author = req.user ? {
      name: req.user.display_name || req.user.username,
      email: req.user.email || `${req.user.username.toLowerCase()}@taskmate.local`
    } : null;

    const result = gitService.commit(SERVER_SOURCE_PATH, message, author);
    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Commit:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/server/push
 * Push für Server-Dateien ausführen
 */
router.post('/server/push', (req, res) => {
  try {
    const { branch, force } = req.body;

    // Prüfe ob Remote existiert
    if (!gitService.hasRemote(SERVER_SOURCE_PATH)) {
      return res.json({
        success: false,
        error: 'Kein Remote konfiguriert'
      });
    }

    let result;
    if (force) {
      // Force Push
      result = gitService.pushWithUpstream(SERVER_SOURCE_PATH, branch || null, 'origin', true);
    } else {
      // Normaler Push
      result = gitService.pushChanges(SERVER_SOURCE_PATH, { branch });

      // Falls Push wegen fehlendem Upstream fehlschlägt, versuche mit -u
      if (!result.success && result.error && result.error.includes('no upstream')) {
        result = gitService.pushWithUpstream(SERVER_SOURCE_PATH, branch || null);
      }
    }

    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Push:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/server/pull
 * Pull für Server-Dateien ausführen
 */
router.post('/server/pull', (req, res) => {
  try {
    const { branch } = req.body;

    // Fetch zuerst
    gitService.fetchRemote(SERVER_SOURCE_PATH);

    // Dann Pull
    const result = gitService.pullChanges(SERVER_SOURCE_PATH, { branch });
    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Pull:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/server/fetch
 * Fetch für Server-Dateien ausführen
 */
router.post('/server/fetch', (req, res) => {
  try {
    const result = gitService.fetchRemote(SERVER_SOURCE_PATH);
    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Fetch:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * POST /api/git/server/checkout
 * Branch für Server-Dateien wechseln
 */
router.post('/server/checkout', (req, res) => {
  try {
    const { branch } = req.body;

    if (!branch) {
      return res.status(400).json({ error: 'Branch ist erforderlich' });
    }

    const result = gitService.checkoutBranch(SERVER_SOURCE_PATH, branch);
    res.json(result);
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Branch-Wechsel:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

/**
 * GET /api/git/server/info
 * Grundlegende Infos über Server-Repository
 */
router.get('/server/info', (req, res) => {
  try {
    const isAccessible = gitService.isPathAccessible(SERVER_SOURCE_PATH);
    const isRepo = isAccessible ? gitService.isGitRepository(SERVER_SOURCE_PATH) : false;
    const hasRemote = isRepo ? gitService.hasRemote(SERVER_SOURCE_PATH) : false;

    let remoteUrl = null;
    if (hasRemote) {
      const remoteResult = gitService.getRemoteUrl(SERVER_SOURCE_PATH);
      remoteUrl = remoteResult.url || null;
    }

    res.json({
      path: SERVER_SOURCE_PATH,
      hostPath: '/home/claude-dev/TaskMate',
      accessible: isAccessible,
      isRepository: isRepo,
      hasRemote: hasRemote,
      remoteUrl: remoteUrl
    });
  } catch (error) {
    logger.error('[Server-Git] Fehler beim Info-Abruf:', error);
    res.status(500).json({ error: 'Serverfehler' });
  }
});

// ============================================
// BROWSER-UPLOAD ENDPOINTS
// Für lokale Verzeichnis-Uploads vom Browser
// ============================================

/**
 * Hilfsfunktion: Verzeichnis rekursiv löschen
 */
function deleteFolderRecursive(dirPath) {
  if (fs.existsSync(dirPath)) {
    fs.readdirSync(dirPath).forEach((file) => {
      const curPath = path.join(dirPath, file);
      if (fs.lstatSync(curPath).isDirectory()) {
        deleteFolderRecursive(curPath);
      } else {
        fs.unlinkSync(curPath);
      }
    });
    fs.rmdirSync(dirPath);
  }
}

/**
 * POST /api/git/browser-upload
 * Empfängt Dateien vom Browser und pusht sie ins Gitea
 *
 * Body (multipart/form-data):
 * - files: Die hochgeladenen Dateien (originalname enthält relativen Pfad)
 * - repoUrl: Die Gitea-Repository-URL
 * - branch: Der Ziel-Branch (default: main)
 * - commitMessage: Die Commit-Nachricht
 * - sessionId: Eindeutige Session-ID für den Upload
 */
router.post('/browser-upload', gitUpload.array('files', 500), async (req, res) => {
  const sessionId = req.body.sessionId || Date.now().toString();
  const sessionDir = path.join(TEMP_UPLOAD_DIR, sessionId);

  try {
    const { repoUrl, branch = 'main', commitMessage } = req.body;
    const files = req.files;

    // Validierung
    if (!repoUrl) {
      return res.status(400).json({ error: 'Repository-URL ist erforderlich' });
    }

    if (!commitMessage) {
      return res.status(400).json({ error: 'Commit-Nachricht ist erforderlich' });
    }

    if (!files || files.length === 0) {
      return res.status(400).json({ error: 'Keine Dateien hochgeladen' });
    }

    logger.info(`[Browser-Upload] ${files.length} Dateien empfangen für ${repoUrl}`);

    // Git-Repository initialisieren
    const initResult = gitService.initRepository(sessionDir);
    if (!initResult.success) {
      throw new Error('Git-Initialisierung fehlgeschlagen: ' + initResult.error);
    }

    // Remote hinzufügen
    const remoteResult = gitService.addRemote(sessionDir, repoUrl, 'origin');
    if (!remoteResult.success) {
      throw new Error('Remote hinzufügen fehlgeschlagen: ' + remoteResult.error);
    }

    // Autor aus eingeloggtem Benutzer
    const author = req.user ? {
      name: req.user.display_name || req.user.username,
      email: req.user.email || `${req.user.username.toLowerCase()}@taskmate.local`
    } : null;

    // Alle Dateien stagen
    const stageResult = gitService.stageAll(sessionDir);
    if (!stageResult.success) {
      throw new Error('Staging fehlgeschlagen: ' + stageResult.error);
    }

    // Commit erstellen
    const commitResult = gitService.commit(sessionDir, commitMessage, author);
    if (!commitResult.success) {
      throw new Error('Commit fehlgeschlagen: ' + commitResult.error);
    }

    // Push mit Upstream
    const pushResult = gitService.pushWithUpstream(sessionDir, branch, 'origin', false);
    if (!pushResult.success) {
      // Bei Fehler: Versuche Force-Push falls Branch existiert
      if (pushResult.error && pushResult.error.includes('rejected')) {
        logger.warn('[Browser-Upload] Normaler Push abgelehnt, versuche mit Force...');
        const forcePushResult = gitService.pushWithUpstream(sessionDir, branch, 'origin', true);
        if (!forcePushResult.success) {
          throw new Error('Push fehlgeschlagen: ' + forcePushResult.error);
        }
      } else {
        throw new Error('Push fehlgeschlagen: ' + pushResult.error);
      }
    }

    logger.info(`[Browser-Upload] Erfolgreich nach ${repoUrl}/${branch} gepusht`);

    // Erfolgreich - Aufräumen
    deleteFolderRecursive(sessionDir);

    res.json({
      success: true,
      message: `${files.length} Dateien erfolgreich nach ${branch} gepusht`,
      filesCount: files.length,
      branch: branch,
      commit: commitResult.hash || null
    });

  } catch (error) {
    logger.error('[Browser-Upload] Fehler:', error);

    // Bei Fehler aufräumen
    try {
      deleteFolderRecursive(sessionDir);
    } catch (cleanupError) {
      logger.warn('[Browser-Upload] Aufräumen fehlgeschlagen:', cleanupError);
    }

    res.status(500).json({
      success: false,
      error: error.message || 'Upload fehlgeschlagen'
    });
  }
});

/**
 * POST /api/git/browser-upload-prepare
 * Bereitet einen Upload vor und gibt eine Session-ID zurück
 */
router.post('/browser-upload-prepare', (req, res) => {
  const sessionId = `upload_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  const sessionDir = path.join(TEMP_UPLOAD_DIR, sessionId);

  try {
    fs.mkdirSync(sessionDir, { recursive: true });

    res.json({
      success: true,
      sessionId: sessionId,
      maxFileSize: 50 * 1024 * 1024, // 50MB
      maxFiles: 500
    });
  } catch (error) {
    logger.error('[Browser-Upload] Prepare fehlgeschlagen:', error);
    res.status(500).json({ error: 'Vorbereitung fehlgeschlagen' });
  }
});

/**
 * DELETE /api/git/browser-upload/:sessionId
 * Löscht eine Upload-Session (für Abbruch)
 */
router.delete('/browser-upload/:sessionId', (req, res) => {
  const { sessionId } = req.params;
  const sessionDir = path.join(TEMP_UPLOAD_DIR, sessionId);

  try {
    if (fs.existsSync(sessionDir)) {
      deleteFolderRecursive(sessionDir);
    }

    res.json({ success: true });
  } catch (error) {
    logger.error('[Browser-Upload] Löschen fehlgeschlagen:', error);
    res.status(500).json({ error: 'Löschen fehlgeschlagen' });
  }
});

module.exports = router;
