package com.rjconsultores.ventaboletos.service.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.brazilutils.br.cpfcnpj.Cpf;
import org.brazilutils.validation.ValidationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zkoss.util.media.Media;
import org.zkoss.util.resource.Labels;

import com.rjconsultores.ventaboletos.entidad.Cliente;
import com.rjconsultores.ventaboletos.entidad.ClienteDireccion;
import com.rjconsultores.ventaboletos.entidad.ClienteFidelidad;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.TarjetaFidelidad;
import com.rjconsultores.ventaboletos.entidad.TipoIdentificacion;
import com.rjconsultores.ventaboletos.entidad.TipoOcupacion;
import com.rjconsultores.ventaboletos.passageirofrequente.vo.ClienteExcelVo;
import com.rjconsultores.ventaboletos.service.ClienteService;
import com.rjconsultores.ventaboletos.service.ImportacaoClientesService;
import com.rjconsultores.ventaboletos.service.TipoIdentificacionService;
import com.rjconsultores.ventaboletos.service.TipoOcupacionService;
import com.rjconsultores.ventaboletos.utilerias.ApplicationProperties;
import com.rjconsultores.ventaboletos.utilerias.CustomEnum;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;

@Service("importacaoClientesService")
public class ImportacaoClientesServiceImpl implements ImportacaoClientesService {

	@Autowired
	private TipoOcupacionService tipoOcupacionService;

	@Autowired
	TipoIdentificacionService tipoIdentificacionService;

	@Autowired
	private ClienteService clienteService;

	private static final Logger log = LogManager.getLogger(ImportacaoClientesServiceImpl.class);

	@Override
	public String[] lerArquivo(Reader reader, List<Empresa> empresas) {
		String linha = null;
		Integer index = 0;
		StringBuilder qtdeGravados = new StringBuilder();
		StringBuilder erros = new StringBuilder();

		Integer inseridos = 0;
		Integer atualizados = 0;

		try {
			BufferedReader leitor = new BufferedReader(reader);

			while ((linha = leitor.readLine()) != null) {
				String[] dados = linha.replace("\"", "").split(",");
				Integer[] gravados = salvarClientes(dados, empresas);
				inseridos = gravados[0] + inseridos;
				atualizados = gravados[1] + atualizados;
				index++;
			}

			leitor.close();

			qtdeGravados.append("Gravados ").append(inseridos + atualizados).append(" clientes de ").append(index).append(" importados.\n");
			qtdeGravados.append("Atualizados ").append(atualizados).append(" clientes.\n");
			qtdeGravados.append("Inseridos ").append(inseridos).append(" novos clientes.");

			String[] resultado = { qtdeGravados.toString(), erros.toString() };
			return resultado;

		} catch (ArrayIndexOutOfBoundsException e) {
			log.error(e);
			String msg = "Erro ao gravar cliente na linha " + (index + 1) + " do arquivo.";
			erros.append(msg);
			String[] resultado = { "Houve erro ao gravar os clientes, consulte o arquivo de erros.", erros.toString() };
			return resultado;
		} catch (Exception e) {
			erros.append("Linha ").append(index).append(" do arquivo de clientes, erro: ").append(e.getCause().getCause()).append("\n");
			log.error(e);
			String[] resultado = { e.toString() };
			return resultado;
		}
	}

	@Override
	public Integer[] salvarClientes(String[] cliente, List<Empresa> empresas) throws Exception {
		String nomeCliente = cliente[1].replace("\"", "").toUpperCase();
		Integer inseridos = new Integer(0);
		Integer atualizados = new Integer(0);
		Integer[] gravados = { 0, 0 };

		for (Empresa e : empresas) {

			Cliente clienteGravar = clienteService.buscarPorNumeroFidelidade(cliente[0], e);
			if (clienteGravar == null) {
				clienteGravar = new Cliente();
				clienteGravar.setNombcliente(nomeCliente);
				clienteGravar.setNumIdentificaUno(cliente[3]);
				TarjetaFidelidad tarjetaFidelidad = new TarjetaFidelidad();
				tarjetaFidelidad.setActivo(Boolean.TRUE);
				tarjetaFidelidad.setFecmodif(Calendar.getInstance().getTime());
				tarjetaFidelidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
				// cast para Integer para remover 0 a esquerda:
				tarjetaFidelidad.setNumTarjeta(cliente[0]);

				List<ClienteFidelidad> ls = new ArrayList<ClienteFidelidad>();

				ClienteFidelidad clienteFidelidad = new ClienteFidelidad();
				clienteFidelidad.setTarjetaFidelidad(tarjetaFidelidad);
				clienteFidelidad.setActivo(Boolean.TRUE);
				clienteFidelidad.setFecmodif(Calendar.getInstance().getTime());
				clienteFidelidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
				clienteFidelidad.setCliente(clienteGravar);
				clienteFidelidad.setEmpresa(e);
				ls.add(clienteFidelidad);

				clienteGravar.setListClienteFidelidad(ls);

				clienteService.suscribir(clienteGravar);
				inseridos = inseridos + 1;
				gravados[0] = gravados[0] + inseridos;
			} else {
				clienteGravar.setNombcliente(nomeCliente);
				clienteGravar.setNumIdentificaUno(cliente[3]);
				clienteService.actualizacion(clienteGravar);

				atualizados = atualizados + 1;
				gravados[1] = gravados[1] + atualizados;
			}
		}
		return gravados;
	}

	@Override
	public String[] lerArquivoExcel(Media media, List<Empresa> empresas) {

		List<TipoIdentificacion> lsTipoIdentificacion = tipoIdentificacionService.obtenerTodos();
		TipoIdentificacion tipoIdentificacionUno = null;
		TipoIdentificacion tipoIdentificacionDoos = null;

		for (TipoIdentificacion t : lsTipoIdentificacion) {
			if (t.getDesctipo().equalsIgnoreCase("cpf")) {
				tipoIdentificacionUno = t;
			} else if (t.getDesctipo().equalsIgnoreCase("rg")) {
				tipoIdentificacionDoos = t;
			}
			if (tipoIdentificacionUno != null && tipoIdentificacionDoos != null)
				break;
		}

		Boolean usaCPFComoFidelidade = false;
		Integer index = 1;
		StringBuilder qtdeGravados = new StringBuilder();
		StringBuilder erros = new StringBuilder();
		Integer inseridos = 0;
		Integer atualizados = 0;
		Integer desconsiderados = 0;
		InputStream isMExcel = media.getStreamData();
		Sheet sheet = null;

		if (media.getFormat().equals("xls")) {
			HSSFWorkbook wb;
			try {
				wb = new HSSFWorkbook(isMExcel);
				sheet = wb.getSheetAt(0);
			} catch (IOException e) {
				e.printStackTrace();
			}

		} else if (media.getFormat().equals("xlsx")) {
			XSSFWorkbook wb;
			try {
				wb = new XSSFWorkbook(isMExcel);
				sheet = wb.getSheetAt(0);
			} catch (IOException e) {
				log.error("", e);
			}
		}

		int rows = sheet.getPhysicalNumberOfRows();

		log.info(String.format("Quantidade cliente:%s", rows));

		if (validaSheet(sheet)) {
			usaCPFComoFidelidade = ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.USA_CPF_COMO_FIDELIDADE.getDescricao());
			log.info(String.format("usaCPFComoFidelidade:%s", usaCPFComoFidelidade));
			try {
				for (index = 1; index < rows; index++) {
					log.info(String.format("index cliente:%s", index));

					Row row = sheet.getRow(index);
					if (row == null) {
						log.info("index/row empty");
						continue;
					}

					Iterator<Cell> cellIterator = row.cellIterator();
					ClienteExcelVo cliente = new ClienteExcelVo();

					while (cellIterator.hasNext()) {
						Cell cell = cellIterator.next();
						switch (cell.getColumnIndex()) {
						case 0:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setCpf(cell.getStringCellValue());
							System.out.println(cliente.getCpf());
							break;
						case 1:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setRg(cell.getStringCellValue());
							break;
						case 2:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setNome(cell.getStringCellValue());
							break;
						case 3:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setEmail(cell.getStringCellValue());
							break;
						case 4:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setTelefone(cell.getStringCellValue());
							break;
						case 5:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setCelular(cell.getStringCellValue());
							break;
						case 6:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setFax(cell.getStringCellValue());
							break;
						case 7:

							String dt = null;

							if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
								dt = cell.getStringCellValue();
							} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
								dt = cell.getDateCellValue() != null ? new SimpleDateFormat("dd/MM/yyyy").format(cell.getDateCellValue()) : null;
							}
							cliente.setNascimento(dt);

							break;
						case 8:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setSexo(cell.getStringCellValue());
							break;
						case 9:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setEndereco(cell.getStringCellValue());
							break;
						case 10:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setBairro(cell.getStringCellValue());
							break;
						case 11:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setCidade(cell.getStringCellValue());
							break;
						case 12:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setEstado(cell.getStringCellValue());
							break;

						}
					}
					log.info(String.format("cliente:%s cpf:%s", cliente.getNome(), cliente.getCpf()));

					if (validaDadosPlanilha(cliente, erros)) {
						log.info("enviado para gravação...");
						try {
							Integer[] gravados = salvarClienteExcel(empresas, usaCPFComoFidelidade, cliente, tipoIdentificacionUno, tipoIdentificacionDoos, false);
							inseridos = gravados[0] + inseridos;
							atualizados = gravados[1] + atualizados;
							desconsiderados = gravados[2] + desconsiderados;
						} catch (Throwable e) {
							log.error("Erro na gravação do registro. Favor revisar", e);
							log.info("continuando importação");
						}

					} else {
						log.info("cliente não validado");
						erros.append("\n erro ao gravar o cliente na linha ");
						erros.append(index + 1).append(" do arquivo.");
					}
				}
				qtdeGravados.append("Gravados ").append(inseridos + atualizados).append(" clientes de ").append(index - 1).append(" importados.\n");
				qtdeGravados.append("Desconsiderados ").append(desconsiderados).append(" clientes.\n");
				qtdeGravados.append("Atualizados ").append(atualizados).append(" clientes.\n");
				qtdeGravados.append("Inseridos ").append(inseridos).append(" novos clientes.");
				String[] resultado = { qtdeGravados.toString(), erros.toString() };

				log.info("importação finalizada");

				return resultado;

			} catch (ArrayIndexOutOfBoundsException e) {
				e.printStackTrace();
				String msg = "Erro ao gravar cliente na linha " + (index + 1) + " do arquivo.";
				erros.append(msg);
				String[] resultado = { "Houve erro ao gravar os clientes, consulte o arquivo de erros.", erros.toString() };
				return resultado;
			} catch (Exception e) {
				e.printStackTrace();
				erros.append("Linha ").append(index).append(" do arquivo de clientes, erro: ").append(e.getCause().getCause()).append("\n");
				String[] resultado = { "Houve erro ao gravar os clientes, consulte o arquivo de erros.", erros.toString() };
				return resultado;
			}

		} else {
			erros.append("A estrutura do arquivo esta com erro ").append("\n");
			String[] resultado = { "Houve erro ao gravar os clientes, consulte o arquivo de erros.", erros.toString() };
			return resultado;
		}

	}

	private Integer[] salvarClienteExcel(List<Empresa> empresas, Boolean usaCPFComoFidelidade, ClienteExcelVo cliente,
			TipoIdentificacion tipoIdentificacionUno, TipoIdentificacion tipoIdentificacionDoos, boolean isImportacaoPolicial) throws ParseException {
		Integer inseridos = new Integer(0);
		Integer atualizados = new Integer(0);
		Integer desconsiderados = new Integer(0);
		Integer[] gravados = { 0, 0, 0 };
		Cliente clienteGravar = new Cliente();

		String docBusca = cliente.getCpf();
		if (isImportacaoPolicial) {
			docBusca = cliente.getRg();
		}

		List<Cliente> lsCliente = clienteService.buscarPorDocumento(docBusca);

		if (lsCliente != null && !lsCliente.isEmpty()) {
			if (ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.IS_DESCONSIDERA_CLIENTE_NA_BASE.getDescricao())) {
				desconsiderados = desconsiderados + 1;
				gravados[2] = gravados[2] + desconsiderados;
				return gravados;
			} else {
				clienteGravar = lsCliente.get(0);
			}
		}

		if (usaCPFComoFidelidade == null)
			usaCPFComoFidelidade = false;

		criarFidelidadesTodasEmpresas(clienteGravar, empresas, cliente, usaCPFComoFidelidade);

		clienteGravar.setNombcliente(cliente.getNome());

		if (isImportacaoPolicial) {
			if (!StringUtils.isEmpty(cliente.getRg())) {
				clienteGravar.setNumIdentificaUno(cliente.getRg());
				clienteGravar.setTipoIdentificacionUno(tipoIdentificacionUno);
			}

			List<TipoOcupacion> ls = tipoOcupacionService.buscar("POLICIAL MILITAR", null);
			if (ls == null || ls.isEmpty()) {
				return null;
			} else {
				clienteGravar.setTipoocupacionId(ls != null && !ls.isEmpty() ? ls.get(0) : null);
			}
			
		} else {
			clienteGravar.setFecnacimiento(StringUtils.isEmpty(cliente.getNascimento()) ? null : retornaDate(cliente.getNascimento()));
			clienteGravar.setDesccorreo(cliente.getEmail());

			clienteGravar.setNumfax(cliente.getFax());
			clienteGravar.setNumtelefono(cliente.getTelefone());
			clienteGravar.setNumtelefonodos(cliente.getCelular());
			clienteGravar.setIndsexo(cliente.getSexo());
			clienteGravar.setNumIdentificaUno(cliente.getCpf());
			clienteGravar.setTipoIdentificacionUno(tipoIdentificacionUno);

			if (!StringUtils.isEmpty(cliente.getRg())) {
				clienteGravar.setNumIdentificaDos(cliente.getRg());
				clienteGravar.setTipoIdentificacionDos(tipoIdentificacionDoos);
			}

			setDirecion(clienteGravar, cliente);
		}

		if (clienteGravar.getClienteId() == null) {
			clienteGravar.setFecCadastro(new Date());
			clienteService.suscribir(clienteGravar);
			inseridos = inseridos + 1;
			gravados[0] = gravados[0] + inseridos;

		} else {
			clienteService.actualizacion(clienteGravar);
			atualizados = atualizados + 1;
			gravados[1] = gravados[1] + atualizados;
		}

		return gravados;
	}

	private void setDirecion(Cliente cliente, ClienteExcelVo cExcel) {
		List<ClienteDireccion> lsDirecion = new ArrayList<ClienteDireccion>();
		ClienteDireccion direccion = new ClienteDireccion();
		if ((cliente.getLsClienteDireccion() != null)
				&& (!cliente.getLsClienteDireccion().isEmpty())) {
			if (cliente.getLsClienteDireccion().get(0) != null) {
				direccion = cliente.getLsClienteDireccion().get(0);
				cliente.getLsClienteDireccion().remove(0);
			}
		}
		direccion.setDesestado(cExcel.getEstado());
		direccion.setDesciudad(cExcel.getCidade());
		direccion.setDesccolonia(cExcel.getBairro());
		direccion.setDesccalle(cExcel.getEndereco());
		direccion.setActivo(true);
		direccion.setClienteId(cliente);
		lsDirecion.add(direccion);
		cliente.setLsClienteDireccion(lsDirecion);

	}

	private void criarFidelidadesTodasEmpresas(Cliente cliente, List<Empresa> empresas, ClienteExcelVo cExce, Boolean usaCPFComoFidelidade) {

		Boolean achou = false;
		List<ClienteFidelidad> fidelidades = null;

		if (cliente.getClienteId() == null) {
			fidelidades = new ArrayList<ClienteFidelidad>();
			for (Empresa e : empresas) {
				fidelidades.add(criarFidelidade(e, cExce, usaCPFComoFidelidade));
			}
			cliente.setListClienteFidelidad(fidelidades);

		} else {
			fidelidades = cliente.getListClienteFidelidad();
			if (fidelidades == null || fidelidades.isEmpty()) {
				for (Empresa e : empresas) {
					fidelidades.add(criarFidelidade(e, cExce, usaCPFComoFidelidade));
				}
			} else {
				for (Empresa e : empresas) {
					for (ClienteFidelidad f : fidelidades) {
						if (f.getEmpresa().equals(e)) {
							f.setActivo(true);
							f.setFecmodif(new Date());
							TarjetaFidelidad tarjetaFidelidad = f.getTarjetaFidelidad();
							if (tarjetaFidelidad != null) {
								tarjetaFidelidad.setActivo(true);
								tarjetaFidelidad.setFecmodif(new Date());
							}

							achou = true;
							break;
						}
					}
					if (!achou) {
						fidelidades.add(criarFidelidade(e, cExce, usaCPFComoFidelidade));
					}
					achou = false;
				}
			}
		}

	}

	private ClienteFidelidad criarFidelidade(Empresa e, ClienteExcelVo cExcel, Boolean usaCPFComoFidelidade) {
		ClienteFidelidad clienteFidelidad = new ClienteFidelidad();
		TarjetaFidelidad tarjetaFidelidad = new TarjetaFidelidad();
		tarjetaFidelidad.setNumTarjeta(usaCPFComoFidelidade ? cExcel.getCpf() : cExcel.getRg());
		tarjetaFidelidad.setActivo(true);
		tarjetaFidelidad.setFecmodif(Calendar.getInstance().getTime());
		tarjetaFidelidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());

		clienteFidelidad.setEmpresa(e);
		clienteFidelidad.setActivo(true);
		clienteFidelidad.setFecmodif(Calendar.getInstance().getTime());
		clienteFidelidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		clienteFidelidad.setTarjetaFidelidad(tarjetaFidelidad);

		return clienteFidelidad;
	}

	public Boolean validaDadosPlanilha(ClienteExcelVo cliente, StringBuilder erros) {

		if (!StringUtils.isEmpty(cliente.getCpf())) {
			try {
				Long.parseLong(cliente.getCpf());
				if (!validarCPF(cliente.getCpf())) {
					erros.append("CPF inválido.");
					return false;
				}
			} catch (NumberFormatException e) {
				erros.append("O CPF deve possuir apenas números.");
				return false;

			} catch (Exception e) {
				e.getMessage();
				erros.append("Erro ao obter o CPF.");
				return false;
			}

		} else {
			erros.append("O CPF e obrigatório.");
			return false;
		}

		if (StringUtils.isEmpty(cliente.getNome())) {
			erros.append("O NOME e obrigatório.");
			return false;
		}

		if (!StringUtils.isEmpty(cliente.getSexo())) {
			if (!(cliente.getSexo().equalsIgnoreCase("f") || cliente.getSexo().equalsIgnoreCase("m") || cliente.getSexo().equalsIgnoreCase("masculino") || cliente.getSexo().equalsIgnoreCase("feminino"))) {
				erros.append("Campo sexo foi informado incorretamente.");
				return false;
			}
		}

		if (!StringUtils.isEmpty(cliente.getNascimento()) && cliente.getNascimento().matches("(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)")) {
			SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
			try {
				dateFormat.parse(cliente.getNascimento());
			} catch (Exception e) {
				erros.append("Campo Nascimento foi informado incorretamente.");
				return false;
			}
		}
		return true;
	}

	private Boolean validaSheet(Sheet sheet) {

		Row row = sheet.getRow(0);
		Iterator<Cell> cellIterator = row.cellIterator();

		while (cellIterator.hasNext()) {
			Cell cell = cellIterator.next();
			switch (cell.getColumnIndex()) {
			case 0:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.cpf"))) {
					break;
				}
				return false;
			case 1:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.rg"))) {
					break;
				}
				return false;
			case 2:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.nome"))) {
					break;
				}
				return false;
			case 3:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.email"))) {
					break;
				}
				return false;

			case 4:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.telefone"))) {
					break;
				}
				return false;

			case 5:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.celular"))) {
					break;
				}
				return false;

			case 6:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.fax"))) {
					break;
				}
				return false;

			case 7:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.nascimento"))) {
					break;
				}
				return false;

			case 8:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.sexo"))) {
					break;
				}
				return false;
			case 9:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.endereco"))) {
					break;
				}
				return false;
			case 10:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.bairro"))) {
					break;
				}
				return false;
			case 11:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.cidade"))) {
					break;
				}
				return false;
			case 12:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesController.HEADERCOLUMN.estado"))) {
					break;
				}
				return false;

			}

		}
		return true;
	}

	private Boolean validaSheetImportacaoPolicial(Sheet sheet) {

		Row row = sheet.getRow(0);
		Iterator<Cell> cellIterator = row.cellIterator();

		while (cellIterator.hasNext()) {
			Cell cell = cellIterator.next();
			switch (cell.getColumnIndex()) {
			case 0:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesPolicialController.HEADERCOLUMN.nome"))) {
					break;
				}
				return false;
			case 1:
				if (cell.getStringCellValue().equalsIgnoreCase(Labels.getLabel("importarClientesPolicialController.HEADERCOLUMN.rg"))) {
					break;
				}
				return false;
			}
		}
		return true;
	}

	private Date retornaDate(String date) throws ParseException {

		SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		Date data = null;
		data = (Date) dateFormat.parse(date);
		return data;

	}

	private Boolean validarCPF(String numDoc) {
		try {
			// https://dicasdeprogramacao.com.br/algoritmo-para-validar-cpf
			// O VAlidador não pegava os CPFs com todos os numeros iguais
			if (numDoc.length() != 11 || numDoc.equals("00000000000") || numDoc.equals("11111111111") || numDoc.equals("22222222222") ||
					numDoc.equals("33333333333") || numDoc.equals("44444444444") || numDoc.equals("55555555555") ||
					numDoc.equals("66666666666") || numDoc.equals("77777777777") || numDoc.equals("88888888888") ||
					numDoc.equals("99999999999")) {
				return false;
			}

			Cpf cpf = new Cpf(numDoc);
			if (!cpf.isValid()) {
				return false;
			}
		} catch (ValidationException e) {
			return false;
		}

		return true;
	}

	@Override
	public String[] lerArquivoPolicialExcel(Media media, List<Empresa> empresas) {

		List<TipoIdentificacion> lsTipoIdentificacion = tipoIdentificacionService.obtenerTodos();
		TipoIdentificacion tipoIdentificacionUno = null;

		for (TipoIdentificacion t : lsTipoIdentificacion) {

			if (t.getDesctipo().equalsIgnoreCase("rg")) {
				tipoIdentificacionUno = t;
			}
			if (tipoIdentificacionUno != null)
				break;
		}

		Integer index = 1;
		StringBuilder qtdeGravados = new StringBuilder();
		StringBuilder erros = new StringBuilder();
		Integer inseridos = 0;
		Integer atualizados = 0;
		Integer desconsiderados = 0;
		InputStream isMExcel = media.getStreamData();
		Sheet sheet = null;

		if (media.getFormat().equals("xls")) {
			HSSFWorkbook wb;
			try {
				wb = new HSSFWorkbook(isMExcel);
				sheet = wb.getSheetAt(0);
			} catch (IOException e) {
				e.printStackTrace();
			}

		} else if (media.getFormat().equals("xlsx")) {
			XSSFWorkbook wb;
			try {
				wb = new XSSFWorkbook(isMExcel);
				sheet = wb.getSheetAt(0);
			} catch (IOException e) {
				log.error("", e);
			}
		}

		int rows = sheet.getPhysicalNumberOfRows();

		log.info(String.format("Quantidade cliente:%s", rows));

		if (validaSheetImportacaoPolicial(sheet)) {

			try {
				for (index = 1; index < rows; index++) {
					log.info(String.format("index cliente:%s", index));

					Row row = sheet.getRow(index);
					if (row == null) {
						log.info("index/row empty");
						continue;
					}

					Iterator<Cell> cellIterator = row.cellIterator();
					ClienteExcelVo cliente = new ClienteExcelVo();

					while (cellIterator.hasNext()) {
						Cell cell = cellIterator.next();
						switch (cell.getColumnIndex()) {
						case 0:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setNome(cell.getStringCellValue());
							break;
						case 1:
							cell.setCellType(Cell.CELL_TYPE_STRING);
							cliente.setRg(cell.getStringCellValue());
							break;
						}
					}
					log.info(String.format("cliente:%s rg:%s", cliente.getNome(), cliente.getRg()));

					log.info("enviado para gravação...");
					try {
						Integer[] gravados = salvarClienteExcel(empresas, false, cliente, tipoIdentificacionUno, null, true);
						inseridos = gravados[0] + inseridos;
						atualizados = gravados[1] + atualizados;
						desconsiderados = gravados[2] + desconsiderados;
					} catch (Throwable e) {
						log.error("Erro na gravação do registro. Favor revisar", e);
						log.info("continuando importação");
					}

				}
				qtdeGravados.append("Gravados ").append(inseridos + atualizados).append(" clientes de ").append(index - 1).append(" importados.\n");
				qtdeGravados.append("Desconsiderados ").append(desconsiderados).append(" clientes.\n");
				qtdeGravados.append("Atualizados ").append(atualizados).append(" clientes.\n");
				qtdeGravados.append("Inseridos ").append(inseridos).append(" novos clientes.");
				String[] resultado = { qtdeGravados.toString(), erros.toString() };

				log.info("importação finalizada");

				return resultado;

			} catch (ArrayIndexOutOfBoundsException e) {
				e.printStackTrace();
				String msg = "Erro ao gravar cliente na linha " + (index + 1) + " do arquivo.";
				erros.append(msg);
				String[] resultado = { "Houve erro ao gravar os clientes, consulte o arquivo de erros.", erros.toString() };
				return resultado;
			} catch (Exception e) {
				e.printStackTrace();
				erros.append("Linha ").append(index).append(" do arquivo de clientes, erro: ").append(e.getCause().getCause()).append("\n");
				String[] resultado = { "Houve erro ao gravar os clientes, consulte o arquivo de erros.", erros.toString() };
				return resultado;
			}

		} else {
			erros.append("A estrutura do arquivo esta com erro ").append("\n");
			String[] resultado = { "Houve erro ao gravar os clientes, consulte o arquivo de erros.", erros.toString() };
			return resultado;
		}

	}

}
