package br.com.centralit.citcorpore.negocio;

import java.util.Collection;

import br.com.centralit.bpm.negocio.ItemTrabalho;
import br.com.centralit.bpm.util.Enumerated;
import br.com.centralit.citcorpore.bean.DespesaViagemDTO;
import br.com.centralit.citcorpore.bean.IntegranteViagemDTO;
import br.com.centralit.citcorpore.bean.RequisicaoViagemDTO;
import br.com.centralit.citcorpore.bean.RoteiroViagemDTO;
import br.com.centralit.citcorpore.bean.SolicitacaoServicoDTO;
import br.com.centralit.citcorpore.bean.TipoMovimFinanceiraViagemDTO;
import br.com.centralit.citcorpore.integracao.DespesaViagemDAO;
import br.com.centralit.citcorpore.integracao.IntegranteViagemDao;
import br.com.centralit.citcorpore.integracao.RequisicaoViagemDAO;
import br.com.centralit.citcorpore.integracao.RoteiroViagemDAO;
import br.com.centralit.citcorpore.negocio.alcada.AlcadaRequisicaoViagem;
import br.com.centralit.citcorpore.util.Enumerados;
import br.com.centralit.citcorpore.util.Enumerados.ServiceRequestStatus;
import br.com.citframework.dto.IDto;
import br.com.citframework.excecao.LogicException;
import br.com.citframework.integracao.CrudDAO;
import br.com.citframework.integracao.TransactionControler;
import br.com.citframework.service.ServiceLocator;
import br.com.citframework.util.UtilDatas;
import br.com.citframework.util.WebUtil;

@SuppressWarnings("unchecked")
public class CompraViagemServiceEjb extends ComplemInfSolicitacaoServicoServiceEjb implements CompraViagemService {

	@Override
	@SuppressWarnings("rawtypes")
    protected CrudDAO getDao() {
        return null;
    }

    @Override
    public IDto deserializaObjeto(final String serialize) throws Exception {
        DespesaViagemDTO despesaViagemDTO = null;

        if (serialize != null) {
            despesaViagemDTO = (DespesaViagemDTO) WebUtil.deserializeObject(DespesaViagemDTO.class, serialize);
        }

        return despesaViagemDTO;
    }

    @Override
    public void validaCreate(final SolicitacaoServicoDTO solicitacaoServicoDto, final IDto model) throws Exception {

    }

    @Override
    public void validaDelete(final SolicitacaoServicoDTO solicitacaoServicoDto, final IDto model) throws Exception {

    }

    @Override
    public void validaUpdate(final SolicitacaoServicoDTO solicitacaoServicoDto, final IDto model) throws Exception {

    }

    @Override
    public IDto create(final TransactionControler tc, final SolicitacaoServicoDTO solicitacaoServicoDto, final IDto model) throws Exception {
        return null;
    }

    @Override
    public void update(final TransactionControler tc, final SolicitacaoServicoDTO solicitacaoServicoDto, final IDto model) throws Exception {
        final RequisicaoViagemDAO requisicaoViagemDao = new RequisicaoViagemDAO();
        TipoMovimFinanceiraViagemDTO tipoMovimFinanceiraViagemDTO = new TipoMovimFinanceiraViagemDTO();
        final TipoMovimFinanceiraViagemService tipoMovimFinanceiraViagemService = (TipoMovimFinanceiraViagemService) ServiceLocator.getInstance().getService(
                TipoMovimFinanceiraViagemService.class, null);

        requisicaoViagemDao.setTransactionControler(tc);

        if (!(solicitacaoServicoDto.getAlterarSituacao().equalsIgnoreCase("S") && solicitacaoServicoDto.getDescrSituacao().equalsIgnoreCase("Cancelada"))) {
            final DespesaViagemDTO despesaViagemDTO = (DespesaViagemDTO) model;
            final DespesaViagemDAO despesaViagemDAO = new DespesaViagemDAO();
            RoteiroViagemDTO roteiroViagemDTO = new RoteiroViagemDTO();
            final RoteiroViagemDAO roteiroViagemDAO = new RoteiroViagemDAO();

            if (solicitacaoServicoDto.getIdSolicitante().intValue() == solicitacaoServicoDto.getUsuarioDto().getIdEmpregado().intValue()
                    && !(despesaViagemDTO != null && despesaViagemDTO.getCancelarRequisicao() != null && despesaViagemDTO.getCancelarRequisicao().equalsIgnoreCase("S"))) {
				throw new LogicException("Usuário sem permissão para Executar Compras!");
            }

            despesaViagemDAO.setTransactionControler(tc);

            if (despesaViagemDTO != null && despesaViagemDTO.getCancelarRequisicao() != null && despesaViagemDTO.getCancelarRequisicao().equalsIgnoreCase("S")) {
                RequisicaoViagemDTO requisicaoViagemDto = new RequisicaoViagemDTO();
                requisicaoViagemDto.setIdSolicitacaoServico(solicitacaoServicoDto.getIdSolicitacaoServico());
                requisicaoViagemDto = (RequisicaoViagemDTO) requisicaoViagemDao.restore(requisicaoViagemDto);

                if (requisicaoViagemDto.getIdSolicitacaoServico() != null) {
                    requisicaoViagemDto.setCancelarRequisicao("S");
					solicitacaoServicoDto.setIdStatus(Enumerados.ServiceRequestStatus.CANCELED.getId());
                    requisicaoViagemDao.updateNotNull(requisicaoViagemDto);

                    this.cancelaAprovacao(solicitacaoServicoDto, tc);
                    return;
                }
            }

			if (Enumerated.ACTION_EXECUTE.equalsIgnoreCase(solicitacaoServicoDto.getAcaoFluxo()) && !ServiceRequestStatus.CANCELED.getId().equals(solicitacaoServicoDto.getIdStatus())) {
				if (despesaViagemDTO.getConfirma() == null || !despesaViagemDTO.getConfirma().equalsIgnoreCase("S")) {
					throw new LogicException("Necessária a Confirmação da Compra dos Itens para Avançar o fluxo");
				}
			}

            final IntegranteViagemService integranteViagemService = (IntegranteViagemService) ServiceLocator.getInstance().getService(IntegranteViagemService.class, null);
            final IntegranteViagemDao integranteViagemDao = new IntegranteViagemDao();

            Collection<IntegranteViagemDTO> colIntegrantes = integranteViagemService.recuperaIntegrantesViagemByIdSolicitacaoEstado(
                    solicitacaoServicoDto.getIdSolicitacaoServico(), RequisicaoViagemDTO.AGUARDANDO_COMPRAS);

            if(colIntegrantes == null || colIntegrantes != null && colIntegrantes.size() <= 0) {
            	colIntegrantes = integranteViagemService.recuperaIntegrantesViagemByIdSolicitacaoEstado(
                    solicitacaoServicoDto.getIdSolicitacaoServico(), RequisicaoViagemDTO.AGUARDANDO_ADIANTAMENTO);
            }

            Collection<DespesaViagemDTO> colItens;

            DespesaViagemService despesaViagemService = (DespesaViagemService) ServiceLocator.getInstance().getService(DespesaViagemService.class, null);

            if (despesaViagemDTO.getConfirma() != null && despesaViagemDTO.getConfirma().equalsIgnoreCase("S")) {
            	boolean irParaAdiantamento = false;
                if (colIntegrantes != null) {
                	Double totalParaAdiantamento = 0d;
                    for (final IntegranteViagemDTO integrante : colIntegrantes) {
                        roteiroViagemDTO = roteiroViagemDAO.findByIdIntegrante(integrante.getIdIntegranteViagem());
                        colItens = despesaViagemDAO.listaItensCompra(solicitacaoServicoDto.getIdSolicitacaoServico(), roteiroViagemDTO.getIdRoteiroViagem());

                        totalParaAdiantamento = despesaViagemService.buscaTotalParaAdiantamento(integrante.getIdIntegranteViagem());
                        if(totalParaAdiantamento > 0) {
                        	integrante.setEstado(RequisicaoViagemDTO.AGUARDANDO_ADIANTAMENTO);
                        	irParaAdiantamento = true;
                        } else {
                        	integrante.setEstado(RequisicaoViagemDTO.AGUARDANDO_PRESTACAOCONTAS);
                        }

                        integranteViagemDao.updateNotNull(integrante);

                        if (colItens != null) {
                            for (final DespesaViagemDTO itemDespesaDto : colItens) {
                                tipoMovimFinanceiraViagemDTO.setIdtipoMovimFinanceiraViagem(itemDespesaDto.getIdTipo());
                                tipoMovimFinanceiraViagemDTO = (TipoMovimFinanceiraViagemDTO) tipoMovimFinanceiraViagemService.restore(tipoMovimFinanceiraViagemDTO);
                                if (tipoMovimFinanceiraViagemDTO.getPermiteAdiantamento().equalsIgnoreCase("N")) {
                                    itemDespesaDto.setSituacao("Comprado");
                                    itemDespesaDto.setDataHoraCompra(UtilDatas.getDataHoraAtual());
                                    itemDespesaDto.setIdResponsavelCompra(solicitacaoServicoDto.getUsuarioDto().getIdEmpregado());
                                    despesaViagemDAO.update(itemDespesaDto);
                                }
                            }
                        }
                    }
                }

                RequisicaoViagemDTO requisicaoViagemDto = new RequisicaoViagemDTO();
                requisicaoViagemDto.setIdSolicitacaoServico(solicitacaoServicoDto.getIdSolicitacaoServico());
                requisicaoViagemDto = (RequisicaoViagemDTO) requisicaoViagemDao.restore(requisicaoViagemDto);

                if (requisicaoViagemDto != null) {
                	if(irParaAdiantamento) {
	                    requisicaoViagemDto.setEstado(RequisicaoViagemDTO.AGUARDANDO_ADIANTAMENTO);
                	} else {
                		requisicaoViagemDto.setEstado(RequisicaoViagemDTO.AGUARDANDO_PRESTACAOCONTAS);
                	}

                	requisicaoViagemDao.updateNotNull(requisicaoViagemDto);
                }
            }
        } else {
            RequisicaoViagemDTO requisicaoViagemDto = new RequisicaoViagemDTO();

            requisicaoViagemDto.setIdSolicitacaoServico(solicitacaoServicoDto.getIdSolicitacaoServico());
            requisicaoViagemDto = (RequisicaoViagemDTO) requisicaoViagemDao.restore(requisicaoViagemDto);

            if (requisicaoViagemDto != null) {
                requisicaoViagemDto.setEstado(Enumerados.ServiceRequestStatus.CANCELED.name());
                requisicaoViagemDao.update(requisicaoViagemDto);

                this.cancelaAprovacao(solicitacaoServicoDto, tc);
            }
        }

    }

    @Override
    public void delete(final TransactionControler tc, final SolicitacaoServicoDTO solicitacaoServicoDto, final IDto model) throws Exception {

    }

    @Override
    public String getInformacoesComplementaresFmtTexto(final SolicitacaoServicoDTO solicitacaoDto, final ItemTrabalho itemTrabalho) throws Exception {
        return solicitacaoDto.getDescricaoSemFormatacao();
    }

    private void cancelaAprovacao(final SolicitacaoServicoDTO solicitacaoServicoDto, TransactionControler tc) throws Exception {
		new AlcadaRequisicaoViagem().cancelaAprovacao( solicitacaoServicoDto.getIdSolicitacaoServico(), tc);
    }

}
