package com.ejie.ab63.service.procedimientos;

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

import com.ejie.ab63.comun.Constantes;
import com.ejie.ab63.model.Establecimiento;
import com.ejie.ab63.model.expedientes.Expedientes;
import com.ejie.ab63.model.inicio.InitForm;
import com.ejie.ab63.model.procedimientos.Procedimientos;
import com.ejie.ab63.model.procedimientos.ProcedimientosRelacionados;
import com.ejie.ab63.model.terceros.DatosDirecciones;
import com.ejie.ab63.service.EstablecimientoService;
import com.ejie.ab63.service.expedientes.DetailExpedienteService;
import com.ejie.ab63.service.expedientes.ExpedientesService;
import com.ejie.ab63.service.terceros.DatosDireccionesService;

/**
 * 
 *  
 *
 */
public abstract class BaseProcedureActions implements ProcedureActions {

	private String procedimiento;

	private DetailExpedienteService detailExpedienteService;

	protected BaseProcedureActions(String procedimiento, DetailExpedienteService detailExpedienteService) {
		this.procedimiento = procedimiento;
		this.detailExpedienteService = detailExpedienteService;
	}

	public abstract Map<String, String> executeAction(InitForm form);

	public abstract String getButtonsText(InitForm form);

	@Override
	public Boolean hasSecondButton(InitForm form) {
		return false;
	}

	protected Map<String, String> registroEstablecimientoProvisional(InitForm initForm) {
		return registroEstablecimiento(initForm, Constantes.TIPO_REGISTRO_PROVISIONAL);
	}

	/**
	 * Registra los establecimiento nuevos apartir de los temporales.
	 * 
	 * @param form
	 * @param tipoRegistro
	 * @return
	 */
	protected Map<String, String> registroEstablecimiento(InitForm form, String tipoRegistro) {
		EstablecimientoService establecimientoService = this.detailExpedienteService.getEstablecimientoService();
		DatosDireccionesService datosDireccionesService = this.detailExpedienteService.getDatosDireccionesService();

		String identificadorDefinitivo = establecimientoService.getNewIntetificador(tipoRegistro,
				form.getTipoEstablecimiento(), form);
		Date fechaSugerida = new Date();
		if (!form.getMapExtraDataForm().isEmpty()
				&& form.getMapExtraDataForm().containsKey(Constantes.EXTRA_FORM_FECHA_SUGERIDA)) {
			fechaSugerida = (Date) form.getMapExtraDataForm().get(Constantes.EXTRA_FORM_FECHA_SUGERIDA);
		}
		establecimientoService.registrarEstablecimientoCenso(form.getIdExpediente(), tipoRegistro,
				identificadorDefinitivo, fechaSugerida);

		// Actualiza la direccion del expediente
		DatosDirecciones datosDirecciones = this.findDireccioneEstablecimiento(form);
		datosDirecciones.setIdentificadorEstablecimiento(identificadorDefinitivo);
		datosDireccionesService.update(datosDirecciones);

		// Se busca la direccion del establecimiento y se iguala con los datos
		// del expediente
		DatosDirecciones datosDireccionesCenso = datosDireccionesService.findDireccionEstablecimiento(
				establecimientoService.findByIdenticadorEstablecimiento(identificadorDefinitivo),
				Constantes.ID_DIRECCION_ACTIVIDAD);
		datosDirecciones.setIdDireccion(datosDireccionesCenso.getIdDireccion());
		datosDirecciones.setIdentificadorEstablecimiento(null);
		datosDirecciones.setDatosTerceros(datosDireccionesCenso.getDatosTerceros());
		datosDireccionesService.update(datosDirecciones);

		if (Constantes.TIPO_REGISTRO_DEFINITIVO.equalsIgnoreCase(tipoRegistro)) {
			Establecimiento establecimientoCensado = establecimientoService
					.findByIdenticadorEstablecimiento(identificadorDefinitivo);
			establecimientoCensado.setDescrNombre(datosDirecciones.getEstablecimiento());
			establecimientoService.updateEstablecimientoDescNombre(establecimientoCensado);
		}
		HashMap<String, String> data = new HashMap<String, String>(5);
		form.setIdentificadorEstablecimiento(identificadorDefinitivo);
		data.put(Constantes.KEY_IDENTIFICADOR_DEFINITIVO, identificadorDefinitivo);
		data.put(Constantes.KEY_AJAX_CALLBACK, Constantes.KEY_FUNC_SHOW_IDENTIFICADORES);
		return data;
	}

	/**
	 * Los expediente que indicaron un identificador, son asociados al
	 * establecimiento
	 * 
	 * @param initForm
	 * @return
	 */
	protected Map<String, String> asociarEstablecimientoTemporal(InitForm initForm) {
		EstablecimientoService establecimientoService = this.detailExpedienteService.getEstablecimientoService();
		DatosDireccionesService datosDireccionesService = this.detailExpedienteService.getDatosDireccionesService();

		Establecimiento establecimiento = establecimientoService
				.findEstablecimientoByIdExpediente(initForm.getIdExpediente());
		establecimiento.setFechaBaja(new Date());
		// establecimiento.setIdExpediente(null);
		establecimientoService.update(establecimiento);

		DatosDirecciones datosDirecciones = datosDireccionesService
				.find(new DatosDirecciones(initForm.getIdDireccionExpediente()));
		datosDirecciones.setIdentificadorEstablecimiento(initForm.getIdentificadorEstablecimiento());
		datosDireccionesService.update(datosDirecciones);

		HashMap<String, String> data = new HashMap<String, String>(5);
		data.put(Constantes.KEY_IDENTIFICADOR_DEFINITIVO, initForm.getIdentificadorEstablecimiento());
		return data;
	}

	public Boolean isEnableSaveExpediente(InitForm initForm) {
		Boolean result = true;
		Expedientes expediente = new Expedientes();
		expediente.setIdExpediente(initForm.getIdExpediente());
		expediente = this.detailExpedienteService.getExpedientesService().find(expediente);

		if (expediente == null) {
			result = false;
		}
		// Si el expediente ya esta cerrado no se puede guardar
		if (result && this.detailExpedienteService.getExpedientesService().checkIsClosed(expediente)) {
			result = false;
		}
		if (result && initForm.getProcedureId() == null) {
			result = false;
		}
		if (result && (initForm.getIdTerceroTitular() == null || initForm.getIdTerceroTitular() == 0)) {
			result = false;
		}
		return result && isTipoRegistroTemp(initForm);
	}

	protected boolean isEmptyIdentificador(InitForm initForm) {
		return initForm.isIdentificadorEmpty();
	}

	protected boolean isTipoRegistroTemp(InitForm initForm) {
		return initForm.isTipoRegistro(Constantes.TIPO_REGISTRO_TEMPORAL);
	}

	public Boolean isEnableAccessCenso(InitForm form) {
		return !isEmptyIdentificador(form);
	}

	public Boolean isEnableCreateDocs(InitForm form) {
		return true;
	}

	public String getProcedimiento() {
		return procedimiento;
	}

	public void setProcedimiento(String procedimiento) {
		this.procedimiento = procedimiento;
	}

	public DetailExpedienteService getDetailExpedienteService() {
		return detailExpedienteService;
	}

	public void setDetailExpedienteService(DetailExpedienteService detailExpedienteService) {
		this.detailExpedienteService = detailExpedienteService;
	}

	@Override
	public List<String> getPestanaConfig() {
		return Constantes.getMapPestanasByProcedure().get(procedimiento);
	}

	@Override
	public Boolean isEnableShowUbicacionEstablecimiento(InitForm form) {
		return true;
	}

	@Override
	public Boolean isEnableAccessInspecciones(InitForm form) {
		return this.getDetailExpedienteService().getExpedientesService().hasInspectExpedient(form.getIdExpediente());
	}

	@Override
	public Boolean isEnableInspect(InitForm form) {
		Boolean isEnableSend = !this.getDetailExpedienteService().getExpedientesService()
				.hasInspectExpedient(form.getIdExpediente());
		return !form.isIdentificadorEmpty() && isEnableSend;
	}

	@Override
	public Boolean isInspectionable(InitForm form) {
		Procedimientos procedimiento = new Procedimientos();
		String procedimientoId = form.getProcedureId();
		int idProcedimiento = Integer.parseInt(procedimientoId);
		procedimiento.setIdProcedimiento(idProcedimiento);

		ProcedimientosService procedimientoService = this.getDetailExpedienteService().getProcedimientosService();
		procedimiento = procedimientoService.find(procedimiento);
		String inspeccionable = procedimiento.getInspeccionable();
		return "1".equals(inspeccionable);
	}

	public Boolean isCloseExpediente(InitForm form) {
		// pasarle el expediente me devuelve si esta cerrado o no
		ExpedientesService expedientesService = this.detailExpedienteService.getExpedientesService();
		return expedientesService.checkIsClosed(new Expedientes(form.getIdExpediente()));
	}

	public Boolean hasProcedimientoInicioOficio(InitForm form) {
		Procedimientos procedimiento = new Procedimientos();
		String procedimientoId = form.getProcedureId();
		int idProcedimiento = Integer.parseInt(procedimientoId);
		procedimiento.setIdProcedimiento(idProcedimiento);

		ProcedimientosService procedimientoService = this.getDetailExpedienteService().getProcedimientosService();

		List<ProcedimientosRelacionados> procedimientoList = procedimientoService.findRelInicioOficio(procedimiento);

		if (procedimientoList.size() > 0) {
			return true;
		} else {
			return false;
		}
	}

}
