const { ContactPerson, Position, Event, EventType, EventPlace } = require('../models');
const { Op } = require('sequelize');

const getAllContactPersons = async (req, res) => {
  try {
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    
    const contactPersons = await ContactPerson.findAll({
      where: {
        [Op.or]: [
          { expiryDate: null },
          { expiryDate: { [Op.gte]: today } }
        ]
      },
      include: [
        {
          model: Position,
          as: 'positions',
          through: { attributes: [] }
        }
      ],
      order: ['name']
    });
    res.json(contactPersons);
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch contact persons' });
    console.error(error);
  }
};

const createContactPerson = async (req, res) => {
  try {
    const { positions, ...contactPersonData } = req.body;
    const contactPerson = await ContactPerson.create(contactPersonData);
    if (positions && positions.length > 0) {
      const positionIds = positions.map(position => position.id);
      await contactPerson.setPositions(positionIds);
    }
    res.status(201).json(contactPerson);
  } catch (error) {
    res.status(500).json({ error: 'Failed to create contact person' });
    console.error(error);
  }
};

const updateContactPerson = async (req, res) => {
  try {
    const { id } = req.params;
    const { positions, ...contactPersonData } = req.body;
    const contactPerson = await ContactPerson.findByPk(id);
    if (!contactPerson) {
      return res.status(404).json({ error: 'Contact person not found' });
    }
    await contactPerson.update(contactPersonData);
    if (positions && positions.length > 0) {
      const positionIds = positions.map(position => position.id);
      await contactPerson.setPositions(positionIds);
    }
    res.status(200).json(contactPerson);
  } catch (error) {
    res.status(500).json({ error: 'Failed to update contact person' });
    console.error(error);
  }
};

const deleteContactPerson = async (req, res) => {
  try {
    const { id } = req.params;
    const deleted = await ContactPerson.destroy({
      where: { id: id }
    });
    if (deleted) {
      res.status(204).json();
    } else {
      res.status(404).json({ error: 'Contact person not found' });
    }
  } catch (error) {
    res.status(500).json({ error: 'Failed to delete contact person' });
    console.error(error);
  }
};

const filterContactPersons = async (req, res) => {
  try {
    const { config: configString } = req.body;
    const config = JSON.parse(configString);
    const where = {};
    const having = [];

    // Filter für nicht abgelaufene Kontaktpersonen
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    where[Op.or] = [
      { expiryDate: null },
      { expiryDate: { [Op.gte]: today } }
    ];

    if (config.selection.id && config.selection.id === 'all') {
      // No additional filter needed for "all"
    } else if (config.selection.id) {
      where.id = config.selection.id;
    } else {
      if (config.selection.types && config.selection.types.length > 0) {
        having.push({ '$positions.id$': { [Op.in]: config.selection.types } });
      }

      if (config.selection.places && config.selection.places.length > 0) {
        having.push({ '$events.eventPlaceId$': { [Op.in]: config.selection.places } });
      }

      if (config.selection.positions && config.selection.positions.length > 0) {
        having.push({ '$positions.id$': { [Op.in]: config.selection.positions } });
      }
    }

    const contactPersons = await ContactPerson.findAll({
      where,
      include: [
        {
          model: Position,
          as: 'positions',
          through: { attributes: [] },
          required: true, // Ensure only contact persons with matching positions are included
        },
        {
          model: Event,
          as: 'events',
          through: { attributes: [] },
          required: false,
        },
      ],
      having: having.length > 0 ? { [Op.and]: having } : undefined,
      order: ['name']
    });

    res.json(contactPersons);
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch contact persons' });
    console.error(error);
  }
};

module.exports = {
  getAllContactPersons,
  createContactPerson,
  updateContactPerson,
  deleteContactPerson,
  filterContactPersons
};
