package com.rjconsultores.ventaboletos.vo.reembolsoocdnotacredito;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.commons.lang.StringUtils;

import com.rjconsultores.ventaboletos.entidad.Boleto;
import com.rjconsultores.ventaboletos.entidad.CajaTarjeta;
import com.rjconsultores.ventaboletos.entidad.NotaCreditoVendaPacote;
import com.rjconsultores.ventaboletos.entidad.OCD;
import com.rjconsultores.ventaboletos.entidad.OCDDatosPagamento;
import com.rjconsultores.ventaboletos.enums.SituacaoNotaCreditoVendaPacote;
import com.rjconsultores.ventaboletos.utilerias.MoneyHelper;
import com.rjconsultores.ventaboletos.utilerias.OcdUtil;

@XmlRootElement(name = "ocdNotaCredito")
public class ReembolsoOcdNotaCreditoVO {
	
	private String numfoliosistema;
	private String numoperacion;
	private String localizador;
	private Date data;
	private Date dataPagamento;
	private BigDecimal valor;
	
	private Set<ReembolsoOcdNotaCreditoDatosPagamentoVO> datosPagamento;
	
	private Set<ReembolsoOcdNotaCreditoTarjetaVO> tarjetas;
	
	public ReembolsoOcdNotaCreditoVO() { }
	
	public static Builder builder() {
		return new ReembolsoOcdNotaCreditoVO.Builder();
	}

	public String getLocalizador() {
		return localizador;
	}

	public void setLocalizador(String localizador) {
		this.localizador = localizador;
	}

	public Date getData() {
		return data;
	}

	public void setData(Date data) {
		this.data = data;
	}

	public Date getDataPagamento() {
		return dataPagamento;
	}

	public void setDataPagamento(Date dataPagamento) {
		this.dataPagamento = dataPagamento;
	}

	public BigDecimal getValor() {
		return valor;
	}

	public void setValor(BigDecimal valor) {
		this.valor = valor;
	}

	@XmlElementWrapper
	@XmlElement(name = "datoPagamento", type = ReembolsoOcdNotaCreditoDatosPagamentoVO.class)
	public Set<ReembolsoOcdNotaCreditoDatosPagamentoVO> getDatosPagamento() {
		return datosPagamento;
	}

	public void setDatosPagamento(Set<ReembolsoOcdNotaCreditoDatosPagamentoVO> datosPagamento) {
		this.datosPagamento = datosPagamento;
	}

	@XmlElementWrapper
	@XmlElement(name = "tarjeta", type = ReembolsoOcdNotaCreditoTarjetaVO.class)
	public Set<ReembolsoOcdNotaCreditoTarjetaVO> getTarjetas() {
		return tarjetas;
	}

	public void setTarjetas(Set<ReembolsoOcdNotaCreditoTarjetaVO> tarjetas) {
		this.tarjetas = tarjetas;
	}

	public String getNumfoliosistema() {
		return numfoliosistema;
	}

	public void setNumfoliosistema(String numfoliosistema) {
		this.numfoliosistema = numfoliosistema;
	}

	public String getNumoperacion() {
		return numoperacion;
	}

	public void setNumoperacion(String numoperacion) {
		this.numoperacion = numoperacion;
	}

	public static class ReembolsoOcdNotaCreditoTarjetaVO {
		
		private String numtarjeta;
		private String numautorizacion;
		private String nsu;
		
		public ReembolsoOcdNotaCreditoTarjetaVO() { }
		
		public ReembolsoOcdNotaCreditoTarjetaVO(CajaTarjeta cajaTarjeta) {
			this.numtarjeta = cajaTarjeta.getNumtarjeta();
			this.numautorizacion = cajaTarjeta.getNumautorizacion();
			this.nsu = cajaTarjeta.getNsu();
		}
		
		public ReembolsoOcdNotaCreditoTarjetaVO(OCD ocd) {
			this.numtarjeta = ocd.getNumtarjeta();
			this.numautorizacion = ocd.getNumautorizacion();
			this.nsu = ocd.getNsu();
		}

		public String getNumtarjeta() {
			return numtarjeta;
		}
		public void setNumtarjeta(String numtarjeta) {
			this.numtarjeta = numtarjeta;
		}
		public String getNumautorizacion() {
			return numautorizacion;
		}
		public void setNumautorizacion(String numautorizacion) {
			this.numautorizacion = numautorizacion;
		}
		public String getNsu() {
			return nsu;
		}
		public void setNsu(String nsu) {
			this.nsu = nsu;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((nsu == null) ? 0 : nsu.hashCode());
			result = prime * result + ((numautorizacion == null) ? 0 : numautorizacion.hashCode());
			result = prime * result + ((numtarjeta == null) ? 0 : numtarjeta.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			ReembolsoOcdNotaCreditoTarjetaVO other = (ReembolsoOcdNotaCreditoTarjetaVO) obj;
			if (nsu == null) {
				if (other.nsu != null)
					return false;
			} else if (!nsu.equals(other.nsu))
				return false;
			if (numautorizacion == null) {
				if (other.numautorizacion != null)
					return false;
			} else if (!numautorizacion.equals(other.numautorizacion))
				return false;
			if (numtarjeta == null) {
				if (other.numtarjeta != null)
					return false;
			} else if (!numtarjeta.equals(other.numtarjeta))
				return false;
			return true;
		}
		
	}
	
	public static class ReembolsoOcdNotaCreditoDatosPagamentoVO {
		
		private String titularcuenta;
		private String identificacion;
		private String banco;
		private String cuentabanco;
		private String agencia;
		private String email;
		private String telefono;
		
		public ReembolsoOcdNotaCreditoDatosPagamentoVO() { }
		
		public ReembolsoOcdNotaCreditoDatosPagamentoVO(OCDDatosPagamento datosPagamento) {
			this.titularcuenta = datosPagamento.getTitularcuenta();
			this.identificacion = datosPagamento.getIdentificacion();
			this.banco = datosPagamento.getBanco();
			this.cuentabanco = datosPagamento.getCuentabanco();
			this.agencia = datosPagamento.getAgencia();
			this.email = datosPagamento.getEmail();
			this.telefono = datosPagamento.getTelefono();
		}
		
		public String getTitularcuenta() {
			return titularcuenta;
		}
		public void setTitularcuenta(String titularcuenta) {
			this.titularcuenta = titularcuenta;
		}
		public String getIdentificacion() {
			return identificacion;
		}
		public void setIdentificacion(String identificacion) {
			this.identificacion = identificacion;
		}
		public String getBanco() {
			return banco;
		}
		public void setBanco(String banco) {
			this.banco = banco;
		}
		public String getCuentabanco() {
			return cuentabanco;
		}
		public void setCuentabanco(String cuentabanco) {
			this.cuentabanco = cuentabanco;
		}
		public String getAgencia() {
			return agencia;
		}
		public void setAgencia(String agencia) {
			this.agencia = agencia;
		}
		public String getEmail() {
			return email;
		}
		public void setEmail(String email) {
			this.email = email;
		}
		public String getTelefono() {
			return telefono;
		}
		public void setTelefono(String telefono) {
			this.telefono = telefono;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((agencia == null) ? 0 : agencia.hashCode());
			result = prime * result + ((banco == null) ? 0 : banco.hashCode());
			result = prime * result + ((cuentabanco == null) ? 0 : cuentabanco.hashCode());
			result = prime * result + ((email == null) ? 0 : email.hashCode());
			result = prime * result + ((identificacion == null) ? 0 : identificacion.hashCode());
			result = prime * result + ((telefono == null) ? 0 : telefono.hashCode());
			result = prime * result + ((titularcuenta == null) ? 0 : titularcuenta.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			ReembolsoOcdNotaCreditoDatosPagamentoVO other = (ReembolsoOcdNotaCreditoDatosPagamentoVO) obj;
			if (agencia == null) {
				if (other.agencia != null)
					return false;
			} else if (!agencia.equals(other.agencia))
				return false;
			if (banco == null) {
				if (other.banco != null)
					return false;
			} else if (!banco.equals(other.banco))
				return false;
			if (cuentabanco == null) {
				if (other.cuentabanco != null)
					return false;
			} else if (!cuentabanco.equals(other.cuentabanco))
				return false;
			if (email == null) {
				if (other.email != null)
					return false;
			} else if (!email.equals(other.email))
				return false;
			if (identificacion == null) {
				if (other.identificacion != null)
					return false;
			} else if (!identificacion.equals(other.identificacion))
				return false;
			if (telefono == null) {
				if (other.telefono != null)
					return false;
			} else if (!telefono.equals(other.telefono))
				return false;
			if (titularcuenta == null) {
				if (other.titularcuenta != null)
					return false;
			} else if (!titularcuenta.equals(other.titularcuenta))
				return false;
			return true;
		}
		
	}
	
	public static class Builder {
		
		private ReembolsoOcdNotaCreditoVO vo;
		
		public Builder() {
			vo = new ReembolsoOcdNotaCreditoVO();
		}
		
		public Builder datosPagamento(List<OCDDatosPagamento> listDatosPagamento) {
			vo.datosPagamento = new HashSet<ReembolsoOcdNotaCreditoDatosPagamentoVO>();
			for (OCDDatosPagamento datosPagamento : listDatosPagamento) {
				vo.datosPagamento.add(new ReembolsoOcdNotaCreditoDatosPagamentoVO(datosPagamento));
			}
			return this;
		}
		
		public Builder cajaTarjeta(List<CajaTarjeta> listCajaTarjeta) {
			vo.tarjetas = new HashSet<ReembolsoOcdNotaCreditoTarjetaVO>();
			for (CajaTarjeta cajaTarjeta : listCajaTarjeta) {
				vo.tarjetas.add(new ReembolsoOcdNotaCreditoTarjetaVO(cajaTarjeta));
			}
			return this;
		}
		
		public Builder ocd(OCD ocd) {
			vo.localizador = OcdUtil.generaLocalizadorOCD(ocd);
			vo.data = ocd.getFecinc();
			vo.dataPagamento = ocd.getFecpagar();
			
			if(ocd.getIndpago() != null && ocd.getIndpago()) {
				vo.valor = MoneyHelper.somar(ocd.getValorPagar(), ocd.getValorTarjeta());
			} else {
				vo.valor = ocd.getSaldoPagar();
			}
			vo.tarjetas = new HashSet<ReembolsoOcdNotaCreditoTarjetaVO>();
			if (StringUtils.isNotEmpty(ocd.getNumtarjeta())) {
				vo.tarjetas.add(new ReembolsoOcdNotaCreditoTarjetaVO(ocd));
			}
			
			return this;
		}
		
		public Builder notaCredito(NotaCreditoVendaPacote notaCredito) {
			vo.localizador = String.valueOf(notaCredito.getNotaCreditoVendaPacoteId());
			vo.data = notaCredito.getDatanotacredito();
			vo.dataPagamento = notaCredito.getDatapagamento();
			vo.numoperacion = notaCredito.getVendapacotecancelamento().getNumoperacion();
			
			if(notaCredito.getSituacao().equals(SituacaoNotaCreditoVendaPacote.UTILIZADA.getValue())) {
				vo.valor = notaCredito.getValor();
			} else {
				vo.valor = notaCredito.getSaldoPagar();
			}
			return this;
		}
		
		public Builder boleto(Boleto boleto) {
			vo.numfoliosistema = boleto.getNumfoliosistema();
			vo.numoperacion = boleto.getNumoperacion();
			return this;
		}
		
		public ReembolsoOcdNotaCreditoVO build() {
			ReembolsoOcdNotaCreditoVO build = vo;
			vo = new ReembolsoOcdNotaCreditoVO();
			return build;
		}
		
	}

}
