package com.mx.dla.dda.admin.presupuestos.actions;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.executor.result.ResultMapException;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;

import com.mx.dla.dda.admin.presupuestos.bos.PresupuestoBO;
import com.mx.dla.dda.admin.presupuestos.dtos.PresupuestoApartadoDTO;
import com.mx.dla.dda.admin.presupuestos.dtos.PresupuestoDTO;
import com.mx.dla.dda.contrato.common.actions.BaseContratoAction;
import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.opensymphony.xwork2.Action;

public class PresupuestosAction extends BaseContratoAction {

	private static final long serialVersionUID = 5280088693174941192L;

	private List<PresupuestoDTO> presupuestos;
	private PresupuestoDTO presupuesto;
	private String tipo;
	private String mensaje;
	private Integer anio;
	private double monto;

	@Autowired
	private PresupuestoBO presupuestoBO;

	public String index() {
		return Action.SUCCESS;
	}

	public String guardaMonto() {
		System.out.println("Almacenando presupuesto");

		try {
			mensaje = presupuestoBO.almacenaMonto(anio, monto);

		} catch (ResultMapException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (PersistenceException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (TransaccionException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (SQLException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		}

		return "SUCCESS";
	}

	public String cargarPresupuestos() {
		try {
			logger.debug("Obteniendo presupuestos");
			presupuestos = presupuestoBO.obtenerPresptoXTipo(tipo);
			logger.debug("Obtenido presupuestos");
		} catch (ResultMapException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (PersistenceException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (TransaccionException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (SQLException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		}
		return "json";
	}

	public String redirectEditPresupuesto() {
		try {
			this.getServletRequest().setAttribute("tipo", this.tipo);
			this.getSession().put("pmn", this.getPmn());
		} catch (PersistenceException ibe) {
			logger.error("Error.", ibe);
			mensaje = "Ocurrio un error en la operacion.";
		}
		return Action.SUCCESS;
	}

	public String guardarPresupuesto() {
		ObjectMapper mapper = new ObjectMapper();
		try {
			logger.debug("Se inicia guarda presupuestos.");

			presupuesto = mapper.readValue(mensaje, PresupuestoDTO.class);
			mensaje = null;
			mensaje = presupuestoBO.guardarApartados(presupuesto.getApartados(), presupuesto.getAnio());
			logger.debug("Se terminaguardar presupuestos.");
		} catch (JsonParseException | JsonGenerationException | JsonMappingException je) {
			logger.error("Error. {}", je);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (IOException ioe) {
			logger.error("Error. {}", ioe);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (ResultMapException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (PersistenceException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (TransaccionException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (SQLException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		}
		return "json";
	}

	public String cargarApartadosAnio() {
		try {
			logger.info("Se obtiene apartado x anio");
			presupuesto = presupuestoBO.obtenerApartadosPresptoXAnio(this.tipo, this.anio.intValue());
			logger.info("Se termina obtener apartado x anio");
		} catch (ResultMapException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (PersistenceException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (TransaccionException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (SQLException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		}
		return "json";
	}

	public String redistribuirPresupuesto() {
		ObjectMapper mapper = new ObjectMapper();
		try {
			logger.debug("Se inicia redistribucion");

			List<PresupuestoApartadoDTO> apartados = mapper.readValue(mensaje,
					new TypeReference<List<PresupuestoApartadoDTO>>() {
					});
			mensaje = null;
			mensaje = presupuestoBO.redistribuirApartados(apartados, Integer.parseInt(tipo));

			logger.debug("Se termina redistribucion");
		} catch (JsonParseException | JsonGenerationException | JsonMappingException je) {
			logger.error("Error. {}", je);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (IOException ioe) {
			logger.error("Error. {}", ioe);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (ResultMapException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (PersistenceException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (TransaccionException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (SQLException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		}
		return "json";
	}

	public String redistribuirPresupuestoMontoDisp() {
		ObjectMapper mapper = new ObjectMapper();
		try {
			logger.debug("Se inicia redistribucion con monto disponible");

			List<PresupuestoApartadoDTO> apartados = mapper.readValue(mensaje,
					new TypeReference<List<PresupuestoApartadoDTO>>() {
					});
			mensaje = null;
			mensaje = presupuestoBO.redistribuirApartadosMontoDispo(apartados, Integer.parseInt(tipo));

			logger.debug("Se termina redistribucion");
		} catch (JsonParseException | JsonGenerationException | JsonMappingException je) {
			logger.error("Error. {}", je);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (IOException ioe) {
			logger.error("Error. {}", ioe);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (ResultMapException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (PersistenceException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (TransaccionException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		} catch (SQLException e) {
			logger.error("Error. {}", e);
			mensaje = "Ocurrio un error en la operacion.";
		}
		return "json";
	}

	public PresupuestoDTO getPresupuesto() {
		return presupuesto;
	}

	public String getTipo() {
		return tipo;
	}

	public String getMensaje() {
		return mensaje;
	}

	public List<PresupuestoDTO> getPresupuestos() {
		return presupuestos;
	}

	public void setPresupuesto(PresupuestoDTO presupuesto) {
		this.presupuesto = presupuesto;
	}

	public void setTipo(String tipo) {
		this.tipo = tipo;
	}

	public void setMensaje(String mensaje) {
		this.mensaje = mensaje;
	}

	public void setAnio(Integer anio) {
		this.anio = anio;
	}

	public double getMonto() {
		return monto;
	}

	public void setMonto(double monto) {
		this.monto = monto;
	}
}
