/**
 * TASKMATE - Reminder Service
 * ===========================
 * Service für Erinnerungsbenachrichtigungen und Scheduling
 */

const { getDb } = require('../database');
const notificationService = require('./notificationService');
const logger = require('../utils/logger');

class ReminderService {
  constructor(io = null) {
    this.io = io;
    this.intervalId = null;
    this.isRunning = false;
  }

  /**
   * Startet den Reminder-Check-Service
   * Läuft alle 5 Minuten (kann für Produktion auf 1 Stunde erhöht werden)
   */
  start() {
    if (this.isRunning) {
      logger.warn('Reminder Service ist bereits gestartet');
      return;
    }

    this.isRunning = true;
    
    // Sofort prüfen
    this.checkDueReminders();
    
    // Dann alle 5 Minuten (300000 ms)
    // In Produktion könnte das auf 1 Stunde (3600000 ms) erhöht werden
    this.intervalId = setInterval(() => {
      this.checkDueReminders();
    }, 300000); // 5 Minuten

    logger.info('Reminder Service gestartet - prüft alle 5 Minuten');
  }

  /**
   * Stoppt den Reminder-Check-Service
   */
  stop() {
    if (!this.isRunning) {
      return;
    }

    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }

    this.isRunning = false;
    logger.info('Reminder Service gestoppt');
  }

  /**
   * Prüft fällige Erinnerungen und sendet Benachrichtigungen
   */
  async checkDueReminders() {
    try {
      const db = getDb();
      const today = new Date().toISOString().split('T')[0];

      // Finde alle fälligen Benachrichtigungen die noch nicht gesendet wurden
      const dueNotifications = db.prepare(`
        SELECT 
          rn.*,
          r.id as reminder_id,
          r.title as reminder_title,
          r.description as reminder_description,
          r.reminder_date,
          r.reminder_time,
          r.color,
          r.project_id,
          r.created_by,
          r.advance_days
        FROM reminder_notifications rn
        JOIN reminders r ON rn.reminder_id = r.id
        WHERE rn.notification_date <= ? 
          AND rn.sent = 0 
          AND r.is_active = 1
        ORDER BY rn.notification_date ASC, r.reminder_time ASC
      `).all(today);

      if (dueNotifications.length === 0) {
        logger.debug('Keine fälligen Erinnerungen gefunden');
        return;
      }

      logger.info(`${dueNotifications.length} fällige Erinnerung(en) gefunden`);

      // Verarbeite jede fällige Benachrichtigung
      for (const notification of dueNotifications) {
        await this.processReminderNotification(notification);
      }

    } catch (error) {
      logger.error('Fehler beim Prüfen fälliger Erinnerungen:', error);
    }
  }

  /**
   * Verarbeitet eine einzelne fällige Erinnerungs-Benachrichtigung
   */
  async processReminderNotification(notification) {
    try {
      const db = getDb();

      // Berechne wie viele Tage im Voraus diese Benachrichtigung ist
      const reminderDate = new Date(notification.reminder_date);
      const notificationDate = new Date(notification.notification_date);
      const daysDiff = Math.ceil((reminderDate - notificationDate) / (1000 * 60 * 60 * 24));

      const reminder = {
        id: notification.reminder_id,
        title: notification.reminder_title,
        description: notification.reminder_description,
        project_id: notification.project_id,
        created_by: notification.created_by,
        color: notification.color
      };

      // Erstelle Benachrichtigung
      const createdNotification = notificationService.createReminderNotification(
        reminder, 
        daysDiff, 
        this.io
      );

      if (createdNotification) {
        // Markiere als gesendet
        db.prepare(`
          UPDATE reminder_notifications 
          SET sent = 1 
          WHERE id = ?
        `).run(notification.id);

        logger.info(`Reminder-Benachrichtigung gesendet: "${notification.reminder_title}" (${daysDiff} Tage vorher)`);
      }

    } catch (error) {
      logger.error(`Fehler beim Verarbeiten der Reminder-Benachrichtigung ${notification.id}:`, error);
    }
  }

  /**
   * Erstellt Benachrichtigungstermine für eine neue Erinnerung
   */
  createNotificationSchedule(reminderId, reminderDate, advanceDays) {
    try {
      const db = getDb();
      const baseDate = new Date(reminderDate);

      // Lösche alte Termine falls vorhanden
      db.prepare('DELETE FROM reminder_notifications WHERE reminder_id = ?').run(reminderId);

      // Erstelle neue Termine für jeden advance day
      advanceDays.forEach(days => {
        const notificationDate = new Date(baseDate);
        notificationDate.setDate(notificationDate.getDate() - parseInt(days));
        
        const notificationDateStr = notificationDate.toISOString().split('T')[0];
        
        // Nur zukünftige Termine erstellen
        const today = new Date().toISOString().split('T')[0];
        if (notificationDateStr >= today) {
          db.prepare(`
            INSERT OR IGNORE INTO reminder_notifications (reminder_id, notification_date)
            VALUES (?, ?)
          `).run(reminderId, notificationDateStr);
        }
      });

      logger.debug(`Benachrichtigungstermine erstellt für Reminder ${reminderId}`);
    } catch (error) {
      logger.error(`Fehler beim Erstellen der Benachrichtigungstermine für Reminder ${reminderId}:`, error);
    }
  }

  /**
   * Manuelle Prüfung für API-Endpoint
   */
  async manualCheck() {
    logger.info('Manuelle Reminder-Prüfung ausgelöst');
    return await this.checkDueReminders();
  }

  /**
   * Statistiken für Debugging
   */
  getStats() {
    try {
      const db = getDb();
      
      const stats = {
        isRunning: this.isRunning,
        activeReminders: db.prepare('SELECT COUNT(*) as count FROM reminders WHERE is_active = 1').get().count,
        pendingNotifications: db.prepare('SELECT COUNT(*) as count FROM reminder_notifications WHERE sent = 0').get().count,
        nextDueDate: db.prepare(`
          SELECT MIN(notification_date) as next_date 
          FROM reminder_notifications 
          WHERE sent = 0 AND notification_date >= date('now')
        `).get().next_date
      };

      return stats;
    } catch (error) {
      logger.error('Fehler beim Abrufen der Reminder-Statistiken:', error);
      return { error: error.message };
    }
  }

  /**
   * Socket.io Instanz setzen/aktualisieren
   */
  setSocketIO(io) {
    this.io = io;
    logger.debug('Socket.IO Instanz für Reminder Service aktualisiert');
  }
}

// Singleton Export
let instance = null;

module.exports = {
  getInstance(io = null) {
    if (!instance) {
      instance = new ReminderService(io);
    } else if (io) {
      instance.setSocketIO(io);
    }
    return instance;
  },
  
  // Für Tests und Debugging
  createInstance(io = null) {
    return new ReminderService(io);
  }
};