package com.ejie.aa21b.view;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

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

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.view.document.AbstractExcelView;

import com.ejie.aa21b.model.Aa21b20s01Consultas;
import com.ejie.aa21b.util.Aa21bConstantes;

/**
 * Crea el excel de listado de expedientes (Consultas y listados)
 * 
 *  
 * 
 */
public class ExcelAa21bListadoExpedientesView extends AbstractExcelView {
	private static final Logger logger = LoggerFactory
			.getLogger(ExcelAa21bListadoExpedientesView.class);
	/** Message source for i18n lookups */
	@Autowired
	private MessageSource messageSource;

	/**
	 * 
	 * @return MessageSource
	 */
	public MessageSource getMessageSource() {
		return messageSource;
	}

	/**
	 * 
	 * @param messageSource
	 *            MessageSource
	 */
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}

	/**
	 * 
	 */
	public ExcelAa21bListadoExpedientesView() {

	}

	/**
	 * 
	 * @param msgSource
	 *            MessageSource
	 */
	public ExcelAa21bListadoExpedientesView(MessageSource msgSource) {
		this.messageSource = msgSource;

	}

	/**
	 * Calcula las celdas tipo fórmula para que se muestren los resultados
	 * correctamente
	 * 
	 * @param wb
	 *            HSSFWorkbook
	 */
	public void evaluateAllFormulaCells(HSSFWorkbook wb) {
		HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
		Iterator rit;
		Iterator cit;
		for (int i = 0; i < wb.getNumberOfSheets(); ++i) {
			HSSFSheet sheet = wb.getSheetAt(i);

			for (rit = sheet.rowIterator(); rit.hasNext();) {
				Row r = (Row) rit.next();

				for (cit = r.cellIterator(); cit.hasNext();) {
					Cell c = (Cell) cit.next();
					if (c.getCellType() == 2)
						try {
							evaluator.evaluateFormulaCell(c);
						} catch (Exception e) {
						}
				}
			}
		}
	}

	Map<String, HSSFCellStyle> estilos;

	/**
	 * Obtener el nombre de fichero que corresponde al año y el idioma
	 * 
	 * @param anio
	 *            int
	 * @param file
	 *            String
	 * @param idioma
	 *            String
	 * @return String
	 */
	public String obtenerNombreFichero(String file, String idioma) {
		String res = "";
		File folder = new File(Aa21bConstantes.DATOSDIR);
		ExcelAa21bListadoExpedientesView.logger
				.info("Obteniendo plantilla correspondiente");
		FiltroNombre fil = new FiltroNombre(file, idioma);
		File[] listOfFiles = folder.listFiles(fil);
		File f = null;

		// String dname = "";
		Arrays.sort(listOfFiles);
		for (int i = 0; i < listOfFiles.length; i++) {
			f = listOfFiles[i];
			// dname = f.getName();
			// dname = f.getName().substring(file.length(), file.length() + 4);
			// fileanio = Integer.parseInt(dname);
			if (i == 0) {
				res = f.getName();
				// break;
			}
		}
		if (res.equals(""))
			res = f.getName();
		return res.substring(0, res.length() - 4);
	}

	/**
	 * Establece la plantilla antes de que comenzar la creación del excel
	 * 
	 * @param model
	 *            Map<String, ?>
	 * @param request
	 *            HttpServletRequest
	 * @param response
	 *            HttpServletResponse
	 * 
	 */
	public void render(Map<String, ?> model, HttpServletRequest request,
			HttpServletResponse response) {
		Locale locale = RequestContextUtils.getLocale(request);
		String file = Aa21bConstantes.EXCELLISTADOEXPEDIENTES;
		String idioma = "ES";
		if (!locale.getDisplayLanguage().contains("es")
				&& !locale.getDisplayLanguage().contains("Spanish"))
			idioma = "EU";
		ExcelAa21bListadoExpedientesView.logger.info("buscando plantilla->"
				+ locale.getDisplayLanguage());
		String ff = file.substring(Aa21bConstantes.DATOSDIR.length() + 5,
				file.length());
		String s = "file:" + Aa21bConstantes.DATOSDIR
				+ obtenerNombreFichero(ff, idioma);
		this.setUrl(s);
		try {
			super.render(model, request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Crea el excel
	 * 
	 * @param model
	 *            Map<String, Object>
	 * @param book
	 *            HSSFWorkbook
	 * @param request
	 *            HttpServletRequest
	 * @param response
	 *            HttpServletResponse Exception Exception
	 * @throws Exception
	 *             Exception
	 */
	@Override
	protected void buildExcelDocument(Map<String, Object> model,
			HSSFWorkbook book, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		ExcelAa21bListadoExpedientesView.logger.info("Creando fichero");

		Locale locale = RequestContextUtils.getLocale(request);
		String idioma = "ES";
		if (!locale.getDisplayLanguage().contains("es")
				&& !locale.getDisplayLanguage().contains("Spanish"))
			idioma = "EU";
		// rellenamos las hojas dat(d)

		rellenarDAT(
				(List<Aa21b20s01Consultas>) model.get("listadoExpedientes"),
				(List<String>) model.get("listaFiltros"), book, idioma, locale);

		evaluateAllFormulaCells(book);
		ExcelAa21bListadoExpedientesView.logger.info("fin de fichero");
	}

	/**
	 * 
	 * @param datos
	 *            List<Aa21b15s01>
	 * @param book
	 *            HSSFWorkbook
	 */
	private void rellenarDAT(List<Aa21b20s01Consultas> datos,
			List<String> listaFiltros, HSSFWorkbook book, String idioma,
			Locale locale) {
		// TODO Auto-generated method stub
		HSSFSheet sheetal = book.getSheet("Listado");
		Map<String, HSSFCellStyle> estilos = createStyles(book);

		if (datos != null) {
			Iterator<Aa21b20s01Consultas> iter = datos.iterator();
			Iterator<String> iterFiltros = listaFiltros.iterator();
			int row = 0;
			HSSFCell c = null;

			Aa21b20s01Consultas actual = new Aa21b20s01Consultas();

			String cservAnt = "";
			int contador = 0;
			boolean mostrarCabecera = false;
			while (iter.hasNext()) {
				actual = iter.next();
				contador++;

				if (actual.getCserv20() != null
						&& !cservAnt.equals(actual.getCserv20().toString())) {
					contador = 1;
					row = row + 4;
					mostrarCabecera = true;
					// Filtros

					while (iterFiltros.hasNext()) {
						String filtro = iterFiltros.next();
						sheetal.createRow(row);
						CellRangeAddress range = new CellRangeAddress(row, row,
								2, 8);
						sheetal.addMergedRegion(range);
						c = getCell(sheetal, row, 2);
						c.setCellStyle(estilos.get("filtro"));
						setText(c, filtro);
						// setLine(sheetal, row, 2, filtro);
						row++;
					}

					// Servicio

					sheetal.createRow(row);
					CellRangeAddress range = new CellRangeAddress(row, row, 2,
							3);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 2);
					c.setCellStyle(estilos.get("cabecera"));
					setText(c, messageSource.getMessage("tramitacion.servicio",
							null, locale));
					// setLine(sheetal, row, 2, "Servicio:");
					range = new CellRangeAddress(row, row, 4, 8);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 4);
					c.setCellStyle(estilos.get("cabeceraDesc"));
					setText(c,
							actual.getCserv20() + " - " + actual.getDserv20());

					row++;

				} else if (actual.getCserv20() == null && cservAnt != null) {
					mostrarCabecera = true;
					contador = 1;
					row = row + 3; // Servicio
					sheetal.createRow(row);
					CellRangeAddress range = new CellRangeAddress(row, row, 2,
							3);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 2);
					c.setCellStyle(estilos.get("cabecera"));
					setText(c, messageSource.getMessage(
							"tramitacion.sinservicio", null, locale));

					row++;
				} else {
					mostrarCabecera = false;
				}

				if (mostrarCabecera) {
					sheetal.createRow(row);
					CellRangeAddress range = new CellRangeAddress(row, row, 1,
							1);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 1);
					c.setCellStyle(estilos.get("cabeceraDetalle"));
					setText(c, messageSource.getMessage("listadoExp.contador",
							null, locale));

					range = new CellRangeAddress(row, row, 2, 3);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 2);
					c.setCellStyle(estilos.get("cabeceraDetalle"));
					setText(c, messageSource.getMessage("listadoExp.refExp",
							null, locale));
					c = getCell(sheetal, row, 3);
					c.setCellStyle(estilos.get("cabeceraDetalle"));

					range = new CellRangeAddress(row, row, 4, 12);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 4);
					c.setCellStyle(estilos.get("cabeceraDetalle"));
					setText(c, messageSource.getMessage("listadoExp.objeto",
							null, locale));
					for (int i = 5; i < 13; i++) {
						c = getCell(sheetal, row, i);
						c.setCellStyle(estilos.get("cabeceraDetalle"));
					}

					range = new CellRangeAddress(row, row, 13, 14);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 13);
					c.setCellStyle(estilos.get("cabeceraDetalle"));
					setText(c, messageSource.getMessage("listadoExp.faper",
							null, locale));
					c = getCell(sheetal, row, 14);
					c.setCellStyle(estilos.get("cabeceraDetalle"));

					range = new CellRangeAddress(row, row, 15, 16);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 15);
					c.setCellStyle(estilos.get("cabeceraDetalle"));
					setText(c, messageSource.getMessage("listadoExp.fcier",
							null, locale));
					c = getCell(sheetal, row, 16);
					c.setCellStyle(estilos.get("cabeceraDetalle"));

					range = new CellRangeAddress(row, row, 17, 18);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 17);
					c.setCellStyle(estilos.get("cabeceraDetalle"));
					setText(c, messageSource.getMessage("listadoExp.impor",
							null, locale));
					c = getCell(sheetal, row, 18);
					c.setCellStyle(estilos.get("cabeceraDetalle"));

					range = new CellRangeAddress(row, row, 19, 20);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 19);
					c.setCellStyle(estilos.get("cabeceraDetalle"));
					setText(c, messageSource.getMessage("listadoExp.imporA",
							null, locale));
					c = getCell(sheetal, row, 20);
					c.setCellStyle(estilos.get("cabeceraDetalle"));

					row++;
				}

				// Expediente
				sheetal.createRow(row);
				CellRangeAddress range = new CellRangeAddress(row, row, 1, 1);
				sheetal.addMergedRegion(range);
				c = getCell(sheetal, row, 1);
				c.setCellStyle(estilos.get("detalle"));
				setText(c, Integer.valueOf(contador).toString());

				range = new CellRangeAddress(row, row, 2, 3);
				sheetal.addMergedRegion(range);
				c = getCell(sheetal, row, 2);
				c.setCellStyle(estilos.get("detalle"));
				setText(c, actual.getRefExp());

				range = new CellRangeAddress(row, row, 4, 12);
				sheetal.addMergedRegion(range);
				c = getCell(sheetal, row, 4);
				c.setCellStyle(estilos.get("detalle"));
				setText(c, actual.getObjeto20());

				range = new CellRangeAddress(row, row, 13, 14);
				sheetal.addMergedRegion(range);

				String fechaApertura = "";
				String fechaCierre = "";
				try {
					SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
					SimpleDateFormat sdf_eu = new SimpleDateFormat("yyyy-MM-dd");

					if (Aa21bConstantes.AA21B_IDIOMA_EUS
							.equalsIgnoreCase(idioma)) {
						if (actual.getFaper20() != null) {
							fechaApertura = sdf_eu.format(actual.getFaper20());
						}
						if (actual.getFcier20() != null) {
							fechaCierre = sdf_eu.format(actual.getFcier20());
						}
					} else {
						if (actual.getFaper20() != null) {
							fechaApertura = sdf.format(actual.getFaper20());
						}
						if (actual.getFcier20() != null) {
							fechaCierre = sdf.format(actual.getFcier20());
						}
					}
				} catch (Exception e) {
					logger.error("getXml - Error formateando fecha de apertura y cierre : "
							+ e.toString());
				}

				c = getCell(sheetal, row, 13);
				c.setCellStyle(estilos.get("detalleCentrado"));
				setText(c, fechaApertura);
				range = new CellRangeAddress(row, row, 15, 16);
				sheetal.addMergedRegion(range);
				c = getCell(sheetal, row, 15);
				c.setCellStyle(estilos.get("detalleCentrado"));
				setText(c, fechaCierre);
				if (actual.getEimpor20() != null) {
					range = new CellRangeAddress(row, row, 17, 18);
					sheetal.addMergedRegion(range);

					c = getCell(sheetal, row, 17);
					c.setCellStyle(estilos.get("detalleCentradoNum"));
					// setText(c, actual.getEimpor20() != null ?
					// actual.getEimpor20()
					// .toString() : "");
					c.setCellType(HSSFCell.CELL_TYPE_NUMERIC);

					c.setCellValue(actual.getEimpor20().doubleValue());
				}
				if (actual.getEimpora20() != null) {
					range = new CellRangeAddress(row, row, 19, 20);
					sheetal.addMergedRegion(range);
					c = getCell(sheetal, row, 19);
					c.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
					c.setCellStyle(estilos.get("detalleCentradoNum"));
					// setText(c, actual.getEimpora20() != null ? actual
					// .getEimpora20().toString() : "");

					c.setCellValue(actual.getEimpora20().doubleValue());
				}
				cservAnt = actual.getCserv20().toString();

				row++;
			}
		}

	}

	/**
	 * Method 'Map'
	 * 
	 * @param wb
	 *            HSSFWorkbook
	 * 
	 * @return Map<String, HSSFCellStyle>
	 */
	private static Map<String, HSSFCellStyle> createStyles(HSSFWorkbook wb) {
		Map<String, HSSFCellStyle> styles = new HashMap<String, HSSFCellStyle>();
		// // titulo principal

		HSSFFont fontcabecera = wb.createFont();
		// cabecera tablas
		fontcabecera.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		fontcabecera.setColor(HSSFColor.BLACK.index);
		fontcabecera.setItalic(true);
		fontcabecera.setFontHeightInPoints((short) 12);
		HSSFCellStyle cabecera = wb.createCellStyle();
		cabecera.setFillForegroundColor(HSSFColor.WHITE.index);
		cabecera.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		cabecera.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		cabecera.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		cabecera.setFont(fontcabecera);
		cabecera.setWrapText(true);
		styles.put("cabecera", cabecera);

		HSSFFont fontcabeceraDesc = wb.createFont();
		// cabecera tablas
		fontcabeceraDesc.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		fontcabeceraDesc.setColor(HSSFColor.BLACK.index);
		fontcabeceraDesc.setItalic(true);
		fontcabeceraDesc.setFontHeightInPoints((short) 12);
		HSSFCellStyle cabeceraDesc = wb.createCellStyle();
		cabeceraDesc.setFillForegroundColor(HSSFColor.WHITE.index);
		cabeceraDesc.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		cabeceraDesc.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		cabeceraDesc.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		cabeceraDesc.setFont(fontcabeceraDesc);
		cabeceraDesc.setWrapText(true);
		styles.put("cabeceraDesc", cabeceraDesc);

		HSSFFont fontcabeceraDetalle = wb.createFont();
		// cabecera tablas
		fontcabeceraDetalle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		fontcabeceraDetalle.setColor(HSSFColor.BLACK.index);
		fontcabeceraDetalle.setItalic(true);
		fontcabeceraDetalle.setFontHeightInPoints((short) 12);
		HSSFCellStyle cabeceraDetalle = wb.createCellStyle();
		cabeceraDetalle.setFillForegroundColor(HSSFColor.WHITE.index);
		cabeceraDetalle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		cabeceraDetalle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		cabeceraDetalle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		cabeceraDetalle.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
		cabeceraDetalle.setTopBorderColor(HSSFColor.BLACK.index);
		cabeceraDetalle.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
		cabeceraDetalle.setBottomBorderColor(HSSFColor.BLACK.index);

		cabeceraDetalle.setFont(fontcabeceraDetalle);
		cabeceraDetalle.setWrapText(true);
		styles.put("cabeceraDetalle", cabeceraDetalle);

		HSSFFont fontFiltro = wb.createFont();
		// cabecera tablas
		fontFiltro.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		fontFiltro.setColor(HSSFColor.BLACK.index);
		fontFiltro.setFontHeightInPoints((short) 12);
		HSSFCellStyle filtro = wb.createCellStyle();
		filtro.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		filtro.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		filtro.setFont(fontFiltro);
		filtro.setWrapText(true);
		styles.put("filtro", filtro);

		HSSFFont fontDetalle = wb.createFont();
		// cabecera tablas
		fontDetalle.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		fontDetalle.setColor(HSSFColor.BLACK.index);
		fontDetalle.setFontHeightInPoints((short) 12);
		HSSFCellStyle detalle = wb.createCellStyle();
		detalle.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		detalle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		detalle.setFont(fontDetalle);
		detalle.setWrapText(true);
		styles.put("detalle", detalle);

		HSSFFont fontDetalleCent = wb.createFont();
		// cabecera tablas
		fontDetalleCent.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		fontDetalleCent.setColor(HSSFColor.BLACK.index);
		fontDetalleCent.setFontHeightInPoints((short) 12);
		HSSFCellStyle detalleCent = wb.createCellStyle();
		detalleCent.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		detalleCent.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		detalleCent.setFont(fontDetalleCent);
		detalleCent.setWrapText(true);
		styles.put("detalleCentrado", detalleCent);
		HSSFCellStyle detalleCentNum = wb.createCellStyle();
		detalleCentNum.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		detalleCentNum.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		detalleCentNum.setFont(fontDetalleCent);
		detalleCentNum.setWrapText(true);
		DataFormat format = wb.createDataFormat();
		detalleCentNum.setDataFormat(format.getFormat("#,##0.00"));
		styles.put("detalleCentradoNum", detalleCentNum);
		HSSFFont fontFiltroDesc = wb.createFont();
		// cabecera tablas
		fontFiltroDesc.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		fontFiltroDesc.setColor(HSSFColor.BLACK.index);
		fontFiltroDesc.setItalic(true);
		fontFiltroDesc.setFontHeightInPoints((short) 12);
		HSSFCellStyle filtroDesc = wb.createCellStyle();
		filtroDesc.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		filtroDesc.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		filtroDesc.setFont(fontFiltroDesc);
		filtroDesc.setWrapText(true);
		styles.put("filtroDesc", filtro);

		return styles;
	}

}
