const pool = require('../config/db'); const cheerio = require('cheerio'); const { logActivity } = require('../services/activityLog'); const MONTHS_FR = { 'janv': '01', 'janvier': '01', 'févr': '02', 'février': '02', 'fevrier': '02', 'mars': '03', 'avr': '04', 'avril': '04', 'mai': '05', 'juin': '06', 'juil': '07', 'juillet': '07', 'août': '08', 'aout': '08', 'sept': '09', 'septembre': '09', 'oct': '10', 'octobre': '10', 'nov': '11', 'novembre': '11', 'déc': '12', 'décembre': '12', 'decembre': '12' }; function parseFrenchDate(str) { const m = str.trim().match(/^(\d+)\s+(\S+)\s+(\d{4})$/); if (!m) return null; const month = MONTHS_FR[m[2].toLowerCase().replace(/\.$/, '')]; if (!month) return null; return `${m[3]}-${month}-${m[1].padStart(2, '0')}`; } exports.list = async (req, res) => { try { const [rows] = await pool.query('SELECT * FROM evenements ORDER BY date ASC'); res.json(rows); } catch (err) { console.error(err); res.status(500).json({ error: 'Server error' }); } }; exports.create = async (req, res) => { try { const { date, nom_evenement, lieu, horaire } = req.body; if (!date || !nom_evenement) { return res.status(400).json({ error: 'Date and name required' }); } const [result] = await pool.query( 'INSERT INTO evenements (date, nom_evenement, lieu, horaire) VALUES (?, ?, ?, ?)', [date, nom_evenement, lieu || null, horaire || null] ); res.status(201).json({ id: result.insertId, message: 'Event created' }); logActivity(req, 'evenement_ajout', { date, nom_evenement }); } catch (err) { console.error(err); res.status(500).json({ error: 'Server error' }); } }; exports.update = async (req, res) => { try { const { date, nom_evenement, lieu, horaire } = req.body; await pool.query( 'UPDATE evenements SET date = ?, nom_evenement = ?, lieu = ?, horaire = ? WHERE id = ?', [date, nom_evenement, lieu || null, horaire || null, req.params.id] ); res.json({ message: 'Updated' }); logActivity(req, 'evenement_modification', { id: req.params.id, date, nom_evenement }); } catch (err) { console.error(err); res.status(500).json({ error: 'Server error' }); } }; exports.remove = async (req, res) => { try { await pool.query('DELETE FROM evenements WHERE id = ?', [req.params.id]); res.json({ message: 'Deleted' }); logActivity(req, 'evenement_suppression', { id: req.params.id }); } catch (err) { console.error(err); res.status(500).json({ error: 'Server error' }); } }; exports.deletePast = async (req, res) => { try { const [result] = await pool.query('DELETE FROM evenements WHERE date < CURDATE()'); res.json({ message: `${result.affectedRows} événement(s) supprimé(s)` }); logActivity(req, 'evenements_passes_supprimes', { count: result.affectedRows }); } catch (err) { console.error(err); res.status(500).json({ error: 'Server error' }); } }; exports.scrape = async (req, res) => { try { const url = 'https://www.rencontres-dirigeants.com/nos-rencontres?region=11&startAt=&endAt=&dateRange=&format=&agency%5B%5D=289&department='; const resp = await fetch(url); const html = await resp.text(); const $ = cheerio.load(html); const candidates = []; $('article, [class*="card"], [class*="event"], [class*="rencontre"]').each((i, el) => { const text = $(el).text(); const lines = text.split('\n').map(l => l.trim()).filter(Boolean); let location = '', dateStr = '', timeStr = ''; for (const line of lines) { if (!location && line.length > 3 && line[0] === line[0].toUpperCase() && !line.includes('€') && !line.includes('Participation') && !line.includes('places')) { location = line; } const dateMatch = line.match(/(\d{1,2}\s+\S+\s+\d{4})/); if (dateMatch && !dateStr) dateStr = dateMatch[1]; const timeMatch = line.match(/(\d{2}h\d{2})\s*[àa]\s*(\d{2}h\d{2})/); if (timeMatch && !timeStr) timeStr = `${timeMatch[1]} - ${timeMatch[2]}`; } if (!dateStr) return; const isoDate = parseFrenchDate(dateStr); if (!isoDate) return; candidates.push({ isoDate, location, timeStr }); }); const imported = []; for (const c of candidates) { const [existing] = await pool.query('SELECT id FROM evenements WHERE date = ? AND nom_evenement LIKE ?', [c.isoDate, `%Rencontre%`]); if (existing.length > 0) continue; const title = c.location ? `Rencontre dirigeants - ${c.location}` : 'Rencontre dirigeants Dynabuy'; await pool.query( 'INSERT INTO evenements (date, nom_evenement, lieu, horaire) VALUES (?, ?, ?, ?)', [c.isoDate, title, c.location || null, c.timeStr || null] ); imported.push({ date: c.isoDate, title, location: c.location, time: c.timeStr }); } res.json({ message: `${imported.length} événement(s) importé(s)`, events: imported }); } catch (err) { console.error(err); res.status(500).json({ error: 'Erreur lors de l\'import: ' + err.message }); } };