const database = require('../config/database');
const { Op } = require('sequelize');

/**
 * Service-Klasse für Zeitwünsche (Timewish)
 * Verwaltet gewünschte Arbeitszeiten pro Wochentag und Zeitraum
 */
class TimewishService {
  /**
   * Holt alle Zeitwünsche eines Users
   * @param {number} userId - Benutzer-ID
   * @returns {Promise<Array>} Array von Zeitwünschen
   */
  async getAllTimewishes(userId) {
    const { Timewish } = database.getModels();
    
    const timewishes = await Timewish.findAll({
      where: {
        user_id: userId
      },
      order: [['day', 'ASC'], ['start_date', 'DESC']],
      raw: true
    });
    
    // Konvertiere DB-Format zu Frontend-Format
    const dayNames = {
      1: 'Montag',
      2: 'Dienstag',
      3: 'Mittwoch',
      4: 'Donnerstag',
      5: 'Freitag',
      6: 'Samstag',
      7: 'Sonntag'
    };
    
    const wishtypeNames = {
      0: 'Kein Wunsch',
      1: 'Frei',
      2: 'Arbeit'
    };
    
    return timewishes.map(tw => ({
      id: tw.id,
      day: tw.day,
      dayName: dayNames[tw.day] || `Tag ${tw.day}`,
      wishtype: tw.wishtype,
      wishtypeName: wishtypeNames[tw.wishtype] || 'Unbekannt',
      hours: tw.hours,
      startDate: tw.start_date,
      endDate: tw.end_date
    }));
  }

  /**
   * Erstellt einen neuen Zeitwunsch
   * @param {number} userId - Benutzer-ID
   * @param {number} day - Wochentag (1=Mo, 7=So)
   * @param {number} wishtype - Typ (0=Kein Wunsch, 1=Frei, 2=Arbeit)
   * @param {number} hours - Stunden (nur bei wishtype=2)
   * @param {string} startDate - Startdatum (YYYY-MM-DD)
   * @param {string} endDate - Enddatum (YYYY-MM-DD, optional)
   * @returns {Promise<Object>} Erstellter Zeitwunsch
   */
  async createTimewish(userId, day, wishtype, hours, startDate, endDate) {
    const { Timewish } = database.getModels();
    
    // Validierung
    if (day < 1 || day > 7) {
      throw new Error('Wochentag muss zwischen 1 (Montag) und 7 (Sonntag) liegen');
    }
    
    if (wishtype < 0 || wishtype > 2) {
      throw new Error('Ungültiger Wunschtyp');
    }
    
    if (wishtype === 2 && (!hours || hours < 0 || hours > 24)) {
      throw new Error('Arbeitsstunden müssen zwischen 0 und 24 liegen');
    }
    
    if (!startDate) {
      throw new Error('Startdatum ist erforderlich');
    }
    
    // Prüfe auf Überschneidungen
    const overlapping = await Timewish.findOne({
      where: {
        user_id: userId,
        day: day,
        [Op.or]: [
          // Fall 1: Neuer Eintrag hat kein Enddatum (gilt ab start_date)
          endDate ? {} : {
            [Op.or]: [
              // Bestehender Eintrag hat kein Enddatum UND start_date <= neuer start_date
              {
                end_date: null,
                start_date: { [Op.lte]: startDate }
              },
              // Bestehender Eintrag hat Enddatum UND überlappt
              {
                end_date: { [Op.gte]: startDate }
              }
            ]
          },
          // Fall 2: Neuer Eintrag hat Enddatum
          endDate ? {
            [Op.or]: [
              // Bestehender Eintrag hat kein Enddatum UND start_date <= neues end_date
              {
                end_date: null,
                start_date: { [Op.lte]: endDate }
              },
              // Bestehender Eintrag hat Enddatum UND überlappt
              {
                start_date: { [Op.lte]: endDate },
                end_date: { [Op.gte]: startDate }
              }
            ]
          } : {}
        ]
      }
    });
    
    if (overlapping) {
      throw new Error(`Überschneidung mit bestehendem Zeitwunsch: ${overlapping.start_date} - ${overlapping.end_date || 'unbegrenzt'}`);
    }
    
    const timewish = await Timewish.create({
      user_id: userId,
      day,
      wishtype,
      hours: wishtype === 2 ? hours : null,
      start_date: startDate,
      end_date: endDate || null,
      version: 0
    });
    
    // Formatiere für Response
    const allTimewishes = await this.getAllTimewishes(userId);
    return allTimewishes.find(tw => tw.id === timewish.id);
  }

  /**
   * Löscht einen Zeitwunsch
   * @param {number} userId - Benutzer-ID
   * @param {number} timewishId - Timewish-ID
   * @returns {Promise<void>}
   */
  async deleteTimewish(userId, timewishId) {
    const { Timewish } = database.getModels();
    
    const timewish = await Timewish.findByPk(timewishId);
    
    if (!timewish) {
      throw new Error('Zeitwunsch nicht gefunden');
    }
    
    // Prüfe Berechtigung
    if (timewish.user_id !== userId) {
      throw new Error('Keine Berechtigung für diesen Eintrag');
    }
    
    await timewish.destroy();
  }
}

module.exports = new TimewishService();

