package com.ejie.ab79.service.AB63;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;

import javax.activation.MimetypesFileTypeMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
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.ab79.clientesWS.ab61WebService.Usuario;
import com.ejie.ab79.comun.Constantes;
import com.ejie.ab79.dao.RelEstInsDao;
import com.ejie.ab79.dao.AB63.EstablecimientosRegistradosDao;
import com.ejie.ab79.dao.expedientes.DatosDireccionesDao;
import com.ejie.ab79.dao.expedientes.DatosTercerosDao;
import com.ejie.ab79.dao.inspecciones.EstadosInspeccionDao;
import com.ejie.ab79.dao.inspecciones.InspeccionesDao;
import com.ejie.ab79.model.Inspectores;
import com.ejie.ab79.model.RelEstIns;
import com.ejie.ab79.model.AB63.EstablecimientosRegistrados;
import com.ejie.ab79.model.expedientes.DatosDirecciones;
import com.ejie.ab79.model.expedientes.DatosTerceros;
import com.ejie.ab79.model.expedientes.Expedientes;
import com.ejie.ab79.model.expedientes.TiposDireccion;
import com.ejie.ab79.model.inspecciones.EstadosInspeccion;
import com.ejie.ab79.model.inspecciones.Inspecciones;
import com.ejie.ab79.model.inspecciones.ResultadosInspeccion;
import com.ejie.ab79.model.nora.T17Provincia;
import com.ejie.ab79.service.inspecciones.InspeccionesService;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;

/**
 * EstablecimientosRegistradosServiceImpl  
 * 12:00:42.
 * 
 *  
 */

@Service(value = "establecimientosRegistradosService")
public class EstablecimientosRegistradosServiceImpl implements EstablecimientosRegistradosService {

	public static final Logger logger = LoggerFactory.getLogger(EstablecimientosRegistradosServiceImpl.class);

	@Autowired
	private EstablecimientosRegistradosDao establecimientosRegistradosDao;

	@Autowired
	private InspeccionesDao inspeccionesDao;

	@Autowired
	private InspeccionesService inspeccionesService;

	@Autowired
	private DatosTercerosDao datosTercerosDao;

	@Autowired
	private DatosDireccionesDao datosDireccionesDao;

	@Autowired
	private RelEstInsDao relEstInsDao;

	@Autowired
	private EstadosInspeccionDao estadosInspeccionDao;

	@Resource
	private ReloadableResourceBundleMessageSource appMessageSource;

	@Override
	public List<EstablecimientosRegistrados> findAllLike(EstablecimientosRegistrados filterEstablecimientosRegistrados,
			TableRequestDto tableRequestDto, boolean startsWith) {
		return this.establecimientosRegistradosDao.findAllLike(filterEstablecimientosRegistrados, tableRequestDto,
				startsWith);
	}

	@Override
	public TableResponseDto<EstablecimientosRegistrados> filter(
			EstablecimientosRegistrados filterEstablecimientosRegistrados, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		List<EstablecimientosRegistrados> listaEstablecimientosRegistrados = this.establecimientosRegistradosDao
				.findAllLike(filterEstablecimientosRegistrados, tableRequestDto, false);
		Long recordNum = this.establecimientosRegistradosDao.findAllLikeCount(filterEstablecimientosRegistrados != null
				? filterEstablecimientosRegistrados : new EstablecimientosRegistrados(), false);

		TableResponseDto<EstablecimientosRegistrados> usuarioDto = new TableResponseDto<EstablecimientosRegistrados>(
				tableRequestDto, recordNum, listaEstablecimientosRegistrados);
		return usuarioDto;
	}

	@Override
	@Transactional
	public void asociarEstablecimientos(List<EstablecimientosRegistrados> establecimientosRegistrados) {

		for (EstablecimientosRegistrados establecimiento : establecimientosRegistrados) {

			// Creamos la inspecci锟絥 a insertar con los datos recibidos
			EstablecimientosRegistradosServiceImpl.logger.info("[asociarEstablecimientos] : Creamos inspecci锟絥");
			Inspecciones inspeccion = new Inspecciones();

			String identificadorInspeccion = this.inspeccionesService
					.crearIdentificadorInspeccion(establecimiento.getCampaina().getDireccion().getIdDireccion());

			inspeccion.setIdentificadorInspeccion(identificadorInspeccion);
			inspeccion.setResultadoInspeccion(new ResultadosInspeccion(null));
			inspeccion.setDireccion(establecimiento.getCampaina().getDireccion());
			inspeccion.setIdProtocolo(establecimiento.getCampaina().getProtocolo());
			inspeccion.setExpediente(new Expedientes(null));
			inspeccion.setCampaina(establecimiento.getCampaina());
			inspeccion.setIdOrigenInspeccion(Constantes.ORIGEN_CAMPAINA);
			inspeccion.setInspector(new Inspectores(null));
			inspeccion.setUsuarioRegistro(establecimiento.getUsuarioRegistro());

			EstadosInspeccion estadoInspeccion = this.estadosInspeccionDao.findByOrigenDireccion(
					inspeccion.getIdOrigenInspeccion(), inspeccion.getDireccion().getIdDireccion(),
					Constantes.ESTADO_PENDIENTE);

			if (estadoInspeccion != null) {
				inspeccion.setEstadoInspeccion(estadoInspeccion);
			} else {
				inspeccion.setEstadoInspeccion(new EstadosInspeccion());
			}

			// Insertamos inspecci锟絥
			EstablecimientosRegistradosServiceImpl.logger.info("[asociarEstablecimientos] : Insertamos inspecci锟絥");
			inspeccion = this.inspeccionesDao.add(inspeccion);

			// Creamos los datosTercero a insertar con los datos recibidos
			EstablecimientosRegistradosServiceImpl.logger.info("[asociarEstablecimientos] : Creamos datos tercero");
			DatosTerceros datosTercero = new DatosTerceros();
			datosTercero.setDocumento(establecimiento.getDatosTercero().getDocumento());
			datosTercero.setTipoDocumento(establecimiento.getDatosTercero().getTipoDocumento());
			datosTercero.setNombre(establecimiento.getDatosTercero().getNombre());
			datosTercero.setApellido1(establecimiento.getDatosTercero().getApellido1());
			datosTercero.setApellido2(establecimiento.getDatosTercero().getApellido2());
			datosTercero.setSexo(establecimiento.getDatosTercero().getSexo());
			datosTercero.setTelefono(establecimiento.getDatosTercero().getTelefono());
			datosTercero.setEmail(establecimiento.getDatosTercero().getEmail());
			datosTercero.setIdioma(establecimiento.getDatosTercero().getIdioma());
			datosTercero.setTipoParticipante(Constantes.PARTICIPANTE_TITULAR);
			datosTercero.setUsuarioRegistro(establecimiento.getUsuarioRegistro());

			// Insertamos datosTercero
			EstablecimientosRegistradosServiceImpl.logger.info("[asociarEstablecimientos] : Insertamos datos tercero");
			datosTercero = this.datosTercerosDao.add(datosTercero);

			// Creamos los datosDireccion a insertar con los datos recibidos
			EstablecimientosRegistradosServiceImpl.logger.info("[asociarEstablecimientos] : Creamos datos direcci锟絥");
			DatosDirecciones datosDireccion = new DatosDirecciones();
			datosDireccion.setDatosTerceros(datosTercero);
			datosDireccion.setTiposDireccion(new TiposDireccion(Constantes.ID_UBICACION_INVERSION));
			datosDireccion.setDireccion(establecimiento.getDatosDireccion().getDireccion());
			datosDireccion.setNumero(establecimiento.getDatosDireccion().getNumero());
			datosDireccion.setEscalera(establecimiento.getDatosDireccion().getEscalera());
			datosDireccion.setPiso(establecimiento.getDatosDireccion().getPiso());
			datosDireccion.setLetra(establecimiento.getDatosDireccion().getLetra());
			datosDireccion.setCodigoPostal(establecimiento.getDatosDireccion().getCodigoPostal());
			datosDireccion.setIdProvincia(establecimiento.getDatosDireccion().getIdProvincia());
			T17Provincia provincia = new T17Provincia();
			provincia.setId(String.valueOf(establecimiento.getDatosDireccion().getIdProvincia()));
			datosDireccion.setProvincia(provincia);
			datosDireccion.setIdMunicipio(establecimiento.getDatosDireccion().getIdMunicipio());
			datosDireccion.setIdLocalidad(establecimiento.getDatosDireccion().getIdLocalidad());
			datosDireccion.setEstablecimiento(establecimiento.getDatosDireccion().getEstablecimiento());
			datosDireccion.setComplementoDireccion(establecimiento.getDatosDireccion().getComplementoDireccion());
			datosDireccion.setIdentificadorEstablecimiento(establecimiento.getIdentificadorEstablecimiento());
			datosDireccion.setUsuarioRegistro(establecimiento.getUsuarioRegistro());

			// Insertamos datosDireccion
			EstablecimientosRegistradosServiceImpl.logger
					.info("[asociarEstablecimientos] : Insertamos datos direcci锟絥");
			datosDireccion = this.datosDireccionesDao.add(datosDireccion);

			// Creamos la relaci锟絥 del establecimiento con la inspecci锟絥
			EstablecimientosRegistradosServiceImpl.logger
					.info("[asociarEstablecimientos] : Creamos relaci锟絥 establecimiento-inspecci锟絥");
			RelEstIns relEstIns = new RelEstIns();
			relEstIns.setInspeccionBD(inspeccion);
			relEstIns.setIdTercero(datosTercero.getIdTercero());
			relEstIns.setIdDireccion(datosDireccion.getIdDireccion());

			String titulo = this.inspeccionesService.crearTitulo(inspeccion, datosTercero, datosDireccion);

			relEstIns.setTitulo(titulo);
			relEstIns.setUsuarioRegistro(establecimiento.getUsuarioRegistro());

			// Insertamos la relaci髇 del establecimiento con la inspecci锟絥
			EstablecimientosRegistradosServiceImpl.logger
					.info("[asociarEstablecimientos] : Insertamos relaci髇 establecimiento-inspecci锟絥");
			this.relEstInsDao.add(relEstIns);

		}

	}

	@Override
	@Transactional
	public void asociarEstablecimientoInspeccion(EstablecimientosRegistrados establecimientoRegistrado,
			Inspecciones inspeccion, Usuario usuario) {

		// Creamos los datosTercero a insertar con los datos recibidos
		EstablecimientosRegistradosServiceImpl.logger.info("[asociarEstablecimientos] : Creamos datos tercero");
		DatosTerceros datosTercero = new DatosTerceros();
		datosTercero.setDocumento(establecimientoRegistrado.getDatosTercero().getDocumento());
		datosTercero.setTipoDocumento(establecimientoRegistrado.getDatosTercero().getTipoDocumento());
		datosTercero.setNombre(establecimientoRegistrado.getDatosTercero().getNombre());
		datosTercero.setApellido1(establecimientoRegistrado.getDatosTercero().getApellido1());
		datosTercero.setApellido2(establecimientoRegistrado.getDatosTercero().getApellido2());
		datosTercero.setSexo(establecimientoRegistrado.getDatosTercero().getSexo());
		datosTercero.setTelefono(establecimientoRegistrado.getDatosTercero().getTelefono());
		datosTercero.setEmail(establecimientoRegistrado.getDatosTercero().getEmail());
		datosTercero.setIdioma(establecimientoRegistrado.getDatosTercero().getIdioma());
		datosTercero.setTipoParticipante(Constantes.PARTICIPANTE_TITULAR);
		datosTercero.setUsuarioRegistro(usuario.getUsuario());

		// Insertamos datosTercero
		EstablecimientosRegistradosServiceImpl.logger.info("[asociarEstablecimientos] : Insertamos datos tercero");
		datosTercero = this.datosTercerosDao.add(datosTercero);

		// Creamos los datosDireccion a insertar con los datos recibidos
		EstablecimientosRegistradosServiceImpl.logger.info("[asociarEstablecimientos] : Creamos datos direcci锟絥");
		DatosDirecciones datosDireccion = new DatosDirecciones();
		datosDireccion.setDatosTerceros(datosTercero);
		datosDireccion.setTiposDireccion(new TiposDireccion(Constantes.ID_UBICACION_INVERSION));
		datosDireccion.setDireccion(establecimientoRegistrado.getDatosDireccion().getDireccion());
		datosDireccion.setNumero(establecimientoRegistrado.getDatosDireccion().getNumero());
		datosDireccion.setEscalera(establecimientoRegistrado.getDatosDireccion().getEscalera());
		datosDireccion.setPiso(establecimientoRegistrado.getDatosDireccion().getPiso());
		datosDireccion.setLetra(establecimientoRegistrado.getDatosDireccion().getLetra());
		datosDireccion.setCodigoPostal(establecimientoRegistrado.getDatosDireccion().getCodigoPostal());
		datosDireccion.setIdProvincia(establecimientoRegistrado.getDatosDireccion().getIdProvincia());
		T17Provincia provincia = new T17Provincia();
		provincia.setId(String.valueOf(establecimientoRegistrado.getDatosDireccion().getIdProvincia()));
		datosDireccion.setProvincia(provincia);
		datosDireccion.setIdMunicipio(establecimientoRegistrado.getDatosDireccion().getIdMunicipio());
		datosDireccion.setIdLocalidad(establecimientoRegistrado.getDatosDireccion().getIdLocalidad());
		datosDireccion.setEstablecimiento(establecimientoRegistrado.getDatosDireccion().getEstablecimiento());
		datosDireccion.setComplementoDireccion(establecimientoRegistrado.getDatosDireccion().getComplementoDireccion());
		datosDireccion.setIdentificadorEstablecimiento(
				establecimientoRegistrado.getDatosDireccion().getIdentificadorEstablecimiento());
		datosDireccion.setUsuarioRegistro(usuario.getUsuario());

		// Insertamos datosDireccion
		EstablecimientosRegistradosServiceImpl.logger.info("[asociarEstablecimientos] : Insertamos datos direcci锟絥");
		datosDireccion = this.datosDireccionesDao.add(datosDireccion);

		// Buscamos la relaci髇 del establecimiento con la inspecci锟絥
		EstablecimientosRegistradosServiceImpl.logger
				.info("[asociarEstablecimientos] : Buscamos la relaci锟絥 establecimiento-inspecci锟絥");
		RelEstIns relEstIns = this.relEstInsDao.findByInspeccion(inspeccion);
		relEstIns.setIdTercero(datosTercero.getIdTercero());
		relEstIns.setIdDireccion(datosDireccion.getIdDireccion());

		if (inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_CAMPAINA)
				|| inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_INSPECCION_OFICIO)
				|| inspeccion.getIdOrigenInspeccion().equals(Constantes.ORIGEN_BUZON_FRAUDE)) {
			String titulo = this.inspeccionesService.crearTitulo(inspeccion, datosTercero, datosDireccion);
			relEstIns.setTitulo(titulo);
		}

		relEstIns.setUsuarioUltModificacion(usuario.getUsuario());
		// Actualizamos la relaci锟絥 del establecimiento con la inspecci锟絥
		EstablecimientosRegistradosServiceImpl.logger
				.info("[asociarEstablecimientos] : Actualizamos relaci锟絥 establecimiento-inspecci锟絥");
		this.relEstInsDao.update(relEstIns);

	}

	@Override
	public void getExcel(List<EstablecimientosRegistrados> listaEstablecimientos, HttpServletResponse response) {

		Locale locale = LocaleContextHolder.getLocale();

		boolean castellano = false;
		boolean euskera = false;

		// Configuramos variables de idioma.
		if (locale.toString().equals(Constantes.CASTELLANO)) {
			castellano = true;
		} else if (locale.toString().equals(Constantes.EUSKERA)) {
			euskera = true;
		}

		try {
			// Nombre del archivo
			String fileName = appMessageSource.getMessage("excel.establecimientosRegistrados.sheetName", null, locale)
					+ Constantes.EXTENSION_EXCEL;

			// Creamos la hoja
			HSSFWorkbook workbook = new HSSFWorkbook();
			HSSFSheet sheet = workbook.createSheet(
					appMessageSource.getMessage("excel.establecimientosRegistrados.sheetName", null, locale));

			// Definimos los estilos y fuentes de la hoja
			HSSFFont font = workbook.createFont();
			font.setFontName(HSSFFont.FONT_ARIAL);
			font.setFontHeightInPoints((short) 12);
			font.setBoldweight(Font.BOLDWEIGHT_BOLD);

			HSSFCellStyle headerStyle = workbook.createCellStyle();
			headerStyle.setBorderBottom(CellStyle.BORDER_MEDIUM);
			headerStyle.setFont(font);
			headerStyle.setAlignment(CellStyle.ALIGN_CENTER);

			// Creamos la fila cabecera
			HSSFRow rowHead = sheet.createRow(0);
			rowHead.createCell(0).setCellValue(
					appMessageSource.getMessage("excel.establecimientosRegistrados.numeroRegistro", null, locale));
			rowHead.createCell(1).setCellValue(
					appMessageSource.getMessage("excel.establecimientosRegistrados.nombreComercial", null, locale));
			rowHead.createCell(2).setCellValue(
					appMessageSource.getMessage("excel.establecimientosRegistrados.direccion", null, locale));
			rowHead.createCell(3).setCellValue(
					appMessageSource.getMessage("excel.establecimientosRegistrados.fechaApertura", null, locale));
			rowHead.createCell(4).setCellValue(
					appMessageSource.getMessage("excel.establecimientosRegistrados.nifTitular", null, locale));
			rowHead.createCell(5).setCellValue(
					appMessageSource.getMessage("excel.establecimientosRegistrados.nombreTitular", null, locale));

			rowHead.getCell(0).setCellStyle(headerStyle);
			rowHead.getCell(1).setCellStyle(headerStyle);
			rowHead.getCell(2).setCellStyle(headerStyle);
			rowHead.getCell(3).setCellStyle(headerStyle);
			rowHead.getCell(4).setCellStyle(headerStyle);
			rowHead.getCell(5).setCellStyle(headerStyle);
			rowHead.setHeightInPoints(20);

			// Creamos el resto de filas con sus celdas
			int rowCount = 1;
			for (EstablecimientosRegistrados establecimiento : listaEstablecimientos) {
				HSSFRow establecimientoRow = sheet.createRow(rowCount++);

				establecimientoRow.createCell(0).setCellValue(establecimiento.getIdentificadorEstablecimiento());
				establecimientoRow.createCell(1).setCellValue(establecimiento.getDatosDireccion().getEstablecimiento());
				establecimientoRow.createCell(2).setCellValue(establecimiento.getDatosDireccion().getDireccion());

				if (establecimiento.getFechaApertura() != null) {
					SimpleDateFormat sdf = new SimpleDateFormat();
					if (castellano) {
						sdf = new SimpleDateFormat(Constantes.FORMATO_FECHA_ES);
					} else if (euskera) {
						sdf = new SimpleDateFormat(Constantes.FORMATO_FECHA_EU);
					}
					String fechaComoCadena = sdf.format(establecimiento.getFechaApertura());
					establecimientoRow.createCell(3).setCellValue(fechaComoCadena);
				}

				establecimientoRow.createCell(4).setCellValue(establecimiento.getDatosTercero().getDocumento());
				establecimientoRow.createCell(5).setCellValue(establecimiento.getNombreTitular());

				establecimientoRow.setHeightInPoints(20);
			}

			// Anchura de las columnas
			sheet.autoSizeColumn(0);
			sheet.autoSizeColumn(1);
			sheet.autoSizeColumn(2);
			sheet.autoSizeColumn(3);
			sheet.autoSizeColumn(4);
			sheet.autoSizeColumn(5);

			FileOutputStream fileOut = new FileOutputStream(fileName);
			workbook.write(fileOut);
			fileOut.close();

			EstablecimientosRegistradosServiceImpl.logger.info("[GET - exportarExcel] : Archivo generado");

			// Creamos el archivo a descargar
			File fileToDownload = new File(fileName);
			InputStream in = new FileInputStream(fileToDownload);

			// Recogemos el MIME type del fichero
			String mimeType = new MimetypesFileTypeMap().getContentType(fileName);

			if (mimeType == null) {
				// Si no se encuentra lo seteamos manualmente
				mimeType = "application/octet-stream";
			}
			EstablecimientosRegistradosServiceImpl.logger.info("[GET - exportarExcel] : MIME type: " + mimeType);

			// Seteamos el contentType de la response
			response.setContentType(mimeType);
			response.setContentLength((int) fileToDownload.length());

			// Descargamos el archivo
			response.setHeader("Content-Disposition", "attachment; filename=\"" + fileToDownload.getName() + "\"");

			// Obtenemos el outputStream de la response
			OutputStream outStream = response.getOutputStream();

			byte[] buffer = new byte[4096];
			int bytesRead = -1;

			while ((bytesRead = in.read(buffer)) != -1) {
				outStream.write(buffer, 0, bytesRead);
			}

			// Cerramos el InputStream y el OutputStream
			in.close();
			outStream.close();

			EstablecimientosRegistradosServiceImpl.logger
					.info("[GET - exportarExcel] : Archivo descargado con 锟絰ito");

		} catch (Exception e) {
			EstablecimientosRegistradosServiceImpl.logger.error(e.getMessage());
		}

	}

}
