package com.mx.dla.dda.factura.general.actions;

import java.util.Arrays;
import java.util.List;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;

import com.mx.dla.dda.catalogos.dtos.EstudioDTO;
import com.mx.dla.dda.catalogos.dtos.IndicadorDTO;
import com.mx.dla.dda.contrato.common.actions.BaseContratoAction;
import com.mx.dla.dda.contrato.generales.bos.PoblarGeneralesBO;
import com.mx.dla.dda.factura.general.bos.FacturacionBO;
import com.mx.dla.dda.factura.general.dtos.ContratoFacturaDTO;
import com.mx.dla.dda.factura.general.dtos.FacturaGeneralDTO;
import com.mx.dla.dda.general.constants.SiNoOpcion;
import com.mx.dla.dda.factura.constants.TipoPagoFactura;
import com.opensymphony.xwork2.Action;

public class FacturacionAction extends BaseContratoAction {

	private static final long serialVersionUID = 1L;
	private FacturaGeneralDTO factura = new FacturaGeneralDTO();

	@Autowired
	private FacturacionBO facturacionBO;

	@Autowired
	private PoblarGeneralesBO poblarGeneralesBO;

	private String idEstudio;
	private String idFactura;
	private String aprobado;
	private String detalleCto;
	private String indicadorIVA;
	private String restCto;

	public String cargaFacturaGeneral() {
						
		try {
			String facturaId  = (String)this.getSession().get("idFactura");							
			Long idFactura    = facturaId != null ? new Long(facturaId) : null;						
			factura           = facturacionBO.cargaFacturaInfoGeneral(idFactura);
			logger.info("cargaFacturaGeneral COMPLETE: " + factura);			
		} catch (Exception e) {
			logger.error("Ha ocurrido el siguiente error durante la consulta. {}", e);
			addActionError("Ha ocurrido el siguiente error durante la consulta: "+ e.getMessage());
		}		
		bajaInfoDeSession();
		return Action.SUCCESS;
	}
	
	public String cargaFacturaDetalle() {
		
		try {					
			logger.debug(idEstudio);
			logger.debug(indicadorIVA);
			logger.debug(idFactura);
			Long   idEst     = new Long(Long.parseLong(idEstudio));
			Long   idFactura = !this.idFactura.trim().equals("") ? new Long(this.idFactura)   : null;							
			Integer approved = !this.aprobado.trim().equals("")  ? new Integer(this.aprobado) : null;						       
			
			factura  = facturacionBO.cargaFacturaInfoGeneral(idFactura);			
			factura.setIdEstudio(idEst);
			factura.setIdFactura(idFactura);
			factura.setApproved(approved);						 
			
			indicadorIVA = indicadorIVA == null || indicadorIVA.equals("") ? factura.getIndicadorIva(): indicadorIVA;
			
			List<ContratoFacturaDTO> detalles = facturacionBO.cargaFacturaInfoDetalle(idEst, idFactura, approved.intValue() == 0 ? false : true, indicadorIVA);
			factura.setContratos(detalles);			
			logger.info("cargaFacturaDetalle COMPLETE: " + factura);
		
		} catch (Exception e) {
			logger.error("Ha ocurrido el siguiente error durante la consulta. {}", e);
			addActionError("Ha ocurrido el siguiente error durante la consulta: "+ e.getMessage());
		}
		
		bajaInfoDeSession();
		return Action.SUCCESS;
	}
	
	public String guardaFactura() {

		try {
									
			ObjectMapper mapper = new ObjectMapper();	
			
			logger.debug("factura: {}", factura);

			List<ContratoFacturaDTO> contratos = mapper.readValue(detalleCto, new TypeReference<List<ContratoFacturaDTO>>(){});			    
			factura.setContratos(contratos);			
			facturacionBO.guardarFactura(factura);
						
			//logger.debug(restCto);
			//if(restCto != null && !restCto.equals(""))
			//{
			//	logger.debug("Llamando Rest Facturacion. Dominio rest. {}", restCto);
			//	FacturaGeneralDTO domRest = restCto != null ? mapper.readValue(restCto, FacturaGeneralDTO.class) : null;
				
				if(factura.getApproved() == 1)
				    facturacionBO.notificarServicioRest(factura);
				
				this.getSession().put("idFactura", String.valueOf(factura.getIdFactura()));
				
				//this.factura = facturacionBO.consultaFactura(new Long(factura.getIdFacdFactura()));
				//logger.debug("factura final: {}", factura);
			//}			   
			 
		} catch (Exception e) {
			logger.error("Ha ocurrido el siguiente error durante el guardado. {}", e);
			addActionError("Ha ocurrido el siguiente error durante el guardad " + e.getMessage());
		}

		addActionMessage("La factura se ha guardado con exito");		
		bajaInfoDeSession();
		return Action.SUCCESS;
	}
	
	
	public String reenvioNotificacion() {

		try {
				logger.debug("Reenvio notificacion factura, idFactura: {}", idFactura);
			
			    FacturaGeneralDTO factura = new FacturaGeneralDTO();
				factura.setIdFactura(new Long(idFactura));
				
				facturacionBO.notificarServicioRest(factura);
				
				this.factura = facturacionBO.consultaFactura(new Long(idFactura));
				
				logger.debug("factura: {}", factura);

				
		} catch (Exception e) {
			logger.error("Ha ocurrido el siguiente error durante el guardado. {}", e);
			addActionError("Ha ocurrido el siguiente error durante el guardad " + e.getMessage());
		}

		//addActionMessage("Se ha reenviado la notificacion");		
		//bajaInfoDeSession();
		return Action.SUCCESS;
	}
	
	
/*	public String consultaFactura() {
		
		try {
				logger.debug("Consulta factura, idFactura: {}", idFactura);
				factura = facturacionBO.consultaFactura(new Long(idFactura));
		} catch (Exception e) {
			logger.error("Ha ocurrido el siguiente error durante el guardado. {}", e);
			addActionError("Ha ocurrido el siguiente error durante el guardad " + e.getMessage());
		}

		return Action.SUCCESS;
	}*/
	
	public void bajaInfoDeSession() {		
		this.setPmn((String)this.getSession().get("pmn"));
		this.setPmnReturn((String) this.getSession().get("pmnReturn"));
	}

	public FacturaGeneralDTO getFactura() {return factura;}	
	public List<EstudioDTO>  getEstudios() {return poblarGeneralesBO.obtenListaEstudios();}
	public List<IndicadorDTO>  getIndicadoresIva() {return poblarGeneralesBO.obtenerIndicadores();}	
	public List<SiNoOpcion>  getSiNoOpcion() {return Arrays.asList(SiNoOpcion.values());}
	public List<TipoPagoFactura>  getTiposPago() {return Arrays.asList(TipoPagoFactura.values());}	

	public String getIdEstudio() {return idEstudio;}
	public String getIdFactura() {return idFactura;}
	public String getAprobado() {return aprobado; }
	public String getDetalleCto() {return detalleCto; }
	public String getIndicadorIVA() { return indicadorIVA; }
	
	public void setFactura(FacturaGeneralDTO factura) {this.factura = factura;}
	public void setIdEstudio(String idEstudio) {this.idEstudio = idEstudio; }	
	public void setIdFactura(String idFactura) {this.idFactura = idFactura; }	
	public void setAprobado(String aprobado) {this.aprobado = aprobado; }	
	public void setDetalleCto(String detalleCto) { this.detalleCto = detalleCto; }	
	public void setRestCto(String restCto) { this.restCto = restCto; }		
	public void setIndicadorIVA(String indicadorIVA) { this.indicadorIVA = indicadorIVA; }		
}