/*
 * Edifact.java
 * Created on May 11, 2005 
 * Author: 	Lï¿½szlï¿½ Felfï¿½ldi, Etixpert GmbH
 * mail:	laszlo.felfoldi@etixpert.com		
 */
package com.etixpert.evolution.app.order;

import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import com.etixpert.evolution.value.DistributorValue;
import com.etixpert.evolution.value.order.BankAccountValue;
import com.etixpert.evolution.value.order.OrderHeaderValue;
import org.apache.log4j.*;


public class Edifact {
	private String bankCode;
	private String accountNumber;
	
	private static String format(String val, String def) {
		String ret = def + val;
		return ret.substring(ret.length() - def.length());
	}
	
	private static String format(long val, String def) {
		return format("" + val, def);
	}
	
	private static Long toNumber(String src) {
	    try {
	        return new Long(src.replaceAll("[^0-9]", ""));
	    } catch (Exception e) {
	        return null;
	    }
	}
		
	public Edifact(String aBankCode, String aAccountNumber) {
		bankCode = aBankCode;
		accountNumber = aAccountNumber;
	}
	
	public String generate(Date date, List orders, List environment, Set processedOrders) {
	    Logger logger= Logger.getLogger("mainControl.Payment");
	    StringBuffer ret = new StringBuffer();
		Calendar     cal = Calendar.getInstance();
		cal.setTime(date);

		//logger.info("Setting up number infos");
		NumberFormat nf  = NumberFormat.getInstance(Locale.GERMAN);
		nf.setMaximumFractionDigits(2);
		nf.setMinimumFractionDigits(2);
		nf.setGroupingUsed(false);
		//logger.info("number ifos set up");
		
		int year   = cal.get(Calendar.YEAR);
		int month  = cal.get(Calendar.MONTH) + 1;
		int day    = cal.get(Calendar.DAY_OF_MONTH);
		int hour   = cal.get(Calendar.HOUR);
		int minute = cal.get(Calendar.MINUTE);
		int second = cal.get(Calendar.SECOND);
		
		String StrRefNr = "" + year + month + day + hour + minute + second;

		int nSeg = 1;
		
		ret.append("UNA:+,? '");
		ret.append("UNB+UNOC:3+EVOLUTION Handels-GmbH+ATBAA+" + format(year % 100, "00"));
		ret.append(format(month, "00") + format(day, "00") + ":" + format(hour, "00"));
		ret.append(format(minute, "00") + "+XXX20020300102'");
		nSeg += 2;
		  
		ret.append("UNH+" + StrRefNr + "+DIRDEB:D:96A:UN'");
		nSeg++;
		  
		ret.append("BGM++" + StrRefNr + "+9'");
		nSeg++;
		  
		ret.append("DTM+137:" + format(year, "0000") + format(month, "00") + format(day, "00"));
		ret.append(format(hour, "00") + format(minute, "00") + format(second, "00") + ":204'");
		nSeg++;
		
		ret.append("FII+MR+" + "+" + bankCode + "'");
		nSeg++;
		  
		ret.append("NAD+MS++EVOLUTION Handels-GmbH'");
		nSeg++;
	
		ret.append("LIN+1'");
		nSeg++;
		  
		ret.append("RFF+AEK:" + StrRefNr + "'");
		nSeg++;
		
		ret.append("BUS++DO++DDT'");
//		ret.append("BUS++DO+13+DDT'");
		nSeg++;
		
		ret.append("MOA+9:");
		
		StringBuffer strVs2 = new StringBuffer();
		strVs2.append("FII+OR+");
		strVs2.append(accountNumber + ":EVOLUTION Handels-GmbH::EUR+:::" + bankCode + ":25:137+AT'");
		nSeg++;
		
		StringBuffer strUms1 = new StringBuffer();
		int    nAnzUms = 1;
		double nSum    = 0;
		//logger.info("size of enviroment: "+environment.size());
		for (Iterator it = environment.iterator(); it.hasNext(); ) {
			DistributorValue dv = (DistributorValue) it.next();
			//logger.info("distributorvalue: "+dv.getName());
			if (dv.getId().toString().startsWith("43") ) {
				int nSegDetails = 0;
				StringBuffer strDetails = new StringBuffer();
				Map vals = new Hashtable();
				
				int colidx = 0;
				//logger.info("Iterating orders. size "+orders.size()+ "MAINLOOP!!!");
				for (Iterator it2 = orders.iterator(); it2.hasNext(); ) {
					OrderHeaderValue ov = (OrderHeaderValue) it2.next();
					BankAccountValue ba = ov.getBankAccount();
					
					//logger.info("checking order and in edifact match. MAIN IF!!! ");
					//logger.info("orderer: " + ov.getOrderer());
					//logger.info("dv: "+ dv);
					//logger.info("orderer= dv? " +ov.getOrderer().equals(dv));
					//logger.info("ba: "+ba);
					//if (ba!=null) {
					  //  logger.info("ba accountnummber length" + ba.getAccountNumber().length());
					    //logger.info("ba bankcode length"+ ba.getBankCode().length());
					//}
					//logger.info("paymethodid" + ov.getPaymentMethodId());
					//logger.info("OrderHeaderVal.PAymentmehtodbank: "+OrderHeaderValue.PAYMENT_METHOD_BANK);
					//logger.info("both equals? "+ov.getPaymentMethodId().equals(OrderHeaderValue.PAYMENT_METHOD_BANK));
					if (ov.getOrderer().equals(dv) &&
							ba != null && toNumber(ba.getAccountNumber()) != null && toNumber(ba.getBankCode()) != null &&
							ov.getPaymentMethodId().equals(OrderHeaderValue.PAYMENT_METHOD_BANK)) {
						
					    //logger.info("In the IF");
						Double val = (Double) vals.get(ba);
						if (val == null) {
							val = new Double(0);
							vals.put(ba, val);
						}
						
						if (++colidx == 5) {
							colidx = 0;
							nSegDetails++;
							strDetails.append("'FTX+PMD+++");
						}
			
						if (colidx > 0) 
							strDetails.append(':');
						
						strDetails.append("BestellNr?:" + ov.getOrderId() + "(");
						strDetails.append(nf.format(ov.getBrutto()) + "EUR)");
						vals.put(ba, new Double(val.doubleValue() + ov.getBrutto()));
						//logger.info("Adding to processedOrders!!!!!!!!!! It works!!!" + ov.getOrderId());
						processedOrders.add(ov.getOrderId());
					}
				}
				
				for (Iterator it2 = vals.keySet().iterator(); it2.hasNext(); ) {
					BankAccountValue ba = (BankAccountValue) it2.next();
					double val = ((Double) vals.get(ba)).doubleValue();

					strUms1.append("SEQ++" + nAnzUms + ":83:EBA:137'");

					nSeg++;
					
					strUms1.append("MOA+9:" + nf.format(val) + ":EUR'");
					nSeg++;
					nSum += val;
					nAnzUms++;
					//-------------Trenker 2003-01-07-------------------
					//we change the value for RFF+PQ, because of an customer request
					//strUms1.append("RFF+PQ:" + "Abbuchung der Rechnungen'");
					strUms1.append("RFF+PQ:" + "DistributorNr?:" + dv.getId() + "'");
					//-------------End Trenker 2003-01-07---------------
					nSeg++;
					strUms1.append("FII+PH+" + toNumber(ba.getAccountNumber()));
					strUms1.append(":" + (dv.getName() + (dv.getAddress() == null ? "" : " " + dv.getAddress()) + "                                   ").substring(0,35).replace('\'', ' ').trim());
					strUms1.append("+:::" + toNumber(ba.getBankCode()) + ":25:137+AT'");
					nSeg++;
				    	
					strUms1.append("PRC+11'FTX+PMD+++DistributorNr?:" + dv.getId() + strDetails + "'");
					nSeg += 2 + nSegDetails;
				}
			}
		}
		
		ret.append(nf.format(nSum) + ":EUR'");
		nSeg++;
		
		ret.append(strVs2);
		ret.append(strUms1);
		   
		ret.append("CNT+1:" + nf.format(nSum) + "'");
		nSeg++;
		
		ret.append("CNT+2:1'");
		nAnzUms--;
		ret.append("CNT+39:" + nAnzUms + "'UNT+" + nSeg + "+" + StrRefNr + "'");
		ret.append("UNZ+1+XXX20020300102'");

		return nSum > 0 ? ret.toString() : null;
	}
}