package com.dev.swms.server.model.base;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

import ognl.Ognl;
import ognl.OgnlException;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.dev.swms.server.model.rules.LotRule;
import com.dev.energy.server.dao.CommonDao;
import com.dev.energy.server.model.DomainModel;

public class LotInfo extends DomainModel implements ApplicationContextAware{
	/** 商品字符串属性 */
	private String propC1;//贸易方式
	private String propC2;//保税/课税
	private String propC3;//批次月
	private String propC4;
	private String propC5;
	private String propC6;
	private String propC7;
	private String propC8;
	private String propC9;
	/** 商品数字属性 */
	private double propN1;
	private double propN2;
	private double propN3;
	/** 商品日期属性 */
	private Date propD1;
	private Date propD2;
	private Date propD3;
	/** 商品ID属性 */
	private Long propL1;
	private Long propL2;
	private Long propL3;
	private String propLC1;
	private String propLC2;
	private String propLC3;
	
	private static ApplicationContext ac;
	private CommonDao commonDao;
	
	protected SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	
	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
		ac = arg0;
		this.commonDao = (CommonDao) ac.getBean("commonDao");
	}
	
	public LotInfo(String propc1, String propc2, String propc3, String propc4,
			String propc5, String propc6, String propc7, String propc8,
			String propc9, double propn1, double propn2, double propn3,
			Date propd1, Date propd2, Date propd3, Long propL1, Long propL2, Long propL3) {
		this.propC1 = propc1;
		this.propC2 = propc2;
		this.propC3 = propc3;
		this.propC4 = propc4;
		this.propC5 = propc5;
		this.propC6 = propc6;
		this.propC7 = propc7;
		this.propC8 = propc8;
		this.propC9 = propc9;
		this.propD1 = propd1;
		this.propD2 = propd2;
		this.propD3 = propd3;
		this.propN1 = propn1;
		this.propN2 = propn2;
		this.propN3 = propn3;
		this.propL1 = propL1;
		this.propL2 = propL2;
		this.propL3 = propL3;
	}

	public LotInfo(){
		
	}
	
	public LotInfo(Map<Integer,String> lotInfo) throws OgnlException, ParseException{
		Map<Integer,String> fields = getLotInfoField();
		for(Map.Entry<Integer, String> me : lotInfo.entrySet()){
			Integer key = me.getKey();
			String value = me.getValue();
			Object _value = null;
			if(key >= 1 && key <= 9){
				_value = value;
			}
			else if(key >= 10 && key <= 12){
				_value = sdf.parse(value);
			}
			else if(key >= 13 && key <= 15){
				_value = Double.valueOf(value);
			}
			Ognl.setValue(fields.get(key), this, _value);
			if(key >= 16 && key <= 18 && StringUtils.isNotBlank(value)){
				Structure organ = (Structure)commonDao.findByNamedQueryUniqueResult("getStructureByCode",
						new String[]{"code"}, new Object[]{value});
				if(organ != null){
					if(key == 16){
						this.setPropL1(organ.getId());
						this.setPropLC1(organ.getName());
					}
					else if(key == 17){
						this.setPropL2(organ.getId());
						this.setPropLC2(organ.getName());
					}else{
						this.setPropL3(organ.getId());
						this.setPropLC3(organ.getName());
					}
				}
			}
		}
	}

	public Long getPropL1() {
		return propL1;
	}
	public void setPropL1(Long propL1) {
		this.propL1 = propL1;
	}
	public Long getPropL2() {
		return propL2;
	}
	public void setPropL2(Long propL2) {
		this.propL2 = propL2;
	}
	public Long getPropL3() {
		return propL3;
	}
	public void setPropL3(Long propL3) {
		this.propL3 = propL3;
	}
	public String getPropLC1() {
		return propLC1;
	}
	public void setPropLC1(String propLC1) {
		this.propLC1 = propLC1;
	}
	public String getPropLC2() {
		return propLC2;
	}
	public void setPropLC2(String propLC2) {
		this.propLC2 = propLC2;
	}
	public String getPropLC3() {
		return propLC3;
	}
	public void setPropLC3(String propLC3) {
		this.propLC3 = propLC3;
	}
	public String getPropC1() {
		return propC1;
	}
	public void setPropC1(String propC1) {
		this.propC1 = propC1;
	}
	public String getPropC2() {
		return propC2;
	}
	public void setPropC2(String propC2) {
		this.propC2 = propC2;
	}
	public String getPropC3() {
		return propC3;
	}
	public void setPropC3(String propC3) {
		this.propC3 = propC3;
	}
	public String getPropC4() {
		return propC4;
	}
	public void setPropC4(String propC4) {
		this.propC4 = propC4;
	}
	public String getPropC5() {
		return propC5;
	}
	public void setPropC5(String propC5) {
		this.propC5 = propC5;
	}
	public String getPropC6() {
		return propC6;
	}
	public void setPropC6(String propC6) {
		this.propC6 = propC6;
	}
	public String getPropC7() {
		return propC7;
	}
	public void setPropC7(String propC7) {
		this.propC7 = propC7;
	}
	public String getPropC8() {
		return propC8;
	}
	public void setPropC8(String propC8) {
		this.propC8 = propC8;
	}
	public String getPropC9() {
		return propC9;
	}
	public void setPropC9(String propC9) {
		this.propC9 = propC9;
	}
	public Date getPropD1() {
		return propD1;
	}
	public void setPropD1(Date propD1) {
		this.propD1 = propD1;
	}
	public Date getPropD2() {
		return propD2;
	}
	public void setPropD2(Date propD2) {
		this.propD2 = propD2;
	}
	public Date getPropD3() {
		return propD3;
	}
	public void setPropD3(Date propD3) {
		this.propD3 = propD3;
	}
	public double getPropN1() {
		return propN1;
	}
	public void setPropN1(double propN1) {
		this.propN1 = propN1;
	}
	public double getPropN2() {
		return propN2;
	}
	public void setPropN2(double propN2) {
		this.propN2 = propN2;
	}
	public double getPropN3() {
		return propN3;
	}
	public void setPropN3(double propN3) {
		this.propN3 = propN3;
	}
	
	public void setInvaidStart(Item item) {
		if (this.getPropD2() != null) {
			this.setPropD1(getDateOfDaysLater(this.getPropD2(),-item.getValidPeriod().intValue()));
		}
	}

	public void setInvaidEnd(Item item) {
		if (this.getPropD1() != null) {
			this.setPropD2(getDateOfDaysLater(this.getPropD1(),item.getValidPeriod().intValue()));
		}
	}
	
	private Date getDateOfDaysLater(Date start,int delta){
		Calendar cal = new GregorianCalendar();
		cal.setTime(start);
		cal.add(Calendar.DATE , delta);	
		return cal.getTime();
	}
	
	public String toString() {
		DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
		String result = "";
		if(this.propC1 != null && !"".equals(this.propC1)){
			result += "#" + this.propC1;
		}
		if(this.propC2 != null && !"".equals(this.propC2)){
			result += "#" + this.propC2;
		}
		if(this.propC3 != null && !"".equals(this.propC3)){
			result += "#" + this.propC3;
		}
		if(this.propC4 != null && !"".equals(this.propC4)){
			result += "#" + this.propC4;
		}
		if(this.propC5 != null && !"".equals(this.propC5)){
			result += "#" + this.propC5;
		}
		if(this.propC6 != null && !"".equals(this.propC6)){
			result += "#" + this.propC6;
		}
		if(this.propC7 != null && !"".equals(this.propC7)){
			result += "#" + this.propC7;
		}
		if(this.propC8 != null && !"".equals(this.propC8)){
			result += "#" + this.propC8;
		}
		if(this.propC9 != null && !"".equals(this.propC9)){
			result += "#" + this.propC9;
		}
		if(this.propN1 != 0){
			result += "#" + this.propN1;
		}
		if(this.propN2 != 0){
			result += "#" + this.propN2;
		}
		if(this.propN3 != 0){
			result += "#" + this.propN3;
		}
		if(this.propD1 != null && !"".equals(this.propD1)){
			result += "#" + formater.format(this.propD1);
		}
		if(this.propD2 != null && !"".equals(this.propD2)){
			result += "#" + formater.format(this.propD2);
		}
		if(this.propD3 != null && !"".equals(this.propD3)){
			result += "#" + formater.format(this.propD3);
		}
		if(this.propL1 != null && this.propL1 != 0){
			result += "#"+this.propLC1;
		}
		if(this.propL2 != null && this.propL2 != 0){
			result += "#"+this.propLC2;
		}
		if(this.propL3 != null && this.propL3 != 0){
			result += "#"+this.propLC3;
		}
		result = StringUtils.replaceOnce(result,"#","");
		return result;
	}

	@Override
	public boolean equals(final Object other) {
		if (!(other instanceof LotInfo))
			return false;
		LotInfo castOther = (LotInfo) other;
		return new EqualsBuilder().append(propC1, castOther.propC1).append(
				propC2, castOther.propC2).append(propC3, castOther.propC3)
				.append(propC4, castOther.propC4).append(propC5,
						castOther.propC5).append(propC6, castOther.propC6)
				.append(propC7, castOther.propC7).append(propC8,
						castOther.propC8).append(propC9, castOther.propC9)
				.append(propN1, castOther.propN1).append(propN2,
						castOther.propN2).append(propN3, castOther.propN3)
				.append(propD1, castOther.propD1).append(propD2,
						castOther.propD2).append(propD3, castOther.propD3)
				.append(propL1, castOther.propL1).append(propL2,
						castOther.propL2).append(propL3,castOther.propL3)
				.isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(propC1).append(propC2).append(
				propC3).append(propC4).append(propC5).append(propC6).append(
				propC7).append(propC8).append(propC9).append(propN1).append(
				propN2).append(propN3).append(propD1).append(propD2).append(
				propD3).append(propL1).append(propL2).append(propL3).toHashCode();
	}
	
	public boolean verifyRequired(LotRule lotRule){
		if (lotRule.getLotRuleComponent().getTrackPropC1() && StringUtils.isEmpty(this.propC1)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropC2() && StringUtils.isEmpty(this.propC2)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropC3() && StringUtils.isEmpty(this.propC3)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropC4() && StringUtils.isEmpty(this.propC4)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropC5() && StringUtils.isEmpty(this.propC5)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropC6() && StringUtils.isEmpty(this.propC6)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropC7() && StringUtils.isEmpty(this.propC7)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropC8() && StringUtils.isEmpty(this.propC8)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropC9() && StringUtils.isEmpty(this.propC9)) {
			return false;
		}
		
		if (lotRule.getLotRuleComponent().getTrackPropN1() && this.propN1 == 0.0) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropN2() && this.propN2 == 0.0) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropN3() && this.propN3 == 0.0) {
			return false;
		}
		
		if (lotRule.getLotRuleComponent().getTrackPropD1() && this.propD1 == null && this.propD2 == null) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropD3() && this.propD3 == null) {
			return false;
		}
		
		if (lotRule.getLotRuleComponent().getTrackPropL1() && (this.propL1 == null || this.propL1 == 0)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropL2() && (this.propL2 == null || this.propL2 == 0)) {
			return false;
		}
		if (lotRule.getLotRuleComponent().getTrackPropL3() && (this.propL3 == null || this.propL3 == 0)) {
			return false;
		}
		return true;
	}
	
	
	public Map<Integer,String> getLotInfoMap(){
		Map<Integer,String> lotInfo = new HashMap<Integer, String>();
		lotInfo.put(1,this.propC1);
		lotInfo.put(2,this.propC2);
		lotInfo.put(3,this.propC3);
		lotInfo.put(4,this.propC4);
		lotInfo.put(5,this.propC5);
		lotInfo.put(6,this.propC6);
		lotInfo.put(7,this.propC7);
		lotInfo.put(8,this.propC8);
		lotInfo.put(9,this.propC9);
		
		lotInfo.put(10,propD1 != null ? sdf.format(this.propD1) : "");
		lotInfo.put(11,propD2 != null ? sdf.format(this.propD2) : "");
		lotInfo.put(12,propD3 != null ? sdf.format(this.propD3) : "");
		
		lotInfo.put(13,this.propN1 + "");
		lotInfo.put(14,this.propN2 + "");
		lotInfo.put(15,this.propN3 + "");
		String propL1Code = null;
		Structure organ = null;
		if(propL1 != null){
			organ = commonDao.load(Structure.class, propL1);
			if(organ != null)
				propL1Code = organ.getCode();
		}
		String propL2Code = null;
		if(propL2 != null){
			organ = commonDao.load(Structure.class, propL2);
			if(organ != null)
				propL2Code = organ.getCode();
		}
		String propL3Code = null;
		if(propL3 != null){
			organ = commonDao.load(Structure.class, propL3);
			if(organ != null)
				propL3Code = organ.getCode();
		}
		lotInfo.put(16,propL1Code);
		lotInfo.put(17,propL2Code);
		lotInfo.put(18,propL3Code);
		return lotInfo;
	}
	
	public Map<Integer,String> getLotInfoField(){
		Map<Integer,String> lotInfo = new HashMap<Integer, String>();
		lotInfo.put(1,"propC1");
		lotInfo.put(2,"propC2");
		lotInfo.put(3,"propC3");
		lotInfo.put(4,"propC4");
		lotInfo.put(5,"propC5");
		lotInfo.put(6,"propC6");
		lotInfo.put(7,"propC7");
		lotInfo.put(8,"propC8");
		lotInfo.put(9,"propC9");
		
		lotInfo.put(10,"propD1");
		lotInfo.put(11,"propD2");
		lotInfo.put(12,"propD3");
		
		lotInfo.put(13,"propN1");
		lotInfo.put(14,"propN2");
		lotInfo.put(15,"propN3");
		
		lotInfo.put(16,"propL1");
		lotInfo.put(17,"propL2");
		lotInfo.put(18,"propL3");
		return lotInfo;
	}

	public void format() {
		if ("".equals(this.getPropC1())) {
			this.setPropC1(null);
		}
		if ("".equals(this.getPropC2())) {
			this.setPropC2(null);
		}
		if ("".equals(this.getPropC3())) {
			this.setPropC3(null);
		}
		if ("".equals(this.getPropC4())) {
			this.setPropC4(null);
		}
		if ("".equals(this.getPropC5())) {
			this.setPropC5(null);
		}
		if ("".equals(this.getPropC6())) {
			this.setPropC6(null);
		}
		if ("".equals(this.getPropC7())) {
			this.setPropC7(null);
		}
		if ("".equals(this.getPropC8())) {
			this.setPropC8(null);
		}
		if ("".equals(this.getPropC9())) {
			this.setPropC9(null);
		}
		if (this.getPropL1() == null || this.getPropL1() == 0) {
			this.setPropL1(null);
			this.setPropLC1(null);
		}
		if (this.getPropL2() == null || this.getPropL2() == 0) {
			this.setPropL2(null);
			this.setPropLC2(null);
		}
		if (this.getPropL3() == null || this.getPropL3() == 0) {
			this.setPropL3(null);
			this.setPropLC3(null);
		}
	}

}
