package br.com.centralit.citcorpore.ajaxForms;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import br.com.centralit.citajax.html.AjaxFormAction;
import br.com.centralit.citajax.html.DocumentHTML;
import br.com.centralit.citajax.html.HTMLElement;
import br.com.centralit.citajax.html.HTMLForm;
import br.com.centralit.citajax.html.HTMLSelect;
import br.com.centralit.citcorpore.bean.RequisitosNivelServicoDTO;
import br.com.centralit.citcorpore.bean.UploadDTO;
import br.com.centralit.citcorpore.negocio.RequisitosNivelServicoService;
import br.com.centralit.citcorpore.util.Enumerados.AuditoriaAcoes;
import br.com.centralit.citcorpore.util.Enumerados.CampoUpload;
import br.com.centralit.citcorpore.util.Enumerados.PagesPortfolio;
import br.com.centralit.citcorpore.util.Enumerados.TipoAnexoRequisitosNivelServico;
import br.com.centralit.citcorpore.util.Permissoes;
import br.com.centralit.citcorpore.util.WebUtil;
import br.com.centralit.citged.bean.ControleGEDDTO;
import br.com.centralit.citged.negocio.ControleGEDService;
import br.com.citframework.excecao.PersistenceException;
import br.com.citframework.excecao.ServiceException;
import br.com.citframework.service.ServiceLocator;
import br.com.citframework.util.UtilI18N;
import br.com.citframework.util.UtilListas;
import br.com.citframework.util.UtilNumbersAndDecimals;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class GerenciamentoPortfolioRNS extends AjaxFormAction {
	private RequisitosNivelServicoService service;
	private ControleGEDService controleGEDService;
	private static Permissoes permissao;


	@Override
	public Class getBeanClass() {
		return RequisitosNivelServicoDTO.class;
	}

	@Override
	public void load(final DocumentHTML document, final HttpServletRequest request, final HttpServletResponse response) throws Exception {
		if (!WebUtil.validarSeUsuarioEstaNaSessao(request, document)) {
			return;
		}
		setPermissoesRNS(document, request);
		RequisitosNivelServicoDTO beanDto = (RequisitosNivelServicoDTO) document.getBean();
		this.carregarDadosComboTipoDeAnexoRNS(document, request, response);
		request.getSession(true).setAttribute(CampoUpload.UPLOADREQUISITOSNIVELSERVICO.getColUploadGED(), null);

		if (beanDto != null && !UtilNumbersAndDecimals.isNull(beanDto.getIdServicoNegocio())) {
			restoreRequisitosNivelServico(beanDto, document, request);
		}
		document.executeScript("uploadRequisitosNivelServico.refresh();");
	}
	
	private void setPermissoesRNS(DocumentHTML document, HttpServletRequest request) throws Exception {
		permissao = new Permissoes(document, request, PagesPortfolio.SERVICO_NEGOCIO_REQUISICAO_SERVICO.getCaminho());
	}

	public void reloadAnexos(final DocumentHTML document, final HttpServletRequest request,
			final HttpServletResponse response) throws Exception {
		RequisitosNivelServicoDTO beanDto = (RequisitosNivelServicoDTO) document.getBean();

		restaurarAnexos(document, request, beanDto);
		document.executeScript("afterReloadAnexosRNS()");
	}

	private void carregarDadosComboTipoDeAnexoRNS(final DocumentHTML document, final HttpServletRequest request,
			final HttpServletResponse response) throws Exception {
		final HTMLSelect combo = document.getSelectById("campoSelect_uploadRequisitosNivelServico");
		this.iniciarCombo(document, request, combo);
		for (final TipoAnexoRequisitosNivelServico tipoAnexo : TipoAnexoRequisitosNivelServico.values()) {
			combo.addOption(tipoAnexo.getIdentificador(), UtilI18N.internacionaliza(request, tipoAnexo.getChave()));
		}
	}

	private void iniciarCombo(final DocumentHTML document, final HttpServletRequest request, final HTMLSelect combo) throws Exception {
		combo.removeAllOptions();
		combo.addOption("", UtilI18N.internacionaliza(request, "citcorpore.comum.selecioneTipoDeAnexo"));
	}

	public void save(final DocumentHTML document, final HttpServletRequest request, final HttpServletResponse response) throws Exception {
		WebUtil.validarSeUsuarioEstaNaSessao(request, document);
		setPermissoesRNS(document, request);
		if(permissao.isGravar()) {
			RequisitosNivelServicoDTO requisitosNivelServicoDTO = (RequisitosNivelServicoDTO) document.getBean();
			try {
				Collection<UploadDTO> arquivosGED = (Collection<UploadDTO>) request.getSession(true).getAttribute(CampoUpload.UPLOADREQUISITOSNIVELSERVICO.getColUploadGED());
	
				requisitosNivelServicoDTO.setColsUploadGED(arquivosGED);
	
				String mensagem = montarMensagemDaAcao(requisitosNivelServicoDTO);
	
				if (requisitosNivelServicoDTO != null && requisitosNivelServicoDTO.getIdRequisitosNivelServico() != null) {
					requisitosNivelServicoDTO.setAcaoRequisitosNivelServicoOcorrenciaServico(AuditoriaAcoes.ALTERADO.getIdentificador());
				} else {
					requisitosNivelServicoDTO.setAcaoRequisitosNivelServicoOcorrenciaServico(AuditoriaAcoes.CRIADO.getIdentificador());
				}
	
				requisitosNivelServicoDTO = this.getService().salvar(requisitosNivelServicoDTO);
	
				if (requisitosNivelServicoDTO != null) {
					document.alert(UtilI18N.internacionaliza(request, mensagem));
					if (requisitosNivelServicoDTO.getIdRequisitosNivelServico() != null) {
						HTMLElement idRequisitosNivelServico = document.getElementById("idRequisitosNivelServico");
						idRequisitosNivelServico.setValue(requisitosNivelServicoDTO.getIdRequisitosNivelServico().toString());
						this.salvarListaArquivosAdicionadosRequisitosNivelServico(arquivosGED, document);
						this.salvarOcorrenciaServicoRequisitosNivelServico(document, request, response);
					}
				} else {
					document.alert(UtilI18N.internacionaliza(request, "MSG01"));
				}
			} catch (final Exception e) {
				e.printStackTrace();
			}
		} else {
			document.executeScript("notificacaoErro('citcorpore.comum.permissaoFuncionalidade');");
		}
	}

	private String montarMensagemDaAcao(final RequisitosNivelServicoDTO beanDto) {
		String mensagemRetorno = "MSG05";
		if (beanDto != null && beanDto.getIdRequisitosNivelServico() != null) {
			mensagemRetorno = "MSG06";
		}
		return mensagemRetorno;
	}

	private void restoreRequisitosNivelServico(RequisitosNivelServicoDTO requisitosNivelServicoDTO, final DocumentHTML document, final HttpServletRequest request)
			throws Exception {
		try {
			final Collection<RequisitosNivelServicoDTO> colRNS = this.getService().findByIdServicoNegocio(requisitosNivelServicoDTO.getIdServicoNegocio());

			if (colRNS != null && !colRNS.isEmpty()) {
				requisitosNivelServicoDTO = colRNS.iterator().next();
			}

			this.definirServicoSelecionadoNaPagina(document, requisitosNivelServicoDTO);
			this.restaurarAnexos(document, request, requisitosNivelServicoDTO);
			this.definirValoresNoFormulario(document, requisitosNivelServicoDTO);
		} catch (PersistenceException | ServiceException e) {
			e.printStackTrace();
		}
	}

	private void definirContadoresRNS(DocumentHTML document, Collection<UploadDTO> anexos) throws Exception {
		List<String> listaTipoAnexo = new ArrayList<String>();
		Map<String, TipoAnexoRequisitosNivelServico> mapColunas = montarMapaColunas();

		gerarListaDescricao(anexos, listaTipoAnexo);
		Map<String, Integer> tipoAnexoQuantidade = UtilListas.agrupaDuplicadosComQtde(listaTipoAnexo);
		montarFuncoesNasTags(document, mapColunas, tipoAnexoQuantidade);
	}

	private void gerarListaDescricao(final Collection<UploadDTO> anexos, final List<String> listaTipoAnexo) {
		for (final UploadDTO up : anexos) {
			listaTipoAnexo.add(up.getDescricao());
		}
	}

	private Map<String, TipoAnexoRequisitosNivelServico> montarMapaColunas() {
		final Map<String, TipoAnexoRequisitosNivelServico> mapColunas = new HashMap<String, TipoAnexoRequisitosNivelServico>();

		mapColunas.put("especificacaoLabel", TipoAnexoRequisitosNivelServico.ESPECIFICACAO);
		mapColunas.put("contextoLabel", TipoAnexoRequisitosNivelServico.CONTEXTO);
		mapColunas.put("funcionalidadesEssenciaisLabel", TipoAnexoRequisitosNivelServico.FUNCIONALIDADES_ESSENCIAIS);
		mapColunas.put("segurancaLabel", TipoAnexoRequisitosNivelServico.SEGURANCA);
		mapColunas.put("disponibilidadeLabel", TipoAnexoRequisitosNivelServico.DISPONIBILIDADE);
		mapColunas.put("capacidadeLabel", TipoAnexoRequisitosNivelServico.CAPACIDADE);
		mapColunas.put("continuidadeDoNegocioLabel", TipoAnexoRequisitosNivelServico.CONTINUIDADE_DO_NEGOCIO);
		mapColunas.put("performanceDesempenhoLabel", TipoAnexoRequisitosNivelServico.PERFORMANCE_DESEMPENHO);
		mapColunas.put("interrupcoesPlanejadasLabel", TipoAnexoRequisitosNivelServico.INTERRUPCOES_PLANEJADAS);
		mapColunas.put("gestaoDeIncidentesLabel", TipoAnexoRequisitosNivelServico.GESTAO_DE_INCIDENTES);
		mapColunas.put("gestaoDeProblemasLabel", TipoAnexoRequisitosNivelServico.GESTAO_DE_PROBLEMAS);
		mapColunas.put("gestaoDeMudancasLabel", TipoAnexoRequisitosNivelServico.GESTAO_DE_MUDANCAS);
		mapColunas.put("conformidadeInternaLabel", TipoAnexoRequisitosNivelServico.CONFORMIDADE_INTERNA);
		mapColunas.put("conformidadeExternaLabel", TipoAnexoRequisitosNivelServico.CONFORMIDADE_EXTERNA);

		return mapColunas;
	}

	private void montarFuncoesNasTags(final DocumentHTML document, final Map<String, TipoAnexoRequisitosNivelServico> mapColunas,
			final Map<String, Integer> tipoAnexoQuantidade) throws Exception {
		for (final String key : mapColunas.keySet()) {
			HTMLElement elemento = document.getElementById(key);
			elemento = document.getElementById(key);
			this.setQuantidadeElemento(tipoAnexoQuantidade, mapColunas.get(key), elemento);
		}
	}

	private void setQuantidadeElemento(Map<String, Integer> tipoAnexoQuantidade, TipoAnexoRequisitosNivelServico tipoAnexo, HTMLElement elemento) {
		Integer valor = tipoAnexoQuantidade.get(tipoAnexo.getIdentificador());

		if (valor != null) {
			elemento.setValue("<i class=\"lfloat material-icons md-14\">attachment</i>&nbsp".concat(valor.toString()));
			elemento.setClassName("rfloat label label-success");
			elemento.setAttributes("onmouseover", "abreTooltip(this, \"citcorpore.comum.quantidadeAnexos\")");
		} else {
			elemento.setValue("<i class=\"material-icons md-14\">attach_file</i>");
			elemento.setClassName("rfloat label label-warning");
			elemento.setAttributes("onmouseover", "abreTooltip(this, \"citcorpore.comum.adicionarAnexos\")");
		}

		elemento.setAttributes("onclick", "onClickLabelAnexosRNS(\"" + tipoAnexo.getIdentificador() + "\")");
		elemento.setAttributes("onmouseout", "fechaTooltip()");
	}

	private void restaurarAnexos(final DocumentHTML document, final HttpServletRequest request, final RequisitosNivelServicoDTO requisitosNivelServicoDTO) throws ServiceException, Exception {
		Collection<UploadDTO> colAnexosUploadDTO = new ArrayList<UploadDTO>();

		final Collection<ControleGEDDTO> colAnexos = getControleGEDService().listByIdTabelaAndID(ControleGEDDTO.TABELA_REQUISITOS_NIVEL_SERVICO,
				requisitosNivelServicoDTO.getIdRequisitosNivelServico());

		if (colAnexos != null && !colAnexos.isEmpty()) {
			colAnexosUploadDTO = getControleGEDService().convertListControleGEDToUploadDTO(colAnexos);
			definirDescricaoAnexos(request, colAnexosUploadDTO);
			request.getSession(true).setAttribute(CampoUpload.UPLOADREQUISITOSNIVELSERVICO.getColUploadGED(), colAnexosUploadDTO);
		} else {
			request.getSession(true).setAttribute(CampoUpload.UPLOADREQUISITOSNIVELSERVICO.getColUploadGED(), null);
		}

		definirContadoresRNS(document, colAnexosUploadDTO);
	}

	private void definirDescricaoAnexos(final HttpServletRequest request, Collection<UploadDTO> colAnexosUploadDTO) {
		if (colAnexosUploadDTO != null) {
			for (final UploadDTO uploadDTO : colAnexosUploadDTO) {
				if (uploadDTO.getDescricao() == null) {
					uploadDTO.setDescricao("");
				} else {
					final String descricao = UtilI18N.internacionaliza(request, TipoAnexoRequisitosNivelServico.fromTipo(uploadDTO.getDescricao())
							.getChave());
					uploadDTO.setTipoAnexoParaCombo(descricao);
				}
			}
		}
	}

	private void definirValoresNoFormulario(final DocumentHTML document, final RequisitosNivelServicoDTO requisitosNivelServicoDTO)
			throws Exception {
		final HTMLForm form = document.getForm("formRequisitosNivelServico");
		form.clear();
		form.setValues(requisitosNivelServicoDTO);
	}

	private void definirServicoSelecionadoNaPagina(final DocumentHTML document, final RequisitosNivelServicoDTO requisitosNivelServicoDTO) {
		final String idServicoSelecionadoNoPortfolio = "document.formRequisitosNivelServico.idServicoNegocio.value = ".concat(String.valueOf(requisitosNivelServicoDTO
				.getIdServicoNegocio()));
		document.executeScript(idServicoSelecionadoNoPortfolio);

		document.executeScript("document.formRequisitosNivelServico.btnLimpar.style.display = 'block';");
		if(requisitosNivelServicoDTO.getIdRequisitosNivelServico() != null){
			document.executeScript("document.formRequisitosNivelServico.btnLimpar.style.display = 'none';");
		}
	}

	private RequisitosNivelServicoService getService() throws ServiceException {
		if (this.service == null) {
			this.service = (RequisitosNivelServicoService) ServiceLocator.getInstance().getService(RequisitosNivelServicoService.class, null);
		}
		return this.service;
	}

	private ControleGEDService getControleGEDService() throws ServiceException {
		if (this.controleGEDService == null) {
			this.controleGEDService = (ControleGEDService) ServiceLocator.getInstance().getService(ControleGEDService.class, null);
		}
		return this.controleGEDService;
	}

	/**
	 * @author deborah.ferreira
	 * @since 26.01.2016
	 */
	public void salvarOcorrenciaServicoRequisitosNivelServico(DocumentHTML document, HttpServletRequest request, HttpServletResponse response) throws Exception {
		RequisitosNivelServicoDTO requisitosNivelServicoDTO = (RequisitosNivelServicoDTO) document.getBean();
		GerenciamentoPortfolioOcorrenciasServico gerenciamentoPortfolioOcorrenciasServico = new GerenciamentoPortfolioOcorrenciasServico();
		gerenciamentoPortfolioOcorrenciasServico.salvaOcorrenciaServicoRequisitoNivelServico(requisitosNivelServicoDTO, document, request);
	}

	/**
	 * @author deborah.ferreira
	 * @since 18.02.2016
	 */
	private void salvarListaArquivosAdicionadosRequisitosNivelServico(Collection<UploadDTO> listaArquivos, DocumentHTML document) throws Exception {
		RequisitosNivelServicoDTO requisitosNivelServicoDTO = (RequisitosNivelServicoDTO) document.getBean();
		String listaIdsStr = "";

		if (listaArquivos != null) {
			for (UploadDTO anexo : listaArquivos) {
				if (anexo.getTemporario().toUpperCase().equals("S")) {
					if (anexo.getIdControleGED() != null) {
						listaIdsStr += anexo.getIdControleGED() + ",";
					}
				}
			}
		}

		requisitosNivelServicoDTO.setListaIdsAnexosRequisitosNivelServicoOcorrenciaServico(listaIdsStr);
	}
}
