/*
 * HVB.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.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
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;

public class HVB {
	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;
	    }
	}	
	
	private static boolean isEmpty(String value) {
		return value == null || value.trim().equals("");
	}
	
	public HVB(String aBankCode, String aAccountNumber) {
		bankCode = aBankCode;
		accountNumber = aAccountNumber;
	}
	
	public String generate(Date date, List orders, List environment, Set processedOrders) {
		StringBuffer ret = new StringBuffer();
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		
		int year  = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;
		int day   = cal.get(Calendar.DAY_OF_MONTH);
		
		ret.append("0128ALK" + format(bankCode, "00000000") + "00000000" + "EVOLUTION HANDELS GESMBH" + "   ");
		ret.append(format(day, "00") + format(month, "00") + format(year % 100, "00") + "    ");
		ret.append(format(accountNumber, "0000000000") + "0000000000               ");
		ret.append(format(day, "00") + format(month, "00") + year + "                        1");
		
		int  sum  = 0;
		int  nSeg = 0;
		long c1   = 0;
		long c2   = 0;
		
		StringBuffer strUms1 = new StringBuffer();
		for (Iterator it = environment.iterator(); it.hasNext(); ) {
			DistributorValue dv = (DistributorValue) it.next();
		
			// only deal with german orders with type
			if (dv.getId().toString().startsWith("49")) {
				Map vals = new Hashtable();
				
				for (Iterator it2 = orders.iterator(); it2.hasNext(); ) {
					OrderHeaderValue ov = (OrderHeaderValue) it2.next();
					BankAccountValue ba = ov.getBankAccount();
					
					if (ba != null && ba.getMandateSignDate() != null && !isEmpty(ba.getIban()) && !isEmpty(ba.getBic())) continue;
					
					if (ov.getOrderer().equals(dv) && 
							ba != null && toNumber(ba.getAccountNumber()) != null && toNumber(ba.getBankCode()) != null &&
							ov.getPaymentMethodId().equals(OrderHeaderValue.PAYMENT_METHOD_BANK)) {
					
						Double val = (Double) vals.get(ba);
						if (val == null) {
							val = new Double(0);
							vals.put(ba, val);
						}
						vals.put(ba, new Double(val.doubleValue() + ov.getBrutto()));
						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("0216C00000000" + format(ba.getBankCode(), "00000000"));
					strUms1.append(format(ba.getAccountNumber(), "0000000000"));
					strUms1.append("000000000000004888 00000000000");
					strUms1.append(format(bankCode, "00000000") + format(accountNumber, "0000000000"));
					strUms1.append(format((long) (val * 100), "00000000000"));
					strUms1.append("   " + format(dv.getName().toUpperCase(), "                           "));
					strUms1.append("        " + "EVOLUTION HANDELS GESMBH" + "   ");
					strUms1.append(format(dv.getName().toUpperCase(), "                           "));
					strUms1.append("1  0102" + format("DNR " + dv.getId(), "                           "));
					strUms1.append("                                        ");
				     
					nSeg++;
					sum += (long) (val * 100);
					c1 += toNumber(ba.getAccountNumber()).doubleValue();
					c2 += toNumber(ba.getBankCode()).doubleValue();
				}
			}
		}
		
		ret.append(strUms1);
		ret.append("0128E     " + format(nSeg, "0000000") + "0000000000000");
		ret.append(format(c1, "00000000000000000") + format(c2, "00000000000000000"));
		ret.append(format(sum, "0000000000000") + "                                                   ");  

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