package com.ejie.ab78.control.expedientes;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.ejie.ab78.adaptadores.Ab79WebServiceAdaptadorService;
import com.ejie.ab78.adaptadores.ab61WebServiceAdaptadorService;
import com.ejie.ab78.clientesWS.ab61WebService.Ab61Exception;
import com.ejie.ab78.clientesWS.ab79WebService.Ab79Exception;
import com.ejie.ab78.comun.Constantes;
import com.ejie.ab78.comun.UtilDate;
import com.ejie.ab78.model.Inspeccion;
import com.ejie.ab78.model.denuncias.Denuncia;
import com.ejie.ab78.model.denuncias.ExpedienteDenuncia;
import com.ejie.ab78.model.denuncias.RelDenIns;
import com.ejie.ab78.model.expedientes.Expedientes;
import com.ejie.ab78.model.procedimientos.Procedimientos;
import com.ejie.ab78.model.terceros.DatosTerceros;
import com.ejie.ab78.model.terceros.RelExpTer;
import com.ejie.ab78.model.terceros.TiposTercero;
import com.ejie.ab78.model.usuario.Usuario;
import com.ejie.ab78.model.util.ErrorResultAjaxOperation;
import com.ejie.ab78.model.util.ResultAjaxOperation;
import com.ejie.ab78.model.util.SuccessResultAjaxOperation;
import com.ejie.ab78.service.denuncias.DenunciasService;
import com.ejie.ab78.service.denuncias.ExpedienteDenunciaService;
import com.ejie.ab78.service.denuncias.RelDenInsService;
import com.ejie.ab78.service.expedientes.ExpedientesService;
import com.ejie.ab78.service.procedimientos.ProcedureActions;
import com.ejie.ab78.service.terceros.DatosTercerosService;

/**
 * RelExpTerController  
 * 
 *  
 */

@Controller
@SessionAttributes("usuario")
@RequestMapping(value = "/denuncias/ficha-denuncia")
public class FichaExpedienteController extends ExpedienteBaseContoller {

	private static final Logger logger = LoggerFactory.getLogger(FichaExpedienteController.class);

	@Autowired
	private DenunciasService denunciasService;

	@Autowired
	private ab61WebServiceAdaptadorService ab61WebServiceService;

	@Autowired
	private Ab79WebServiceAdaptadorService inspeccionesService;

	@Autowired
	private DatosTercerosService datosTercerosService;

	@Autowired
	private RelDenInsService relDenInsService;

	@Autowired
	private ExpedientesService expedientesService;

	@Autowired
	private ExpedienteDenunciaService expedienteDenunciaService;
	
	@Override
	protected String getCurrentPage() {
		return Constantes.PESTANA_EXPEDIENTE;
	}

	@Override
	protected String getTilesPage() {
		return "fichaDenunciaFormal";
	}

	@Override
	protected void setCurrentPageModel(Model model, Expedientes initForm) {
		if (initForm.isExpedienteOficio() != null && initForm.isExpedienteOficio()) {
			model.addAttribute("showSearchIdentificador", true);
		}
		Inspeccion inspeccion = this.getExpedientesService().getInspectExpedient(initForm.getIdExpediente());
		logger.info("id Inspeccion " + inspeccion + " para el expediente " + initForm.getIdExpediente());
		if (inspeccion != null && inspeccion.getIdInspeccion() != null && inspeccion.getIdInspeccion() > 0) {
			Denuncia denuncia = (Denuncia) model.asMap().get("denuncia");
			denuncia.setIdentificadorInspeccion(inspeccion.getIdentificadorInspeccion());
			denuncia.setIdInspeccion(inspeccion.getIdInspeccion());
		}
		setListParticipantes(model, initForm);
		Boolean isEnableChangeNreg = false;
		model.addAttribute("isEnableChangeNreg", isEnableChangeNreg);
	}

	@RequestMapping(value = "/maint/{idExpediente}", method = RequestMethod.GET)
	public ModelAndView mostrarGetN(Model model, @PathVariable("idExpediente") Integer idExpediente) throws Exception {
		Expedientes expediente = new Expedientes();
		expediente.setIdExpediente(idExpediente);
		expediente = getExpedientesService().find(expediente);
		if (expediente == null) {
			return new ModelAndView("folderNoExiste");
		}
		Denuncia denuncia = new Denuncia();
		denuncia.setExpediente(new Expedientes(idExpediente));
		denuncia = getDenunciasService().findByIdExpediente(denuncia);

		model.addAttribute("denuncia", denuncia);
		// TODO modificar tipo expediente oficio
		expediente.setExpedienteOficio(false);

		return mostrar(model, expediente);
	}

	@RequestMapping(value = "/{folderId}", method = { RequestMethod.GET, RequestMethod.POST })
	public ModelAndView accessUrl(Model model, @PathVariable("folderId") String folderId, HttpSession httpSession)
			throws Exception {
		if (!folderId.matches("[0-9a-zA-Z_]+")) {
			return new ModelAndView("folderNoExiste");
		}

		Expedientes expediente = new Expedientes();
		expediente.setFolderId(folderId);
		httpSession.setAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE_MIGRADO, null);

		expediente = getExpedientesService().findByFolderId(expediente);

		httpSession.setAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE, expediente.getFolderId());

		if (null != expediente && null != expediente.getProcedimientos()
				&& null != expediente.getProcedimientos().getCodProcedureId()) {
			ProcedureActions procedureActions = getProcedureActions(expediente);
			model.addAttribute("isCloseExpediente", procedureActions.isCloseExpediente(expediente));
		}
		if (expediente == null) {
			return new ModelAndView("folderNoExiste");
		}
		return mostrar(model, expediente);
	}

	@RequestMapping(value = "/mig/{idDenuncia}", method = { RequestMethod.GET, RequestMethod.POST })
	public ModelAndView accessUrlMig(Model model, @PathVariable("idDenuncia") Integer idDenuncia,
			HttpSession httpSession) throws Exception {
		FichaExpedienteController.logger.info("accessUrlMig");
		String sessionKey = Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE_MIGRADO;
		Object lastIdDenuncia = httpSession.getAttribute(sessionKey);
		if (idDenuncia != null) {
			lastIdDenuncia = idDenuncia;
			httpSession.setAttribute(sessionKey, lastIdDenuncia);
		}
		httpSession.setAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE, null);

		if (httpSession.getAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE) != null) {
			Object folderIdUltimoExpediente = httpSession.getAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE);

			model.addAttribute("ultimoExpediente", folderIdUltimoExpediente);
		}
		if (httpSession.getAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE_MIGRADO) != null) {
			Object IdDenunciaUltimoExpediente = httpSession
					.getAttribute(Constantes.SESSIONKEY_ULTIMO_EXPEDIENTE_MIGRADO);

			model.addAttribute("IdDenunciaUltimoExpediente", IdDenunciaUltimoExpediente);
		}

		Denuncia denuncia = this.getDenunciasService().find(new Denuncia(idDenuncia));
		Expedientes expediente = new Expedientes();
		if (denuncia.getExpediente() != null) {
			expediente = getExpedientesService().find(denuncia.getExpediente());
		}
		if (expediente != null && expediente.getProcedimientos() != null
				&& Constantes.TIPO_DENUNCIA_NO_FORMAL.equals(expediente.getProcedimientos().getTipoDenuncia())) {
			return mostrar(model, expediente);
		}

		return mostrarMigrados(model, idDenuncia);
	}

	@RequestMapping(value = "/{idExpediente}", method = RequestMethod.POST)
	public ModelAndView mostrarExp(Model model, @PathVariable("idExpediente") Integer idExpediente) throws Exception {
		Expedientes expediente = new Expedientes();
		expediente.setIdExpediente(idExpediente);
		expediente = getExpedientesService().find(expediente);

		if (expediente == null) {
			return new ModelAndView("folderNoExiste");
		}

		return mostrar(model, expediente);
	}

	@RequestMapping(value = "/maint", method = RequestMethod.GET)
	public ModelAndView mostrarMaint(Model model, Usuario usuario) throws Exception {
		return new ModelAndView("folderError");
	}

	/**
	 * @param model
	 *            Model
	 * @param initForm
	 *            initForm
	 * 
	 * @return ModelAndView
	 * @throws Exception
	 */
	@RequestMapping(value = "/maint", method = RequestMethod.POST)
	public ModelAndView mostrarInit(Model model, Usuario usuario) throws Exception {
		return new ModelAndView("folderError");

	}

	@RequestMapping(value = "/guardar/{idExpediente}", method = RequestMethod.POST)
	public @ResponseBody ResultAjaxOperation guardar(@RequestBody Denuncia denuncia, HttpServletRequest request,
			@PathVariable("idExpediente") Integer idExpediente) {
		try {
			Expedientes expediente = new Expedientes();
			expediente.setIdExpediente(idExpediente);
			expediente = getExpedientesService().find(expediente);

			denuncia.setExpediente(expediente);
			// Se guarda la informacion modificada de la ficha
			return super.saveExpediente(denuncia, request);
		} catch (Exception e) {
			logger.error("errorGenerico: ", e.getMessage(), e);
			return new ErrorResultAjaxOperation("errorGenerico", e.getMessage());
		}

	}

	@RequestMapping(value = "/guardar/mig/{idDenuncia}", method = RequestMethod.POST)
	public @ResponseBody ResultAjaxOperation guardarMigrados(@PathVariable("idDenuncia") Integer idDenuncia,
			@RequestBody Denuncia denuncia) {
		try {
			// Se guarda la informacion modificada de la ficha
			return super.saveDenuncia(denuncia);
		} catch (Exception e) {
			logger.error("errorGenerico: ", e.getMessage(), e);
			return new ErrorResultAjaxOperation(Constantes.ERROR_GENERICO_GUARDADO, e.getMessage());
		}

	}

	@RequestMapping(value = "/procesar/{idExpediente}", method = RequestMethod.POST)
	public @ResponseBody ResultAjaxOperation procesar(HttpServletRequest request,
			@PathVariable("idExpediente") Integer idExpediente,
			@RequestParam(value = "fechaSugerida", required = false) Date fechaSugerida) {
		try {
			Expedientes expediente = new Expedientes();
			expediente.setIdExpediente(idExpediente);
			expediente = getExpedientesService().find(expediente);

			// Se guarda la informacion modificada de la ficha
			// return super.save(expediente, request, true);
			return null;
		} catch (Exception e) {
			logger.error("errorGenerico: ", e.getMessage(), e);
			return new ErrorResultAjaxOperation("errorGenerico", e.getMessage());
		}

	}

	@RequestMapping(value = "/pendientes/{idExpediente}", method = RequestMethod.GET)
	public @ResponseBody ResultAjaxOperation checkExpedientes(@PathVariable("idExpediente") Integer idExpediente) {
		List<Expedientes> expedientes = null;
		try {
			expedientes = this.getExpedientesService().findExpedientesPendientesByExpediente(idExpediente);
		} catch (Exception e) {
			return new ErrorResultAjaxOperation("errorGenerico", e.getMessage());
		}
		SuccessResultAjaxOperation success = new SuccessResultAjaxOperation("expPendientes");
		HashMap<String, String> data = new HashMap<String, String>();
		for (Expedientes expediente : expedientes) {
			Integer idExp = expediente.getIdExpediente();
			if (!idExp.equals(idExpediente)) {
				StringBuilder token = new StringBuilder();
				token.append(expediente.getTitulo());
				token.append("#");
				token.append(expediente.getProcedimientos().getDescripcionEs());
				token.append("#");
				token.append(expediente.getProcedimientos().getDescripcionEu());
				token.append("#");
				token.append(expediente.getFolderNumber());
				token.append("#");
				token.append(
						UtilDate.convertirFechaEnString(expediente.getFechaRegistro(), "dd-MM-yyyy", "yyyy-MM-dd"));
				data.put(expediente.getFolderId(), token.toString());
			}
		}
		if (data.isEmpty()) {
			success.setMessage("sinExpPendientes");
		}
		success.setData(data);
		return success;
	}

	@RequestMapping(value = "/inspecciones/{idExpediente}/{numDenuncia}", method = RequestMethod.POST)
	public @ResponseBody ResultAjaxOperation inspecciones(@PathVariable("idExpediente") Integer idExpediente,
			@PathVariable("numDenuncia") String numDenuncia,
			@RequestParam(value = "fechaLimite", required = false) Date fechaLimite,
			@RequestParam(value = "o", required = false) String observaciones) {
		try {
			Expedientes expediente = new Expedientes();
			expediente.setIdExpediente(idExpediente);
			expediente = getExpedientesService().find(expediente);

			String identInspeccion = inspeccionesService.crearInspeccion(expediente, fechaLimite, observaciones,
					numDenuncia);

			if (identInspeccion != null && identInspeccion.indexOf("Exception") == -1) {
				SuccessResultAjaxOperation successResultAjaxOperation = new SuccessResultAjaxOperation(
						"inspeccionSuccess");

				if (Constantes.TIPO_DENUNCIA_FORMAL.equals(expediente.getProcedimientos().getTipoDenuncia())) {
					Inspeccion inspeccion = this.getExpedientesService()
							.getInspectExpedient(expediente.getIdExpediente());
					successResultAjaxOperation.getData().put("idInspeccion",
							String.valueOf(inspeccion.getIdInspeccion()));

				} else if (Constantes.TIPO_DENUNCIA_NO_FORMAL
						.equals(expediente.getProcedimientos().getTipoDenuncia())) {
					RelDenIns relDenIns = this.relDenInsService.findByIdentificadorInspeccion(identInspeccion);
					successResultAjaxOperation.getData().put("idInspeccion",
							String.valueOf(relDenIns.getIdInspeccion()));
				}

				successResultAjaxOperation.getData().put("identInspeccion", identInspeccion);
				successResultAjaxOperation.setCallback("disableButtonsInspecSuccess");
				return successResultAjaxOperation;
			}
			return new ErrorResultAjaxOperation("errorInspecciones");
		} catch (Exception e) {
			logger.error("errorGenerico: ", e.getMessage(), e);
			return new ErrorResultAjaxOperation("errorInspecciones", e.getMessage());
		}

	}

	@RequestMapping(value = "/inspecciones/eliminarInspeccion/{idExpediente}", method = RequestMethod.POST)
	public @ResponseBody ResultAjaxOperation eliminarInspeccion(@PathVariable Integer idExpediente,
			@ModelAttribute("usuario") Usuario usuario) throws Ab79Exception {
		ResultAjaxOperation operacion = null;
		try {
			
			String identificadorInspeccion = "";
			
			Expedientes expediente = this.expedientesService.find(new Expedientes(idExpediente));
			if(expediente != null && expediente.getProcedimientos() != null 
					&& expediente.getProcedimientos().getTipoDenuncia() != null && expediente.getProcedimientos().getTipoDenuncia().equals(Constantes.TIPO_DENUNCIA_FORMAL)){
				
				Inspeccion inspeccion = this.getExpedientesService().getInspectExpedient(idExpediente);	
				
				identificadorInspeccion = inspeccion.getIdentificadorInspeccion();
			}else if(expediente != null && expediente.getProcedimientos() != null 
					&& expediente.getProcedimientos().getTipoDenuncia() != null && expediente.getProcedimientos().getTipoDenuncia().equals(Constantes.TIPO_DENUNCIA_NO_FORMAL)){
				
				ExpedienteDenuncia expedienteDenuncia = new ExpedienteDenuncia();
				expedienteDenuncia.setIdExpediente(idExpediente.longValue());

				List<ExpedienteDenuncia> listado = this.expedienteDenunciaService.findAllLike(expedienteDenuncia, null, false);
				if(listado != null && !listado.isEmpty()){
					expedienteDenuncia = listado.get(0);
				}
				
				RelDenIns relDenIns = relDenInsService.findByNumDenuncia(expedienteDenuncia.getNumDenunciaFormateado());
				identificadorInspeccion = (relDenIns != null ? relDenIns.getIdentificadorInspeccion() : null);
			}
			
			
			String respuesta = "";
			if(identificadorInspeccion != null && !identificadorInspeccion.equals("")){
				
				respuesta = this.inspeccionesService.eliminarInspeccion(identificadorInspeccion,
						usuario.getNombreUsuario());
			}
			
			if ("ok".equalsIgnoreCase(respuesta)) {
				operacion = new SuccessResultAjaxOperation("inspeccionEliminada");
			} else {
				operacion = new ErrorResultAjaxOperation("inspeccionNoEliminada");
			}
		} catch (Ab79Exception e) {
			logger.error("eliminarInspeccion - ERROR", e);
			String error = e.getMessage();
			operacion = new ErrorResultAjaxOperation(error);
		}
		return operacion;
	}

	@RequestMapping(value = "/origen", method = RequestMethod.GET)
	public @ResponseBody List<Expedientes> findExpedientesOrigen(
			@RequestParam(value = "identificadorEstablecimiento", required = false) String identificadorEstablecimiento) {
		if (identificadorEstablecimiento == null) {
			return new ArrayList<Expedientes>();
		}
		return this.getExpedientesService().findAllExpedientesOrigen(identificadorEstablecimiento);
	}

	@RequestMapping(value = "/insertarParticipacion", method = RequestMethod.POST)
	public @ResponseBody ResultAjaxOperation insertarParticipacion(@RequestParam("folderId") String folderId,
			@RequestParam("idTercero") Integer idTercero, @RequestParam("idExpediente") Integer idExpediente)
			throws Ab61Exception {
		ResultAjaxOperation operacion = null;
		try {
			String participantId = ab61WebServiceService.insertarParticipacion(folderId, idTercero, "Partes inculpadas",
					"Alderdi erruztakoak");

			DatosTerceros datosTerceros = this.datosTercerosService.find(idTercero);
			datosTerceros.setIdTercero(null);

			DatosTerceros datosTercerosClone = this.datosTercerosService.add(datosTerceros);

			RelExpTer participacion = new RelExpTer();

			participacion.setIdExpediente(idExpediente);
			participacion.setDatosTerceros(datosTercerosClone);
			participacion.setTiposTercero(new TiposTercero(new Long(Constantes.ID_TIPO_TERCERO_AFECTADO)));
			participacion.setParticipantId(participantId);
			participacion.setIdSubtipo(Constantes.PARTICIPACION_SOLICITANTE);

			this.getRelExpTerService().add(participacion);

		} catch (Ab61Exception e) {
			logger.error("insertarParticipacion - ERROR", e);
			String error = e.getMessage();
			operacion = new ErrorResultAjaxOperation(error);
		}
		return operacion;
	}

	@RequestMapping(value = "/insertarParteInculpada", method = RequestMethod.POST)
	public @ResponseBody ResultAjaxOperation insertarParteInculpada(@RequestParam("idTercero") Integer idTercero,
			@RequestParam("idExpediente") Integer idExpediente) throws Exception {
		ResultAjaxOperation operacion = null;
		try {
			RelExpTer participacion = this.getRelExpTerService().getRelExpTerByExpTercero(idExpediente, idTercero);

			participacion.setIdSubtipo(Constantes.PARTICIPACION_SOLICITANTE);

			this.getRelExpTerService().updateSubtipo(participacion);

		} catch (Exception e) {
			logger.error("insertarParticipacion - ERROR", e);
			String error = e.getMessage();
			operacion = new ErrorResultAjaxOperation(error);
		}
		return operacion;
	}

	@Override
	public DenunciasService getDenunciasService() {
		return denunciasService;
	}

	@Override
	public void setDenunciasService(DenunciasService denunciasService) {
		this.denunciasService = denunciasService;
	}
}
