const { Op } = require('sequelize');

// Construir opciones de query con filtros, búsqueda y ordenamiento
const buildQueryOptions = (params) => {
  const {
    search,
    searchFields = [],
    sortBy = 'id',
    sortOrder = 'DESC',
    ...filters
  } = params;
  const queryOptions = {
    order: [[sortBy, sortOrder.toUpperCase()]]
  };

  // Construir condiciones WHERE
  const whereConditions = {};

  // Agregar búsqueda si existe
  if (search && searchFields.length > 0) {
    const searchConditions = searchFields.map(field => ({
      [field]: {
        [Op.like]: `%${search}%`
      }
    }));

    whereConditions[Op.or] = searchConditions;
  }

  // Agregar filtros adicionales
  Object.keys(filters).forEach(key => {
    if (filters[key] !== undefined && filters[key] !== null && filters[key] !== '') {
      // Si el filtro es un array, usar Op.in
      if (Array.isArray(filters[key])) {
        whereConditions[key] = {
          [Op.in]: filters[key]
        };
      } else {
        whereConditions[key] = filters[key];
      }
    }
  });

  // Solo agregar where si hay condiciones
  if (Object.keys(whereConditions).length > 0) {
    queryOptions.where = whereConditions;
  }

  return queryOptions;
};

// Construir filtros de rango de fechas
const buildDateRangeFilter = (startDate, endDate, fieldName = 'createdAt') => {
  const dateFilter = {};

  if (startDate && endDate) {
    dateFilter[fieldName] = {
      [Op.between]: [new Date(startDate), new Date(endDate)]
    };
  } else if (startDate) {
    dateFilter[fieldName] = {
      [Op.gte]: new Date(startDate)
    };
  } else if (endDate) {
    dateFilter[fieldName] = {
      [Op.lte]: new Date(endDate)
    };
  }

  return dateFilter;
};

// Construir filtros numéricos
const buildNumericFilter = (value, operator = 'eq', fieldName) => {
  const numericFilter = {};

  switch (operator) {
    case 'gt':
      numericFilter[fieldName] = { [Op.gt]: value };
      break;
    case 'gte':
      numericFilter[fieldName] = { [Op.gte]: value };
      break;
    case 'lt':
      numericFilter[fieldName] = { [Op.lt]: value };
      break;
    case 'lte':
      numericFilter[fieldName] = { [Op.lte]: value };
      break;
    case 'between':
      if (Array.isArray(value) && value.length === 2) {
        numericFilter[fieldName] = { [Op.between]: value };
      }
      break;
    default:
      numericFilter[fieldName] = value;
  }

  return numericFilter;
};

module.exports = {
  buildQueryOptions,
  buildDateRangeFilter,
  buildNumericFilter
};