package com.ejie.ab63.service.leerExcel;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.ab63.comun.Constantes;
import com.ejie.ab63.comun.utilidades.config.Config;
import com.ejie.ab63.exceptions.PifException;
import com.ejie.ab63.model.Alojamiento;
import com.ejie.ab63.model.Aseo;
import com.ejie.ab63.model.AseoAlojamiento;
import com.ejie.ab63.model.EstablecimientoData;
import com.ejie.ab63.model.Habitacion;
import com.ejie.ab63.model.HabitacionAlojamiento;
import com.ejie.ab63.model.Parcela;
import com.ejie.ab63.model.Suite;
import com.ejie.ab63.model.TipoAseo;
import com.ejie.ab63.model.TipoHabitacion;
import com.ejie.ab63.service.AlojamientoService;
import com.ejie.ab63.service.AseoAlojamientoService;
import com.ejie.ab63.service.AseoService;
import com.ejie.ab63.service.EstablecimientoService;
import com.ejie.ab63.service.HabitacionAlojamientoService;
import com.ejie.ab63.service.HabitacionService;
import com.ejie.ab63.service.ParcelaService;
import com.ejie.ab63.service.SuiteService;
import com.ejie.ab63.service.TipoAseoService;
import com.ejie.ab63.service.TipoHabitacionService;
import com.ejie.ab63.tramita.adapter.PifAdapterService;
import com.ejie.ab63.util.ExcelUtil;
import com.sun.jmx.snmp.Timestamp;

@Service(value = "leerExcelService")
public class LeerExcelServiceImpl implements LeerExcelService {
	@Autowired
	HabitacionService habitacionService;
	@Autowired
	SuiteService suiteService;
	@Autowired
	AlojamientoService alojamientoService;
	@Autowired
	AseoService aseoService;
	@Autowired
	HabitacionAlojamientoService habitacionAlojamientoService;
	@Autowired
	EstablecimientoService establecimientoService;
	@Autowired
	private PifAdapterService pifAdapterService;
	@Autowired
	private ReloadableResourceBundleMessageSource appMessageSource;
	@Autowired
	AseoAlojamientoService aseoAlojamientoService;
	@Autowired
	ParcelaService parcelaService;
	@Autowired
	TipoAseoService tipoAseoService;
	@Autowired
	TipoHabitacionService tipoHabitacionService;

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

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public String masivoExcel(InputStream fis, Integer idEstablecimiento, String idTipoEstablecimiento)
			throws Exception {
		try {
			if (Constantes.HOTEL.equalsIgnoreCase(idTipoEstablecimiento)) {
				XSSFWorkbook workbook = new XSSFWorkbook(fis);
				boolean esMismoTipo = ExcelUtil.comprobarPlantilla(workbook, idTipoEstablecimiento);
				if (esMismoTipo) {
					List<Habitacion> listaHabitaciones = ExcelUtil.leerExcelHabitaciones(workbook, idEstablecimiento,
							0);
					List<Alojamiento> listaAlojamientos = ExcelUtil.leerExcelAlojamiento(workbook, idEstablecimiento, 1,
							false);
					List<HabitacionAlojamiento> listaHabitacionAlojamiento = ExcelUtil
							.leerExcelHabitacionAlojamiento(workbook, idEstablecimiento, 2);
					List<AseoAlojamiento> listaAseosAlojamiento = ExcelUtil.leerExcelBañosApartamento(workbook,
							idEstablecimiento, 3);
					List<Suite> listaSuites = ExcelUtil.leerExcelSuites(workbook, idEstablecimiento, 4);
					List<Aseo> listaAseos = ExcelUtil.leerExcelBañosGenerales(workbook, idEstablecimiento, 5);

					habitacionService.addMasivo(listaHabitaciones);
					suiteService.addMasivo(listaSuites);
					alojamientoService.addMasivo(listaAlojamientos, listaHabitacionAlojamiento, listaAseosAlojamiento);
					aseoService.addMasivo(listaAseos);
				} else {
					return appMessageSource.getMessage("excel.DistintoTipo", null, LocaleContextHolder.getLocale());
				}

			} else if (Constantes.ALBERGUE_TURISTICO.equalsIgnoreCase(idTipoEstablecimiento)) {

				XSSFWorkbook workbook = ExcelUtil.formarWorkbook(fis);
				boolean esMismoTipo = ExcelUtil.comprobarPlantilla(workbook, idTipoEstablecimiento);
				if (esMismoTipo) {
					List<Habitacion> listaHabitaciones = ExcelUtil.leerExcelHabitaciones(workbook, idEstablecimiento,
							0);
					List<Alojamiento> listaAlojamientos = ExcelUtil.leerExcelAlojamiento(workbook, idEstablecimiento, 1,
							true);
					List<HabitacionAlojamiento> listaHabitacionAlojamiento = ExcelUtil
							.leerExcelHabitacionAlojamiento(workbook, idEstablecimiento, 2);
					List<AseoAlojamiento> listaAseosAlojamiento = ExcelUtil.leerExcelBañosApartamento(workbook,
							idEstablecimiento, 3);
					List<Aseo> listaAseos = ExcelUtil.leerExcelBañosGenerales(workbook, idEstablecimiento, 4);

					habitacionService.addMasivo(listaHabitaciones);
					alojamientoService.addMasivo(listaAlojamientos, listaHabitacionAlojamiento, listaAseosAlojamiento);
					aseoService.addMasivo(listaAseos);
				} else {
					return appMessageSource.getMessage("excel.DistintoTipo", null, LocaleContextHolder.getLocale());
				}
			} else if (Constantes.CASA_RURAL.equalsIgnoreCase(idTipoEstablecimiento)
					|| Constantes.AGROTURISMO.equalsIgnoreCase(idTipoEstablecimiento)) {

				XSSFWorkbook workbook = ExcelUtil.formarWorkbook(fis);
				boolean esMismoTipo = ExcelUtil.comprobarPlantilla(workbook, idTipoEstablecimiento);
				if (esMismoTipo) {
					List<Habitacion> listaHabitaciones = ExcelUtil.leerExcelHabitaciones(workbook, idEstablecimiento,
							0);
					List<Alojamiento> listaAlojamientos = ExcelUtil.leerExcelAlojamiento(workbook, idEstablecimiento, 1,
							false);
					List<HabitacionAlojamiento> listaHabitacionAlojamiento = ExcelUtil
							.leerExcelHabitacionAlojamiento(workbook, idEstablecimiento, 2);
					List<AseoAlojamiento> listaAseosAlojamiento = ExcelUtil.leerExcelBañosApartamento(workbook,
							idEstablecimiento, 3);
					List<Aseo> listaAseos = ExcelUtil.leerExcelBañosGenerales(workbook, idEstablecimiento, 4);

					habitacionService.addMasivo(listaHabitaciones);
					alojamientoService.addMasivo(listaAlojamientos, listaHabitacionAlojamiento, listaAseosAlojamiento);
					aseoService.addMasivo(listaAseos);
				} else {
					return appMessageSource.getMessage("excel.DistintoTipo", null, LocaleContextHolder.getLocale());
				}

			} else if (Constantes.APARTAMENTO.equalsIgnoreCase(idTipoEstablecimiento)) {

				XSSFWorkbook workbook = ExcelUtil.formarWorkbook(fis);
				boolean esMismoTipo = ExcelUtil.comprobarPlantilla(workbook, idTipoEstablecimiento);
				if (esMismoTipo) {
					List<Alojamiento> listaAlojamientos = ExcelUtil.leerExcelAlojamiento(workbook, idEstablecimiento, 0,
							false);
					List<HabitacionAlojamiento> listaHabitacionAlojamiento = ExcelUtil
							.leerExcelHabitacionAlojamiento(workbook, idEstablecimiento, 1);
					List<AseoAlojamiento> listaAseosAlojamiento = ExcelUtil.leerExcelBañosApartamento(workbook,
							idEstablecimiento, 2);
					List<Aseo> listaAseos = ExcelUtil.leerExcelBañosGenerales(workbook, idEstablecimiento, 3);

					alojamientoService.addMasivo(listaAlojamientos, listaHabitacionAlojamiento, listaAseosAlojamiento);
					aseoService.addMasivo(listaAseos);
				} else {
					return appMessageSource.getMessage("excel.DistintoTipo", null, LocaleContextHolder.getLocale());
				}

			} else if (Constantes.CAMPING.equalsIgnoreCase(idTipoEstablecimiento)) {

				XSSFWorkbook workbook = ExcelUtil.formarWorkbook(fis);
				boolean esMismoTipo = ExcelUtil.comprobarPlantilla(workbook, idTipoEstablecimiento);
				if (esMismoTipo) {
					List<Parcela> listaParcelas = ExcelUtil.leerExcelParcelas(workbook, idEstablecimiento, 0);
					List<Aseo> listaAseos = ExcelUtil.leerExcelBañosGenerales(workbook, idEstablecimiento, 1);

					parcelaService.addMasivo(listaParcelas);
					aseoService.addMasivo(listaAseos);
				} else {
					return appMessageSource.getMessage("excel.DistintoTipo", null, LocaleContextHolder.getLocale());
				}

			}
		} catch (Exception e) {
			LeerExcelServiceImpl.logger.error(e.getMessage());
			return appMessageSource.getMessage("excel.Error", null, LocaleContextHolder.getLocale());
		}
		return null;
	}

	public String recuperarExcel(Integer idEstablecimiento, String idTipoEstablecimiento, int isPlantilla)
			throws IOException, PifException {
		String ruta = "";

		TipoAseo tipoAseo = new TipoAseo();
		tipoAseo.setBaja(0);
		List<TipoAseo> listaTipoAseos = tipoAseoService.findAll(tipoAseo, null);

		TipoHabitacion tipoHabitacion = new TipoHabitacion();
		tipoHabitacion.setBaja(0);
		List<TipoHabitacion> listaTipoHabitacion = tipoHabitacionService.findAll(tipoHabitacion, null);

		Alojamiento alojamientofind = new Alojamiento();
		EstablecimientoData establecimientoDataFind = new EstablecimientoData(idEstablecimiento);
		alojamientofind.setEstablecimientoData(establecimientoDataFind);
		alojamientofind.setTipoRegistro(Constantes.TIPO_REGISTRO_DETALLE);
		List<Alojamiento> listaAlojamientos = alojamientoService.findAll(alojamientofind, null);

		Habitacion habitacion = new Habitacion();
		habitacion.setEstablecimientoData(establecimientoDataFind);
		habitacion.setTipoRegistro(Constantes.TIPO_REGISTRO_DETALLE);
		List<Habitacion> listaHabitaciones = habitacionService.findAll(habitacion, null);

		Aseo aseo = new Aseo();
		aseo.setEstablecimientoData(establecimientoDataFind);
		aseo.setTipoRegistro(Constantes.TIPO_REGISTRO_DETALLE);
		List<Aseo> listaAseos = aseoService.findAll(aseo, null);

		List<HabitacionAlojamiento> listaHabitacionesAlojamiento = new ArrayList<HabitacionAlojamiento>();
		for (Alojamiento Alojamiento : listaAlojamientos) {
			Alojamiento alojamientoFind = new Alojamiento();
			alojamientoFind.setIdAlojamiento(Alojamiento.getIdAlojamiento());
			HabitacionAlojamiento habitacionAlojamiento = new HabitacionAlojamiento();
			habitacionAlojamiento.setAlojamiento(alojamientoFind);
			habitacionAlojamiento.setTipoRegistro(Constantes.TIPO_REGISTRO_DETALLE);
			listaHabitacionesAlojamiento.addAll(habitacionAlojamientoService.findAll(habitacionAlojamiento, null));
		}

		List<AseoAlojamiento> listaAseosAlojamiento = new ArrayList<AseoAlojamiento>();
		for (Alojamiento Alojamiento : listaAlojamientos) {
			Alojamiento alojamientoFind = new Alojamiento();
			alojamientoFind.setIdAlojamiento(Alojamiento.getIdAlojamiento());
			AseoAlojamiento aseoAlojamiento = new AseoAlojamiento();
			aseoAlojamiento.setAlojamiento(alojamientoFind);
			listaAseosAlojamiento.addAll(aseoAlojamientoService.findAll(aseoAlojamiento, null));
		}
		Properties prop = Config.loadProperties(Constantes.COD_APPL_CONFIG);
		if (Constantes.HOTEL.equalsIgnoreCase(idTipoEstablecimiento)) {
			String PATH_PLANTILLA = prop.getProperty("RUTA_EXCEL") + "hotel.xlsx";

			FileInputStream fis = new FileInputStream(PATH_PLANTILLA);
			XSSFWorkbook workbook = new XSSFWorkbook(fis);
			Suite suite = new Suite();
			suite.setEstablecimientoData(establecimientoDataFind);
			suite.setTipoRegistro(0);

			List<Suite> listaSuites = suiteService.findAll(suite, null);

			ExcelUtil.escribirTipoAseoHabitacion(listaTipoAseos, listaTipoHabitacion, workbook, 6);

			if (isPlantilla != 1) {
				ExcelUtil.escribirHabitaciones(listaHabitaciones, workbook, 0);
				ExcelUtil.escribirApartamentos(listaAlojamientos, workbook, 1);
				ExcelUtil.escribirHabitacionesAlojamiento(listaHabitacionesAlojamiento, workbook, 2);
				ExcelUtil.escribirAseosAlojamiento(listaAseosAlojamiento, workbook, 3);
				ExcelUtil.escribirSuites(listaSuites, workbook, 4);
				ExcelUtil.escribirAseos(listaAseos, workbook, 5);
			}
			ruta = subirExcelPif(workbook,
					appMessageSource.getMessage("excel.Hotel", null, LocaleContextHolder.getLocale()));
		} else if (Constantes.CASA_RURAL.equalsIgnoreCase(idTipoEstablecimiento)) {
			String PATH_PLANTILLA = prop.getProperty("RUTA_EXCEL") + "casaRural.xlsx";

			FileInputStream fis = new FileInputStream(PATH_PLANTILLA);
			XSSFWorkbook workbook = new XSSFWorkbook(fis);

			ExcelUtil.escribirTipoAseoHabitacion(listaTipoAseos, listaTipoHabitacion, workbook, 5);

			if (isPlantilla != 1) {
				ExcelUtil.escribirHabitaciones(listaHabitaciones, workbook, 0);
				ExcelUtil.escribirApartamentos(listaAlojamientos, workbook, 1);
				ExcelUtil.escribirHabitacionesAlojamiento(listaHabitacionesAlojamiento, workbook, 2);
				ExcelUtil.escribirAseosAlojamiento(listaAseosAlojamiento, workbook, 3);
				ExcelUtil.escribirAseos(listaAseos, workbook, 4);
			}
			ruta = subirExcelPif(workbook,
					appMessageSource.getMessage("excel.CasaRural", null, LocaleContextHolder.getLocale()));
		} else if (Constantes.AGROTURISMO.equalsIgnoreCase(idTipoEstablecimiento)) {
			String PATH_PLANTILLA = prop.getProperty("RUTA_EXCEL") + "agroturismo.xlsx";

			FileInputStream fis = new FileInputStream(PATH_PLANTILLA);
			XSSFWorkbook workbook = new XSSFWorkbook(fis);

			ExcelUtil.escribirTipoAseoHabitacion(listaTipoAseos, listaTipoHabitacion, workbook, 5);

			if (isPlantilla != 1) {
				ExcelUtil.escribirHabitaciones(listaHabitaciones, workbook, 0);
				ExcelUtil.escribirApartamentos(listaAlojamientos, workbook, 1);
				ExcelUtil.escribirHabitacionesAlojamiento(listaHabitacionesAlojamiento, workbook, 2);
				ExcelUtil.escribirAseosAlojamiento(listaAseosAlojamiento, workbook, 3);
				ExcelUtil.escribirAseos(listaAseos, workbook, 4);
			}
			ruta = subirExcelPif(workbook,
					appMessageSource.getMessage("excel.Agroturismo", null, LocaleContextHolder.getLocale()));
		} else if (Constantes.APARTAMENTO.equalsIgnoreCase(idTipoEstablecimiento)) {
			String PATH_PLANTILLA = prop.getProperty("RUTA_EXCEL") + "alojamiento.xlsx";

			FileInputStream fis = new FileInputStream(PATH_PLANTILLA);
			XSSFWorkbook workbook = new XSSFWorkbook(fis);

			ExcelUtil.escribirTipoAseoHabitacion(listaTipoAseos, listaTipoHabitacion, workbook, 4);

			if (isPlantilla != 1) {
				ExcelUtil.escribirApartamentos(listaAlojamientos, workbook, 0);
				ExcelUtil.escribirHabitacionesAlojamiento(listaHabitacionesAlojamiento, workbook, 1);
				ExcelUtil.escribirAseosAlojamiento(listaAseosAlojamiento, workbook, 2);
				ExcelUtil.escribirAseos(listaAseos, workbook, 3);
			}
			ruta = subirExcelPif(workbook,
					appMessageSource.getMessage("excel.Apartamento", null, LocaleContextHolder.getLocale()));
		} else if (Constantes.ALBERGUE_TURISTICO.equalsIgnoreCase(idTipoEstablecimiento)) {
			String PATH_PLANTILLA = prop.getProperty("RUTA_EXCEL") + "albergueTuristico.xlsx";

			FileInputStream fis = new FileInputStream(PATH_PLANTILLA);
			XSSFWorkbook workbook = new XSSFWorkbook(fis);

			ExcelUtil.escribirTipoAseoHabitacion(listaTipoAseos, listaTipoHabitacion, workbook, 5);

			if (isPlantilla != 1) {
				ExcelUtil.escribirHabitaciones(listaHabitaciones, workbook, 0);
				ExcelUtil.escribirApartamentos(listaAlojamientos, workbook, 1);
				ExcelUtil.escribirHabitacionesAlojamiento(listaHabitacionesAlojamiento, workbook, 2);
				ExcelUtil.escribirAseosAlojamiento(listaAseosAlojamiento, workbook, 3);
				ExcelUtil.escribirAseos(listaAseos, workbook, 4);
			}
			ruta = subirExcelPif(workbook,
					appMessageSource.getMessage("excel.AlbergueTuristico", null, LocaleContextHolder.getLocale()));
		} else if (Constantes.CAMPING.equalsIgnoreCase(idTipoEstablecimiento)) {
			String PATH_PLANTILLA = prop.getProperty("RUTA_EXCEL") + "camping.xlsx";

			FileInputStream fis = new FileInputStream(PATH_PLANTILLA);
			XSSFWorkbook workbook = new XSSFWorkbook(fis);
			Parcela parcela = new Parcela();
			parcela.setEstablecimientoData(establecimientoDataFind);
			parcela.setTipoRegistro(0);

			List<Parcela> listaParcelas = parcelaService.findAll(parcela, null);

			ExcelUtil.escribirTipoAseoHabitacion(listaTipoAseos, listaTipoHabitacion, workbook, 2);

			if (isPlantilla != 1) {
				ExcelUtil.escribirParcelas(listaParcelas, workbook, 0);
				ExcelUtil.escribirAseos(listaAseos, workbook, 1);
			}
			ruta = subirExcelPif(workbook,
					appMessageSource.getMessage("excel.Camping", null, LocaleContextHolder.getLocale()));
		}

		return ruta;
	}

	private String subirExcelPif(XSSFWorkbook workbook, String nombreExcel) throws PifException, IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		workbook.write(bos);
		byte[] barray = bos.toByteArray();
		InputStream is = new ByteArrayInputStream(barray);

		Timestamp timestamp = new Timestamp();
		return pifAdapterService.putFile(is, nombreExcel + "_" + timestamp.getDateTime(), Constantes.CODIGO_APLICACION);
	}

}