package com.ejie.ad74a.service;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.odftoolkit.odfdom.doc.OdfSpreadsheetDocument;
import org.odftoolkit.odfdom.doc.table.OdfTable;
import org.odftoolkit.odfdom.doc.table.OdfTableRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.ad74a.dao.PagosBeneficiarioDao;
import com.ejie.ad74a.model.PagosBeneficiario;
import com.ejie.ad74a.util.comun.UtilLiterales;
import com.ejie.ad74a.util.comun.UtilSeguridad;
import com.ejie.ad74a.util.comun.UtilidadesFecha;
import com.ejie.ad74a.util.constantes.MesesEnum;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;
import com.lowagie.text.Document;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

/**
 * PagosBeneficiarioServiceImpl generated by UDA, 04-oct-2023 9:26:03.
 * 
 * @author UDA
 */

@Service(value = "pagosBeneficiarioService")
public class PagosBeneficiarioServiceImpl implements PagosBeneficiarioService {

	private static final Logger logger = LoggerFactory.getLogger(PagosBeneficiarioServiceImpl.class);

	@Autowired
	private ReloadableResourceBundleMessageSource messageSource;

	@Autowired
	private PagosBeneficiarioDao pagosBeneficiarioDao;

	@Resource
	private ReloadableResourceBundleMessageSource appMessageSource;

	/**
	 * Inserts a single row in the PagosBeneficiario table.
	 *
	 * @param pagosBeneficiario PagosBeneficiario
	 * @return PagosBeneficiario
	 */
	@Transactional(rollbackFor = Throwable.class)
	public PagosBeneficiario add(PagosBeneficiario pagosBeneficiario) {
		if (pagosBeneficiario != null) {
			pagosBeneficiario.setUsuAlta75(UtilSeguridad.getUsuarioConectado().getUserName());
			pagosBeneficiario.setUsuModif75(UtilSeguridad.getUsuarioConectado().getUserName());
			pagosBeneficiario.setfAlta75(UtilidadesFecha.getFechaSistema());
			pagosBeneficiario.setfModif75(UtilidadesFecha.getFechaSistema());
		}
		return this.pagosBeneficiarioDao.add(pagosBeneficiario);
	}

	/**
	 * Updates a single row in the PagosBeneficiario table.
	 *
	 * @param pagosBeneficiario PagosBeneficiario
	 * @return PagosBeneficiario
	 */
	@Transactional(rollbackFor = Throwable.class)
	public PagosBeneficiario update(PagosBeneficiario pagosBeneficiario) {
		if (pagosBeneficiario != null) {
			pagosBeneficiario.setUsuModif75(UtilSeguridad.getUsuarioConectado().getUserName());
			pagosBeneficiario.setfModif75(UtilidadesFecha.getFechaSistema());
		}
		return this.pagosBeneficiarioDao.update(pagosBeneficiario);
	}

	/**
	 * Finds a single row in the PagosBeneficiario table.
	 *
	 * @param pagosBeneficiario PagosBeneficiario
	 * @return PagosBeneficiario
	 */
	public PagosBeneficiario find(PagosBeneficiario pagosBeneficiario) {
		return (PagosBeneficiario) this.pagosBeneficiarioDao.find(pagosBeneficiario);
	}

	/**
	 * Deletes a single row in the PagosBeneficiario table.
	 *
	 * @param pagosBeneficiario PagosBeneficiario
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void remove(PagosBeneficiario pagosBeneficiario) {
		this.pagosBeneficiarioDao.remove(pagosBeneficiario);
	}

	/**
	 * Finds a list of rows in the PagosBeneficiario table.
	 *
	 * @param pagosBeneficiario PagosBeneficiario
	 * @param tableRequestDto   TableRequestDto
	 * @return List<PagosBeneficiario>
	 */
	public List<PagosBeneficiario> findAll(PagosBeneficiario pagosBeneficiario, TableRequestDto tableRequestDto) {
		return (List<PagosBeneficiario>) this.pagosBeneficiarioDao.findAll(pagosBeneficiario, tableRequestDto);
	}

	/**
	 * Finds rows in the PagosBeneficiario table using like.
	 *
	 * @param pagosBeneficiario PagosBeneficiario
	 * @param tableRequestDto   TableRequestDto
	 * @param startsWith        Boolean
	 * @return List<PagosBeneficiario>
	 */
	public List<PagosBeneficiario> findAllLike(PagosBeneficiario pagosBeneficiario, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return (List<PagosBeneficiario>) this.pagosBeneficiarioDao.findAllLike(pagosBeneficiario, tableRequestDto,
				startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the PagosBeneficiario table.
	 *
	 * @param tableRequestDto TableRequestDto
	 */
	public void removeMultiple(TableRequestDto tableRequestDto) {
		this.pagosBeneficiarioDao.removeMultiple(tableRequestDto);
	}

	/**
	 * Filter method in the PagosBeneficiario table.
	 *
	 * @param filterPagosBeneficiario PagosBeneficiario
	 * @param tableRequestDto         TableRequestDto
	 * @param startsWith              Boolean
	 * @return TableResponseDto<PagosBeneficiario>
	 */
	public TableResponseDto<PagosBeneficiario> filter(PagosBeneficiario filterPagosBeneficiario,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<PagosBeneficiario> listaPagosBeneficiario = this.pagosBeneficiarioDao.findAllLike(filterPagosBeneficiario,
				tableRequestDto, false);
		Long recordNum = this.pagosBeneficiarioDao.findAllLikeCount(
				filterPagosBeneficiario != null ? filterPagosBeneficiario : new PagosBeneficiario(), false);

		TableResponseDto<PagosBeneficiario> tableResponseDto = new TableResponseDto<PagosBeneficiario>(tableRequestDto,
				recordNum, listaPagosBeneficiario);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<PagosBeneficiario>> reorderSelection = this.pagosBeneficiarioDao
					.reorderSelection(filterPagosBeneficiario, tableRequestDto, startsWith);
			tableResponseDto.setReorderedSelection(reorderSelection);
			tableResponseDto.addAdditionalParam("reorderedSelection", reorderSelection);
			tableResponseDto.addAdditionalParam("selectedAll", tableRequestDto.getMultiselection().getSelectedAll());
		}
		if (tableRequestDto.getSeeker().getSelectedIds() != null) {
			tableRequestDto.setMultiselection(tableRequestDto.getSeeker());
			List<TableRowDto<PagosBeneficiario>> reorderSeeker = this.pagosBeneficiarioDao
					.reorderSelection(filterPagosBeneficiario, tableRequestDto, startsWith);
			tableResponseDto.setReorderedSeeker(reorderSeeker);
			tableResponseDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return tableResponseDto;
	}

	/**
	 * Searches rows in the PagosBeneficiario table.
	 *
	 * @param filterPagosBeneficiario PagosBeneficiario
	 * @param searchPagosBeneficiario PagosBeneficiario
	 * @param tableRequestDto         TableRequestDto
	 * @param startsWith              Boolean
	 * @return List<TableRowDto<PagosBeneficiario>>
	 */
	public List<TableRowDto<PagosBeneficiario>> search(PagosBeneficiario filterPagosBeneficiario,
			PagosBeneficiario searchPagosBeneficiario, TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.pagosBeneficiarioDao.search(filterPagosBeneficiario, searchPagosBeneficiario, tableRequestDto,
				startsWith);
	}

	/**
	 * Reorder the selection made in PagosBeneficiario table.
	 *
	 * @param filterPagosBeneficiario PagosBeneficiario
	 * @param tableRequestDto         TableRequestDto
	 * @param startsWith              Boolean
	 * @return Object
	 */
	public Object reorderSelection(PagosBeneficiario filterPagosBeneficiario, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.pagosBeneficiarioDao.reorderSelection(filterPagosBeneficiario, tableRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */

	/**
	 * Finder method in the hierarchical the PagosBeneficiario table.
	 *
	 * @param filterPagosBeneficiario PagosBeneficiario
	 * @param tableRequestDto         TableRequestDto
	 * @param startsWith              Boolean
	 * @return TableResponseDto<JerarquiaDto<PagosBeneficiario>>
	 */
	public TableResponseDto<JerarquiaDto<PagosBeneficiario>> jerarquia(PagosBeneficiario filterPagosBeneficiario,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<JerarquiaDto<PagosBeneficiario>> listaPagosBeneficiario = this.pagosBeneficiarioDao
				.findAllLikeJerarquia(filterPagosBeneficiario, tableRequestDto);
		Long recordNum = this.pagosBeneficiarioDao.findAllLikeCountJerarquia(filterPagosBeneficiario, tableRequestDto);
		return new TableResponseDto<JerarquiaDto<PagosBeneficiario>>(tableRequestDto, recordNum,
				listaPagosBeneficiario);
	}

	/**
	 * Finder method for siblings rows in the hierarchical the PagosBeneficiario
	 * table.
	 *
	 * @param filterPagosBeneficiario PagosBeneficiario
	 * @param tableRequestDto         TableRequestDto
	 * @return TableResponseDto<JerarquiaDto<PagosBeneficiario>>
	 */
	public TableResponseDto<JerarquiaDto<PagosBeneficiario>> jerarquiaChildren(
			PagosBeneficiario filterPagosBeneficiario, TableRequestDto tableRequestDto) {
		TableResponseDto<JerarquiaDto<PagosBeneficiario>> tableResponseDto = new TableResponseDto<JerarquiaDto<PagosBeneficiario>>();
		tableResponseDto.addAdditionalParam(TableResponseDto.CHILDREN,
				this.pagosBeneficiarioDao.findAllChild(filterPagosBeneficiario, tableRequestDto));
		return tableResponseDto;
	}

	/**
	 * Exporta Datos al clipBoard
	 *
	 */
	public List<PagosBeneficiario> getMultiple(PagosBeneficiario filterPagosBeneficiario,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.pagosBeneficiarioDao.getMultiple(filterPagosBeneficiario, tableRequestDto, startsWith);
	}

	/**
	 * Devuelve un fichero xlsx que contiene los datos de los beneficiarios.
	 * 
	 * @param pagosBeneficiario pagosBeneficiario
	 * @param request           HttpServletRequest
	 * @param response          HttpServletResponse
	 */
	@Override
	public void generateExcelReportBeneficiarios(PagosBeneficiario pagosBeneficiario, HttpServletRequest request,
			HttpServletResponse response) {
		// Obtener datos de los beneficiarios
		TableRequestDto tableRequestDto = new TableRequestDto();
		tableRequestDto.setSidx("SOLIDENTIFICADOR01");
		tableRequestDto.setSord("ASC");
		List<PagosBeneficiario> listaPagosBeneficiario = this.pagosBeneficiarioDao.findAllLike(pagosBeneficiario,
				tableRequestDto, false);

		// Columnas
		String[] columns = new String[11];
		columns[0] = "solicitantes.identificador01";
		columns[1] = "solicitantes.nombre01";
		columns[2] = "solicitantes.apellido101";
		columns[3] = "solicitantes.apellido201";
		columns[4] = "solicitantes.direcciones.provinciaNORA.descProvincia";
		columns[5] = "solicitantes.fInicio01";
		columns[6] = "solicitantes.fBaja01";
		columns[7] = "maestroNivSoporte.desc";
		columns[8] = "numDias75";
		columns[9] = "tarifa75";
		columns[10] = "importe";

		// Nombre de las columnas
		String[] columnsName = new String[11];
		columnsName[0] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.identificador");
		columnsName[1] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.nombre");
		columnsName[2] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.apellido1");
		columnsName[3] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.apellido2");
		columnsName[4] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.territorio");
		columnsName[5] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.fInstalacion");
		columnsName[6] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.fBaja");
		columnsName[7] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.nivelSoporte");
		columnsName[8] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.numDias");
		columnsName[9] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.tarifa");
		columnsName[10] = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.importe");

		// Titulo archivo excel
		String fileName = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.titulo");

		// Titulo hoja excel
		String sheetTitle = UtilLiterales.getLiteralMessage(messageSource, "report.beneficiarios.excel.hoja");

		// Extension archivo
		String extension = ".xlsx";

		// Obtener el formato de fecha especifico del locale
		this.generateExcelReport(listaPagosBeneficiario, columns, columnsName, fileName, sheetTitle, extension,
				response);
	}

	/**
	 * Devuelve un fichero en el formato deseado que contiene los datos exportados
	 * de la tabla.
	 *
	 * @param filterPagosBeneficiario PagosBeneficiario
	 * @param columns                 String[]
	 * @param fileName                String
	 * @param sheetTitle              String
	 * @param reportsParams           ArrayList<?>
	 * @param tableRequestDto         TableRequestDto
	 * @param request                 HttpServletRequest
	 * @param response                HttpServletResponse
	 */
	@Override
	public void generateReport(PagosBeneficiario filterPagosBeneficiario, String[] columns, String[] columnsName,
			String fileName, String sheetTitle, ArrayList<?> reportsParams, TableRequestDto tableRequestDto,
			HttpServletRequest request, HttpServletResponse response) {
		// Accede a la DB para recuperar datos
		List<PagosBeneficiario> filteredData = getDataForReports(filterPagosBeneficiario, tableRequestDto);
		String extension = null;

		// Comprobar si las siguientes variables estan vacias, en caso de estarlo se las
		// asigna un valor generico
		fileName = (fileName != null && !fileName.isEmpty()) ? fileName : "report";
		sheetTitle = (sheetTitle != null && !sheetTitle.isEmpty()) ? sheetTitle
				: PagosBeneficiario.class.getSimpleName();

		// Cuando no se definen columnas porque se quieren obtener todas
		if (columns == null) {
			Field[] fields = PagosBeneficiario.class.getDeclaredFields();
			ArrayList<String> tempColumns = new ArrayList<String>();

			for (int i = 0; i < fields.length; i++) {
				try {
					String methodName = fields[i].getName();
					methodName = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
					PagosBeneficiario.class.getMethod("get" + methodName);
					tempColumns.add(fields[i].getName());
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				}

			}
			columns = tempColumns.toArray(new String[0]);
		}

		// si no se definen el nombre de las columnas , se dejan las de por defecto.
		if (columnsName == null) {
			columnsName = columns;
		}

		String servletPath = request.getServletPath();
		String reportType = null;
		if (servletPath.contains("/") && (servletPath.lastIndexOf("/") + 1 != servletPath.length())) {
			reportType = servletPath.substring(servletPath.lastIndexOf("/") + 1, servletPath.length());
		} else {
			reportType = servletPath.substring(0, servletPath.length());
		}

		if (reportType.equals("xlsReport")) {
			extension = ".xls";
			generateExcelReport(filteredData, columns, columnsName, fileName, sheetTitle, extension, response);
		} else if (reportType.equals("xlsxReport")) {
			extension = ".xlsx";
			generateExcelReport(filteredData, columns, columnsName, fileName, sheetTitle, extension, response);
		} else if (reportType.equals("pdfReport")) {
			extension = ".pdf";
			generatePDFReport(filteredData, columns, columnsName, fileName, response);
		} else if (reportType.equals("odsReport")) {
			extension = ".ods";
			generateODSReport(filteredData, columns, columnsName, fileName, sheetTitle, response);
		} else if (reportType.equals("csvReport")) {
			extension = ".csv";
			// Obtener idioma
			String language = request.getLocale().getLanguage();
			generateCSVReport(filteredData, columns, columnsName, fileName, sheetTitle, language, response);
		}

	}

	/**
	 * Devuelve un fichero excel que contiene los datos exportados de la tabla.
	 *
	 * @param filteredData List<PagosBeneficiario>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param sheetTitle   String
	 * @param extension    String
	 * @param response     HttpServletResponse
	 */
	private void generateExcelReport(List<PagosBeneficiario> filteredData, String[] columns, String[] columnsName,
			String fileName, String sheetTitle, String extension, HttpServletResponse response) {
		try {
			// Creacion del Excel
			Workbook workbook = null;
			if (extension == ".xlsx") {
				workbook = new XSSFWorkbook();
				response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
			} else {
				workbook = new HSSFWorkbook();
				response.setContentType("application/vnd.ms-excel");
			}

			response.setHeader("Content-Disposition", "attachment; filename=" + fileName + extension + "");

			// Creacion de una hoja y asignacion de su nombre
			Sheet sheet = workbook.createSheet(sheetTitle);

			// Se crea una fuente para estilizar las cabeceras
			Font headerFont = workbook.createFont();
			headerFont.setBold(true);
			headerFont.setFontHeightInPoints((short) 12);

			// Se crea un CellStyle con la fuente
			CellStyle headerCellStyle = workbook.createCellStyle();
			headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
			headerCellStyle.setFont(headerFont);

			// Inicializar contador de filas
			int rowNumber = 0;

			// Se crea la fila para insertar los titulos de las columnas
			Row row = sheet.createRow(rowNumber++);

			// Añadir titulos
			for (int i = 0; i < columnsName.length; i++) {
				Cell cell = row.createCell(i);
				cell.setCellValue(UtilLiterales.getLiteralMessage(appMessageSource, columnsName[i]));
				cell.setCellStyle(headerCellStyle);
			}

			// CreationHelper ayudara a mantener la compatibilidad del DataFormat tanto si
			// se crea un .xls como un .xlsx
			CreationHelper createHelper = workbook.getCreationHelper();

			// Se crea un CellStyle para añadir el formateador de fechas
			CellStyle dateCellStyle = workbook.createCellStyle();
			dateCellStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd/mm/yyyy"));

			// Se crea un CellStyle para añadir el formateador de nº de días
			CellStyle numDiasCellStyle = workbook.createCellStyle();
			numDiasCellStyle.setAlignment(HorizontalAlignment.RIGHT);

			// Se crea un CellStyle para añadir el formateador de la tarifa y el importe
			CellStyle tarifasCellStyle = workbook.createCellStyle();
			tarifasCellStyle.setAlignment(HorizontalAlignment.RIGHT);

			// Se crea un CellStyle para añadir el formateador de la tarifa y el importe
			CellStyle mesesCellStyle = workbook.createCellStyle();
			mesesCellStyle.setAlignment(HorizontalAlignment.LEFT);

			// Añadir datos
			for (PagosBeneficiario rowPagosBeneficiario : filteredData) {
				int cellNumber = 0;
				row = sheet.createRow(rowNumber++);

				// Se iteran las columnas y se insertan los datos respetando el orden que tenian
				// las columnas en la tabla
				for (String column : columns) {
					Cell cellPagosBeneficiario = row.createCell(cellNumber++);

					if (null != column) {
						if (column.equals("solicitantes.fInicio01")) {
							cellPagosBeneficiario.setCellStyle(dateCellStyle);
							cellPagosBeneficiario.setCellValue(rowPagosBeneficiario.getSolicitantes().getfInicio01());
						} else if (column.equals("solicitantes.fBajaPs01")) {
							cellPagosBeneficiario.setCellStyle(dateCellStyle);
							cellPagosBeneficiario.setCellValue(rowPagosBeneficiario.getSolicitantes().getfBajaPs01());
						} else if (column.equals("solicitantes.fBaja01")) {
							cellPagosBeneficiario.setCellStyle(dateCellStyle);
							cellPagosBeneficiario.setCellValue(rowPagosBeneficiario.getSolicitantes().getfBajaPs01());
						} else if (column.equals("numDias75")) {
							cellPagosBeneficiario.setCellStyle(numDiasCellStyle);
							cellPagosBeneficiario.setCellValue(rowPagosBeneficiario.getNumDias75().doubleValue());
						} else if (column.equals("tarifaStr")) {
							cellPagosBeneficiario.setCellStyle(tarifasCellStyle);
							cellPagosBeneficiario.setCellValue(rowPagosBeneficiario.getTarifaStr());
						} else if (column.equals("tarifa75")) {
							cellPagosBeneficiario.setCellStyle(tarifasCellStyle);
							cellPagosBeneficiario.setCellValue(rowPagosBeneficiario.getTarifaStr());
						} else if (column.equals("importeStr")) {
							cellPagosBeneficiario.setCellStyle(tarifasCellStyle);
							cellPagosBeneficiario.setCellValue(rowPagosBeneficiario.getImporteStr());
						} else if (column.equals("pagos.mesPago74")) {
							cellPagosBeneficiario.setCellStyle(mesesCellStyle);
							cellPagosBeneficiario.setCellValue(
									MesesEnum.getLabelDesc(rowPagosBeneficiario.getPagos().getMesPago74()));
						} else if (column.equals("importe")) {
							cellPagosBeneficiario.setCellStyle(tarifasCellStyle);
							cellPagosBeneficiario.setCellValue(rowPagosBeneficiario.getImporteStr());
						} else {
							cellPagosBeneficiario.setCellValue(getCellValue(column, rowPagosBeneficiario));
						}
					}
				}
			}

			// Se adapta el ancho de las columnas al contenido
			for (int i = 0; i < columns.length; i++) {
				sheet.autoSizeColumn(i);
			}

			// Se añade el fichero excel al response
			workbook.write(response.getOutputStream());
			workbook.close();
		} catch (

		IOException e) {
			e.printStackTrace();
		}
	}

	public static String formatearConPuntos(String valor) {
		try {
			// Convertir el String a un número
			double numero = Double.parseDouble(valor);

			// Crear un objeto DecimalFormat para formatear el número
			DecimalFormatSymbols simbolos = new DecimalFormatSymbols();
			simbolos.setGroupingSeparator('.'); // Puntos como separador de miles
			simbolos.setDecimalSeparator(','); // Coma como separador de decimales

			// Definir el patrón de formato para incluir hasta 3 decimales (puedes ajustarlo
			// según tus necesidades)
			DecimalFormat formateador = new DecimalFormat("#,##0.###", simbolos);

			// Formatear el número y añadir " EUR" al final
			return formateador.format(numero) + " €";

		} catch (NumberFormatException e) {
			// Si el String no es un número válido, devolver el valor original sin cambios
			return "El valor introducido no es un número válido.";
		}
	}

	/**
	 * Devuelve un fichero pdf que contiene los datos exportados de la tabla.
	 *
	 * @param filteredData List<PagosBeneficiario>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param response     HttpServletResponse
	 */
	private void generatePDFReport(List<PagosBeneficiario> filteredData, String[] columns, String[] columnsName,
			String fileName, HttpServletResponse response) {
		try {
			// Se añade el fichero excel al response y se añade el contenido
			response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".pdf");
			response.setContentType("application/pdf");

			Document document = new Document();
			// Se añade el fichero pdf al response
			PdfWriter.getInstance(document, response.getOutputStream());

			document.open();

			PdfPTable table = new PdfPTable(columns.length);

			for (String column : columnsName) {
				PdfPCell header = new PdfPCell();
				header.setBorderWidth(2);
				header.setPhrase(new Phrase(column));
				table.addCell(header);
			}

			// Añadir datos
			for (PagosBeneficiario rowPagosBeneficiario : filteredData) {
				// Se iteran las columnas y se insertan los datos respetando el orden que tenian
				// las columnas en la tabla
				for (String column : columns) {
					table.addCell(getCellValue(column, rowPagosBeneficiario));
				}
			}

			document.add(table);
			document.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Devuelve un fichero ods que contiene los datos exportados de la tabla.
	 *
	 * @param filteredData List<PagosBeneficiario>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param sheetTitle   String
	 * @param response     HttpServletResponse
	 */
	private void generateODSReport(List<PagosBeneficiario> filteredData, String[] columns, String[] columnsName,
			String fileName, String sheetTitle, HttpServletResponse response) {
		try {
			// Se añade el fichero ods al response y se añade el contenido
			response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".ods");
			response.setContentType("application/vnd.oasis.opendocument.spreadsheet");

			OdfSpreadsheetDocument ods = OdfSpreadsheetDocument.newSpreadsheetDocument();
			ods.getOrCreateDocumentStyles();

			// Hay que eliminar la hoja que se genera por defecto
			ods.getTableByName("Sheet1").remove();

			// Hoja nueva
			OdfTable table = OdfTable.newTable(ods, filteredData.size() + 1, columns.length);
			table.setTableName(sheetTitle);

			// Inicializar contador de filas
			int rowNumber = 0;

			// Cabeceras
			OdfTableRow row = table.getRowByIndex(rowNumber++);
			for (int i = 0; i < columnsName.length; i++) {
				row.getCellByIndex(i).setStringValue(columnsName[i]);
			}

			// Añadir datos
			for (PagosBeneficiario rowPagosBeneficiario : filteredData) {
				row = table.getRowByIndex(rowNumber++);
				int cellNumber = 0;

				// Se iteran las columnas y se insertan los datos respetando el orden que tenian
				// las columnas en la tabla
				for (String column : columns) {
					row.getCellByIndex(cellNumber++).setStringValue(getCellValue(column, rowPagosBeneficiario));
				}
			}

			// Se añade el fichero ods al response
			ods.save(response.getOutputStream());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Devuelve un fichero csv que contiene los datos exportados de la tabla.
	 *
	 * @param filteredData List<PagosBeneficiario>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param sheetTitle   String
	 * @param language     String
	 * @param response     HttpServletResponse
	 */
	private void generateCSVReport(List<PagosBeneficiario> filteredData, String[] columns, String[] columnsName,
			String fileName, String sheetTitle, String language, HttpServletResponse response) {
		try {
			// Se añade el fichero excel al response y se añade el contenido
			response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".csv");
			response.setContentType("text/csv");

			// Separador de campos dependiendo del idioma
			String separator = ";";
			if (language.equals("en")) {
				separator = ",";
			}

			// Se añade el fichero csv al response
			OutputStream out = response.getOutputStream();
			// Añadir titulos
			boolean addTitles = true;

			// Añadir datos
			for (PagosBeneficiario rowPagosBeneficiario : filteredData) {
				int cellNumber = 1;
				StringBuilder columnsTitles = new StringBuilder();
				StringBuilder row = new StringBuilder();

				// Se iteran las columnas y se insertan los datos respetando el orden que tenian
				// las columnas en la tabla
				for (String column : columns) {
					String cellValue = getCellValue(column, rowPagosBeneficiario);

					if (cellNumber < columns.length) {
						if (addTitles) {
							columnsTitles.append("\"");
							columnsTitles.append(column);
							columnsTitles.append("\"");
							columnsTitles.append(separator);
						}
						row.append("\"");
						row.append(cellValue);
						row.append("\"");
						row.append(separator);
						cellNumber++;
					} else {
						if (addTitles) {
							columnsTitles.append("\"");
							columnsTitles.append(column);
							columnsTitles.append("\"\n");
						}
						row.append("\"");
						row.append(cellValue);
						row.append("\"\n");
					}
				}

				if (addTitles) {
					out.write(columnsTitles.toString().getBytes());
					addTitles = false;
				}
				out.write(row.toString().getBytes());
			}
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Devuelve los datos recuperados de la DB.
	 *
	 * @param filterPagosBeneficiario PagosBeneficiario
	 * @param tableRequestDto         TableRequestDto
	 */
	public List<PagosBeneficiario> getDataForReports(PagosBeneficiario filterPagosBeneficiario,
			TableRequestDto tableRequestDto) {
		if (tableRequestDto.getMultiselection().getSelectedAll()
				&& tableRequestDto.getMultiselection().getSelectedIds().isEmpty()) {
			if (filterPagosBeneficiario != null) {
				return this.pagosBeneficiarioDao.findAllLikeXCL(filterPagosBeneficiario, tableRequestDto, false);
			} else {
				return this.pagosBeneficiarioDao.findAll(new PagosBeneficiario(), tableRequestDto);
			}
		} else {
			return this.pagosBeneficiarioDao.getMultiple(filterPagosBeneficiario, tableRequestDto, false);
		}
	}

	/**
	 * Obtiene los valores de las celdas.
	 *
	 * @param column               String
	 * @param rowPagosBeneficiario PagosBeneficiario
	 */
	private String getCellValue(String column, PagosBeneficiario rowPagosBeneficiario) {
		String cellValue = "";
		try {
			cellValue = BeanUtils.getProperty(rowPagosBeneficiario, column) != null
					? BeanUtils.getProperty(rowPagosBeneficiario, column)
					: "";
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		return cellValue;
	}

//	private String obtenerMesString(String numMes) {
//		String mes = "";
//		if (numMes.equals((MesesEnum.ENERO.getId()))) {
//			mes = MesesEnum.ENERO.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.FEBRERO.getId()))) {
//			mes = MesesEnum.FEBRERO.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.MARZO.getId()))) {
//			mes = MesesEnum.MARZO.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.ABRIL.getId()))) {
//			mes = MesesEnum.ABRIL.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.MAYO.getId()))) {
//			mes = MesesEnum.MAYO.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.JUNIO.getId()))) {
//			mes = MesesEnum.JUNIO.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.JULIO.getId()))) {
//			mes = MesesEnum.JULIO.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.AGOSTO.getId()))) {
//			mes = MesesEnum.AGOSTO.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.SEPTIEMBRE.getId()))) {
//			mes = MesesEnum.SEPTIEMBRE.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.OCTUBRE.getId()))) {
//			mes = MesesEnum.OCTUBRE.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.NOVIEMBRE.getId()))) {
//			mes = MesesEnum.NOVIEMBRE.getLabelDesc();
//		} else if (numMes.equals((MesesEnum.DICIEMBRE.getId()))) {
//			mes = MesesEnum.DICIEMBRE.getLabelDesc();
//		}
//		return mes;
//	}

}
