import { FindOptions, Sequelize } from "sequelize";
import { Criteria } from "./critera.js";

/**
 * Mapeo lógico→físico de campos.
 * - clave: nombre de campo en dominio (Criteria)
 * - valor: columna real en BD (p.ej. 'invoice_date' o 'current_customer.name')
 */
export type CriteriaMappings = Record<string, string>;

/**
 * Parámetros de conversión → FindOptions (Sequelize).
 * - allowedFields: lista blanca de campos ordenables (deben estar indexados).
 * - searchableFields: columnas FULLTEXT (deben tener índice FT en BD).
 * - enableFullText: activa MATCH ... AGAINST si true.
 * - mappings: mapeo Criteria→SQL.
 * - database: instancia Sequelize para escapar literales en FULLTEXT.
 * - baseOptions: opciones iniciales (se fusionan con el resultado final).
 * - strictMode?: true = lanza error si orden no permitido
 */
export interface ConvertParams {
  allowedFields?: string[]; // p.ej. ['invoice_date','id','created_at']
  searchableFields?: string[]; // p.ej. ['reference','description','notes']
  enableFullText?: boolean; // default: false
  mappings?: CriteriaMappings; // default: {}
  database?: Sequelize; // requerido si enableFullText=true
  baseOptions?: FindOptions; // default: {}
  strictMode?: boolean;
}

export interface ICriteriaToOrmConverter {
  convert(criteria: Criteria, params: ConvertParams): FindOptions;
  applyFilters(options: FindOptions, criteria: Criteria, mappings: CriteriaMappings): void;
  applyQuickSearch(options: FindOptions, criteria: Criteria, params: ConvertParams): void;
  applyOrder(
    options: FindOptions,
    criteria: Criteria,
    mappings: CriteriaMappings,
    params: ConvertParams
  ): void;
  applyPagination(options: FindOptions, criteria: Criteria): void;
}
