/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rjconsultores.ventaboletos.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.rjconsultores.ventaboletos.dao.EmpresaDAO;
import com.rjconsultores.ventaboletos.dao.EsquemaCorridaDAO;
import com.rjconsultores.ventaboletos.dao.RutaEmpresaDAO;
import com.rjconsultores.ventaboletos.entidad.ComEmpCategoria;
import com.rjconsultores.ventaboletos.entidad.ComEmpConferencia;
import com.rjconsultores.ventaboletos.entidad.ComEmpFormapago;
import com.rjconsultores.ventaboletos.entidad.ComEmpTipoEventoExtra;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.InscricaoEstadual;
import com.rjconsultores.ventaboletos.entidad.Marca;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.service.EmpresaService;
import com.rjconsultores.ventaboletos.service.LogAuditoriaService;
import com.rjconsultores.ventaboletos.service.MarcaService;
import com.rjconsultores.ventaboletos.utilerias.RegistroConDependenciaException;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.web.utilerias.security.SecurityEmpresaToken;

/**
 *
 * @author Administrador
 */
@Service("empresaService")
public class EmpresaServiceImpl implements EmpresaService {

	@Autowired
	private EmpresaDAO empresaDAO;

	@Autowired
	private MarcaService marcaService;

	@Autowired
	private RutaEmpresaDAO rutaEmpresaDAO;

	@Autowired
	private EsquemaCorridaDAO esquemaCorridaDAO;
	@Autowired
	private LogAuditoriaService logAuditoriaService;
	private static final Logger log = LogManager.getLogger(EmpresaServiceImpl.class);


	public List<Empresa> obtenerTodos() {
		return empresaDAO.obtenerTodos();
	}

	public Empresa obtenerID(Integer id) {
		
		Empresa empresa = empresaDAO.obtenerID(id);
		empresa.setToken(this.token(empresa));
		
		try {
			empresa.clonar();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return empresa;
		
	}

	@Transactional
	public Empresa suscribirActualizacion(Empresa entidad) throws BusinessException {
		ComEmpConferencia comEmpConferencia = null;
		if (entidad.getComEmpConferencias() != null && !entidad.getComEmpConferencias().isEmpty()) {
			comEmpConferencia = entidad.getComEmpConferencias().iterator().next();
		}

		entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		entidad.setFecmodif(Calendar.getInstance().getTime());
		entidad.setActivo(Boolean.TRUE);

		if (entidad.getEmpresaId() == null) {

			entidad = empresaDAO.suscribir(entidad);
			logAuditoriaService.auditar(null, entidad, null);

			entidad.setToken(this.token(entidad));

			gerarMarca(entidad);

		} else {
			try {
				Empresa empresaClone = entidad.getCloneObject();
				entidad =  empresaDAO.actualizacion(entidad);
				logAuditoriaService.auditar(empresaClone, entidad, entidad.getEmpresaId());
			} catch (Exception e) {
				log.error(e);
			}
		}

		if (comEmpConferencia != null) {
			comEmpConferencia.setEmpresa(entidad);
			suscribirOrActualizacion(comEmpConferencia);
		}

		return entidad;
	}

	private void gerarMarca(Empresa empresa) {

		Marca marca = new Marca();

		marca.setEmpresa(empresa);
		marca.setDescmarca(empresa.getNombempresa());

		marcaService.suscribir(marca);

	}

	@Transactional
	public void borrar(Empresa entidad) throws RegistroConDependenciaException {
		if ((rutaEmpresaDAO.obtenerPorEmpresa(entidad).size() > 0) ||
				(esquemaCorridaDAO.buscarPorEmpresaCorrida(entidad).size() > 0)) {
			throw new RegistroConDependenciaException();
		}

		entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		entidad.setFecmodif(Calendar.getInstance().getTime());
		entidad.setActivo(Boolean.FALSE);

		empresaDAO.actualizacion(entidad);
		logAuditoriaService.auditarExclusao(entidad,null);

	}

	public List<Empresa> buscar(String nombempresa, Boolean indExterna, Short indTipo) {
		return empresaDAO.buscar(nombempresa, indExterna, indTipo);
	}

	public List<Empresa> buscarTodosExceto(List<Empresa> empresa, Integer... idEmpresa) {
		return this.filtrarApenasEmpresasLicencaValida(empresaDAO.buscarTodosExceto(empresa, idEmpresa));
	}

	public List<Empresa> obtenerIndExternoFalse() {
		return empresaDAO.obtenerIndExternoFalse();
	}

	public List<Empresa> obtenerIndTipo2() {
		return empresaDAO.obtenerIndTipo2();
	}

	@Override
	public List<Empresa> buscarNotInPuntoVtaComissao(PuntoVenta puntoVenta) {
		return empresaDAO.buscarNotInPuntoVtaComissao(puntoVenta);

	}

	@Override
	public List<InscricaoEstadual> buscaInscricoesEstaduais(Empresa empresa) {
		return empresaDAO.buscaInscricoesEstaduais(empresa);
	}

	@Override
	public void actualizaInscEstadual(InscricaoEstadual inscricaoEstadual) {
		empresaDAO.actualizaInscEstadual(inscricaoEstadual);
	}

	@Override
	public List<Empresa> filtrarApenasEmpresasLicencaValida(List<Empresa> lsEmpresa){
		SecurityEmpresaToken security = new SecurityEmpresaToken();
		List<Empresa> lsRetorno = new ArrayList<>();
		
		if (lsEmpresa == null || lsEmpresa.isEmpty()){
			return lsEmpresa;
		}
		
		for(Empresa empresa:lsEmpresa){
			boolean licenseValidate = security.licenseValidate(empresa.getLicenca(), empresa.getEmpresaId(), empresa.getCnpj());
			if (!licenseValidate){
				log.info(String.format("Empresa sem licença válida", empresa.getEmpresaId()));
				
				continue;
			}
			lsRetorno.add(empresa);
		}
		return lsRetorno;
	}
	@Override
	public List<Empresa> buscaLike(String nombempresa) {
		List<Empresa> lsEmpresa = empresaDAO.buscaLike(nombempresa);
		
		return this.filtrarApenasEmpresasLicencaValida(lsEmpresa); 
	}

	@Override
	public ComEmpCategoria adicionarComissaoCategoria(ComEmpCategoria comEmpCategoria) {
		comEmpCategoria.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		comEmpCategoria.setFecmodif(Calendar.getInstance().getTime());
		comEmpCategoria.setActivo(Boolean.TRUE);
		return empresaDAO.adicionarComissaoCategoria(comEmpCategoria);
	}

	@Override
	public void removerComissaoCategoria(ComEmpCategoria comEmpCategoria) {
		comEmpCategoria.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		comEmpCategoria.setFecmodif(Calendar.getInstance().getTime());
		comEmpCategoria.setActivo(Boolean.FALSE);
		empresaDAO.removerComissaoCategoria(comEmpCategoria);
	}

	@Override
	public ComEmpFormapago adicionarComissaoFormapago(ComEmpFormapago comEmpFormapago) {
		comEmpFormapago.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		comEmpFormapago.setFecmodif(Calendar.getInstance().getTime());
		comEmpFormapago.setActivo(Boolean.TRUE);
		return empresaDAO.adicionarComissaoFormapago(comEmpFormapago);
	}

	@Override
	public void removerComissaoFormapago(ComEmpFormapago comEmpFormapago) {
		comEmpFormapago.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		comEmpFormapago.setFecmodif(Calendar.getInstance().getTime());
		comEmpFormapago.setActivo(Boolean.FALSE);
		empresaDAO.removerComissaoFormapago(comEmpFormapago);
	}

	@Override
	public ComEmpTipoEventoExtra adicionarComissaoTipoEventoExtra(ComEmpTipoEventoExtra comEmpTipoEventoExtra) {
		comEmpTipoEventoExtra.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		comEmpTipoEventoExtra.setFecmodif(Calendar.getInstance().getTime());
		comEmpTipoEventoExtra.setActivo(Boolean.TRUE);
		return empresaDAO.adicionarComissaoTipoEventoExtra(comEmpTipoEventoExtra);
	}

	@Override
	public void removerComissaoTipoEventoExtra(ComEmpTipoEventoExtra comEmpTipoEventoExtra) {
		comEmpTipoEventoExtra.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		comEmpTipoEventoExtra.setFecmodif(Calendar.getInstance().getTime());
		comEmpTipoEventoExtra.setActivo(Boolean.FALSE);
		empresaDAO.removerComissaoTipoEventoExtra(comEmpTipoEventoExtra);
	}

	@Override
	public List<Empresa> obtenerTodosIncluindoEmpresaTodas() {
		return empresaDAO.obtenerTodosIncluindoEmpresaTodas();
	}

	@Override
	@Transactional
	public ComEmpConferencia suscribirOrActualizacion(ComEmpConferencia comEmpConferencia) {
		comEmpConferencia.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		comEmpConferencia.setFecmodif(Calendar.getInstance().getTime());
		comEmpConferencia.setActivo(Boolean.TRUE);
		if (comEmpConferencia.getComempconferenciaId() == null) {
			return empresaDAO.suscribir(comEmpConferencia);
		} else {
			return empresaDAO.actualizacion(comEmpConferencia);
		}
	}
	
	@Override
	public String validarTokenLicensa(Empresa empresa,String tokenLicenca){
		if (tokenLicenca == null){
			return null;
		}
		try{
			SecurityEmpresaToken security = new SecurityEmpresaToken();
		
			final String license = security.tokenValidate(tokenLicenca);
			
			return license;
		}catch(Throwable th){
			log.error("Erro ao validar token",th);
		}
		
		return null;
	}
	
	@Override
	public String token(Empresa empresa){
		
		SecurityEmpresaToken security = new SecurityEmpresaToken();
		final String bodyRequest = security.bodyRequestGenerate(empresa.getEmpresaId(), empresa.getCnpj());
		final String request = security.requestGenerate(bodyRequest);
		
		return request;
	}

	@Override
	public List<Empresa> buscarEmpresaPtoVtaComissao() {
		return empresaDAO.buscarEmpresaPtoVtaComissao();
	}

	@Override
	@Transactional
	public Integer atualizarLicencaEmpresasPrimeiraVez(){
		boolean primeiraVezLicenca = empresaDAO.isPrimeiraVezLicenca();
		int cantEmpresasAtualizadas = 0;
		
		log.info(String.format("primeiraVezLicenca: %s", primeiraVezLicenca));
		
		if (primeiraVezLicenca){
			SecurityEmpresaToken security = new SecurityEmpresaToken();
			List<Empresa> lsEmpresas = empresaDAO.obtenerTodos();
			
			for(Empresa empresa:lsEmpresas){
				String licenseDefaultGenerate = security.licenseDefaultGenerate(empresa.getEmpresaId(), empresa.getCnpj());
				
				log.info(String.format("licenseDefaultGenerate: %s", licenseDefaultGenerate));
				
				empresa.setLicenca(licenseDefaultGenerate);
				
				empresaDAO.actualizacion(empresa);
				cantEmpresasAtualizadas++;
			}
			
		}
		
		return cantEmpresasAtualizadas;
	}

	@Override
	public String buscarNomeEmpresa(Integer empresaId) {		
		return empresaDAO.buscarNomeEmpresa(empresaId);
	}
}
