/**
 * BaseService - Base service class (deprecated)
 *
 * NOTE: This base class is deprecated. New services should be standalone
 * and use TypeORM Repository pattern directly with DataSource injection.
 *
 * The ServiceContext and PaginatedResult interfaces are still exported
 * for backwards compatibility with existing code.
 *
 * @deprecated Use standalone service pattern with TypeORM Repository instead
 * @module Shared
 */

/**
 * Contexto de servicio para multi-tenant
 */
export interface ServiceContext {
  tenantId: string;
  userId?: string;
}

/**
 * Resultado paginado genérico
 */
export interface PaginatedResult<T> {
  data: T[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

/**
 * Filtros de paginación base
 */
export interface BasePaginationFilters {
  page?: number;
  limit?: number;
  sortBy?: string;
  sortOrder?: 'asc' | 'desc';
  search?: string;
}

/**
 * Opciones para construcción de queries
 */
export interface QueryOptions {
  includeDeleted?: boolean;
}

/**
 * Configuración del servicio base
 */
export interface BaseServiceConfig {
  tableName: string;
  schema: string;
  selectFields: string;
  searchFields?: string[];
  defaultSortField?: string;
  softDelete?: boolean;
}

/**
 * Clase base abstracta para servicios CRUD con soporte multi-tenant
 *
 * @deprecated Use standalone service pattern with TypeORM Repository instead
 *
 * Example of new pattern:
 * ```typescript
 * import { DataSource, Repository, IsNull } from 'typeorm';
 *
 * interface ServiceContext {
 *   tenantId: string;
 *   userId?: string;
 * }
 *
 * interface PaginatedResult<T> {
 *   data: T[];
 *   total: number;
 *   page: number;
 *   limit: number;
 *   totalPages: number;
 * }
 *
 * export class MyService {
 *   private repository: Repository<MyEntity>;
 *
 *   constructor(dataSource: DataSource) {
 *     this.repository = dataSource.getRepository(MyEntity);
 *   }
 *
 *   async findById(ctx: ServiceContext, id: string): Promise<MyEntity | null> {
 *     return this.repository.findOne({
 *       where: { id, tenantId: ctx.tenantId, deletedAt: IsNull() },
 *     });
 *   }
 * }
 * ```
 */
export abstract class BaseService<_T = unknown, _CreateDto = unknown, _UpdateDto = unknown> {
  protected abstract config: BaseServiceConfig;

  /**
   * Nombre completo de la tabla (schema.table)
   */
  protected get fullTableName(): string {
    return `${this.config.schema}.${this.config.tableName}`;
  }

  /**
   * Sanitiza nombre de campo para prevenir SQL injection
   */
  protected sanitizeFieldName(field: string): string {
    if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(field)) {
      return this.config.defaultSortField || 'created_at';
    }
    return field;
  }

  /**
   * Redondea a N decimales
   */
  protected roundToDecimals(value: number, decimals: number = 2): number {
    const factor = Math.pow(10, decimals);
    return Math.round(value * factor) / factor;
  }
}

export default BaseService;
