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

const JOB_NAME = 'auto_ticket_status';

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('[autoTicketStatus] Impossible d\'écrire dans job_logs :', e.message);
  }
}

/**
 * Règles appliquées :
 *
 * 1. open → pending
 *    Ticket ouvert sans aucun message depuis plus de 2 jours.
 *    (updated_at sert d'horodatage de la dernière activité)
 *
 * 2. pending → resolved  (clôture automatique)
 *    Ticket en attente où le créateur du ticket n'a pas posté de message
 *    depuis plus de 5 jours.
 *    On cherche le dernier message de l'émetteur (is_admin = 0 et user_id = ticket.user_id).
 *    Si ce message date de plus de 5 jours, le ticket est clôturé.
 */
export function checkTicketStatuses() {
  let nbChanges = 0;
  const details = [];

  // ── Règle 1 : open → pending (pas de réponse depuis 2 jours) ─────────────
  const toPending = db.prepare(`
    SELECT id, ticket_number, subject, updated_at
    FROM tickets
    WHERE status = 'open'
      AND datetime(updated_at) < datetime('now', '-2 days')
  `).all();

  const setPending = db.prepare(`
    UPDATE tickets SET status = 'pending', updated_at = datetime('now') WHERE id = ?
  `);

  const notifyUserPending = db.prepare(`
    INSERT INTO notifications (user_id, type, title, body, link)
    SELECT user_id, 'ticket_reply',
      '[' || ticket_number || '] Ticket mis en attente',
      'Votre ticket "' || subject || '" est passé en attente faute de réponse depuis 2 jours.',
      '/communication?ticket=' || id
    FROM tickets WHERE id = ?
  `);

  for (const t of toPending) {
    setPending.run(t.id);
    try { notifyUserPending.run(t.id); } catch (_) { /* best-effort */ }
    details.push(`[pending] ${t.ticket_number} (id=${t.id})`);
    nbChanges++;
  }

  // ── Règle 2 : pending → resolved (pas de réponse créateur depuis 5 jours) ─
  const pendingTickets = db.prepare(`
    SELECT id, ticket_number, subject, user_id
    FROM tickets
    WHERE status = 'pending'
  `).all();

  const lastCreatorMsg = db.prepare(`
    SELECT MAX(created_at) as last_at
    FROM ticket_messages
    WHERE ticket_id = ? AND user_id = ? AND is_admin = 0
  `);

  const setResolved = db.prepare(`
    UPDATE tickets SET status = 'resolved', updated_at = datetime('now') WHERE id = ?
  `);

  const notifyUserResolved = db.prepare(`
    INSERT INTO notifications (user_id, type, title, body, link)
    SELECT user_id, 'ticket_reply',
      '[' || ticket_number || '] Ticket clôturé automatiquement',
      'Votre ticket "' || subject || '" a été clôturé automatiquement après 5 jours sans réponse.',
      '/communication?ticket=' || id
    FROM tickets WHERE id = ?
  `);

  for (const t of pendingTickets) {
    const row = lastCreatorMsg.get(t.id, t.user_id);
    // Si jamais de message créateur, on prend la date de création du ticket (updated_at)
    const refDate = row?.last_at ?? null;
    if (!refDate) continue; // pas de message créateur trouvé, on ne clôture pas

    const ageDays = (Date.now() - new Date(refDate + 'Z').getTime()) / (1000 * 60 * 60 * 24);
    if (ageDays > 5) {
      setResolved.run(t.id);
      try { notifyUserResolved.run(t.id); } catch (_) { /* best-effort */ }
      details.push(`[resolved] ${t.ticket_number} (id=${t.id}, last_creator_msg=${refDate})`);
      nbChanges++;
    }
  }

  const summary = nbChanges === 0
    ? 'Aucun ticket modifié'
    : details.join('; ');

  writeLog({ status: 'ok', nbChanges, details: summary });
  if (nbChanges > 0) {
    console.log(`[autoTicketStatus] ${nbChanges} ticket(s) mis à jour : ${summary}`);
  }
  return nbChanges;
}

/**
 * Démarre le job — exécution immédiate au démarrage, puis toutes les heures.
 */
export function startAutoTicketStatusJob() {
  const INTERVAL_MS = 60 * 60 * 1000; // 1 heure

  try {
    checkTicketStatuses();
  } catch (err) {
    console.error('[autoTicketStatus] Erreur initiale :', err);
    writeLog({ status: 'error', nbChanges: 0, errorMsg: err.message });
  }

  setInterval(() => {
    try {
      checkTicketStatuses();
    } catch (err) {
      console.error('[autoTicketStatus] Erreur :', err);
      writeLog({ status: 'error', nbChanges: 0, errorMsg: err.message });
    }
  }, INTERVAL_MS);

  console.log('[autoTicketStatus] Job démarré — vérification toutes les heures');
}
