const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const cookieParser = require('cookie-parser');
const morgan = require('morgan');
const path = require('path');
const cron = require('node-cron');
const http = require('http');
const WebSocket = require('ws');

const config = require('./config');
const { initAuth } = require('./auth');
const routes = require('./routes');
const webhookRoutes = require('./webhook');
const { checkAllApps, getAllStatuses } = require('./healthcheck');
const { getCommits } = require('./gitea');
const { initDynamicApps } = require('./app-creator');

const app = express();
const server = http.createServer(app);

// WebSocket server pour les mises à jour en temps réel
const wss = new WebSocket.Server({ server, path: '/ws' });

// Middleware
app.use(helmet({
  contentSecurityPolicy: false,
  crossOriginEmbedderPolicy: false,
}));
app.use(cors({
  origin: true,
  credentials: true,
}));
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ extended: true, limit: '50mb' }));
app.use(cookieParser());
app.use(morgan('combined'));

// Route webhook montée en premier avec raw body pour la vérification HMAC
app.use('/api/webhook', express.raw({ type: 'application/json', limit: '10mb' }), (req, res, next) => {
  if (req.body && Buffer.isBuffer(req.body)) {
    req.rawBody = req.body;
    try { req.body = JSON.parse(req.body.toString()); } catch(e) { req.body = {}; }
  }
  next();
}, webhookRoutes);
// API routes
app.use('/api', routes);

// Servir le frontend en production
const frontendPath = path.join(__dirname, '../../frontend/dist');
app.use(express.static(frontendPath));

// SPA fallback
app.get('*', (req, res) => {
  if (!req.path.startsWith('/api') && !req.path.startsWith('/ws')) {
    res.sendFile(path.join(frontendPath, 'index.html'));
  }
});

// Broadcast WebSocket message
global.wsBroadcast = broadcast;
function broadcast(data) {
  const message = JSON.stringify(data);
  wss.clients.forEach((client) => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(message);
    }
  });
}

// Health check périodique
async function runHealthChecks() {
  try {
    const results = await checkAllApps();
    broadcast({ type: 'health_update', data: results });

    // Vérifier les nouveaux commits Gitea
    for (const appConfig of config.apps) {
      try {
        const commits = await getCommits(appConfig.giteaOwner, appConfig.giteaRepo, 5);
        if (commits.length > 0) {
          broadcast({
            type: 'gitea_commits',
            data: { appId: appConfig.id, commits },
          });
        }
      } catch (e) {
        // Ignorer les erreurs Gitea
      }
    }
  } catch (err) {
    console.error('Erreur health check:', err.message);
  }
}

// Démarrage
async function start() {
  await initAuth();

  // Charger les applications dynamiques
  initDynamicApps();

  // Premier health check
  setTimeout(runHealthChecks, 2000);

  // Health check toutes les 30 secondes
  setInterval(runHealthChecks, config.healthCheckInterval);

  server.listen(config.port, '0.0.0.0', () => {
    console.log(`Manus Dashboard Backend démarré sur le port ${config.port}`);
    console.log(`Frontend servi depuis: ${frontendPath}`);
  });
}

// WebSocket connection handler
wss.on('connection', (ws) => {
  console.log('Nouvelle connexion WebSocket');

  // Envoyer les statuts actuels
  const statuses = getAllStatuses();
  if (statuses.length > 0) {
    ws.send(JSON.stringify({ type: 'health_update', data: statuses }));
  }

  ws.on('close', () => {
    console.log('Connexion WebSocket fermée');
  });
});

start().catch((err) => {
  console.error('Erreur au démarrage:', err);
  process.exit(1);
});
