import db from '../db/index.js';

const JOB_NAME = 'auto_statut_retard';

/** Persiste une entrée dans job_logs */
function writeLog({ status, nbChanges, details, errorMsg }) {
  try {
    db.prepare(`
      INSERT INTO job_logs (job_name, status, nb_changes, details, error_msg)
      VALUES (?, ?, ?, ?, ?)
    `).run(JOB_NAME, status, nbChanges ?? 0, details ?? null, errorMsg ?? null);
  } catch (e) {
    console.error('[autoStatut] Impossible d\'écrire dans job_logs :', e.message);
  }
}

/**
 * Passe automatiquement au statut "en_retard" les investissements dont :
 *   - le statut est actuellement "en_cours"
 *   - la date_cible est renseignée et strictement antérieure à aujourd'hui
 *
 * Chaque passage est tracé dans investissement_historique avec le
 * type_evenement 'passage_auto_retard' pour conserver l'auditabilité.
 *
 * @returns {number} nombre d'investissements mis à jour
 */
export function checkStatutsRetard() {
  const candidats = db.prepare(`
    SELECT id, nom_projet, date_cible
    FROM investissements
    WHERE statut = 'en_cours'
      AND date_cible IS NOT NULL
      AND date_cible < date('now')
  `).all();

  if (candidats.length === 0) {
    writeLog({ status: 'ok', nbChanges: 0, details: 'Aucun investissement en retard détecté' });
    return 0;
  }

  const updateStmt = db.prepare(`
    UPDATE investissements
    SET statut = 'en_retard', updated_at = datetime('now')
    WHERE id = ?
  `);

  const histStmt = db.prepare(`
    INSERT INTO investissement_historique
      (investissement_id, type_evenement, changements, notes)
    VALUES (?, 'passage_auto_retard', ?, ?)
  `);

  const tx = db.transaction(() => {
    for (const inv of candidats) {
      updateStmt.run(inv.id);
      histStmt.run(
        inv.id,
        JSON.stringify([{
          champ:           'statut',
          label:           'Statut',
          ancienne_valeur: 'en_cours',
          nouvelle_valeur: 'en_retard',
        }]),
        `Passage automatique : date cible (${inv.date_cible}) dépassée`
      );
    }
  });
  tx();

  const details = candidats
    .map(i => `"${i.nom_projet}" (id=${i.id}, date_cible=${i.date_cible})`)
    .join('; ');

  writeLog({
    status: 'ok',
    nbChanges: candidats.length,
    details: `Passé en retard : ${details}`,
  });

  console.log(`[autoStatut] ${candidats.length} investissement(s) passé(s) en retard : ${details}`);
  return candidats.length;
}

/**
 * Démarre le job de vérification automatique des statuts.
 *
 * - Exécution immédiate au démarrage (rattrape les retards accumulés
 *   pendant que le serveur était éteint).
 * - Puis répétition quotidienne, calée sur la prochaine minuit locale
 *   afin de ne pas dériver au fil des redémarrages.
 */
export function startAutoStatutJob() {
  // Exécution initiale
  try {
    checkStatutsRetard();
  } catch (err) {
    console.error('[autoStatut] Erreur lors de la vérification initiale :', err);
    writeLog({ status: 'error', nbChanges: 0, errorMsg: err.message });
  }

  // Calcule le délai jusqu'à la prochaine minuit locale
  function msUntilMidnight() {
    const now  = new Date();
    const next = new Date(now);
    next.setHours(24, 0, 0, 0);
    return next.getTime() - now.getTime();
  }

  // Planifie la première échéance à minuit, puis toutes les 24h (sans dérive)
  function scheduleDailyRun() {
    setTimeout(() => {
      try {
        checkStatutsRetard();
      } catch (err) {
        console.error('[autoStatut] Erreur lors de la vérification quotidienne :', err);
        writeLog({ status: 'error', nbChanges: 0, errorMsg: err.message });
      }
      scheduleDailyRun();
    }, msUntilMidnight());
  }

  scheduleDailyRun();
  console.log(`[autoStatut] Job démarré — prochaine vérification dans ${Math.round(msUntilMidnight() / 60000)} min (minuit)`);
}
