/*
 * Edifact.java
 * Created on May 25, 2005 
 * Author: 	L�szl� Felf�ldi, Etixpert GmbH
 * mail:	laszlo.felfoldi@etixpert.com		
 */
package com.etixpert.evolution.app.bonus;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
import java.util.Set;

import com.etixpert.evolution.value.DistributorValue;
import com.etixpert.evolution.value.order.BankAccountValue;

public class HVB {
	private String strBlz;
	private String strKto;
	
	private static String format(String val, String def) {
		String ret = def + val;
		ret = ret.replaceAll("\u00d6", "OE"); 
		ret = ret.replaceAll("\u00dc", "UE"); 
		ret = ret.replaceAll("\u00c4", "AE"); 
		ret = ret.replaceAll("\u00df", "SS"); 
		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 HVB(String aBlz, String aKto) {
		strBlz = aBlz;
		strKto = aKto;
	}
	
	public String generate(Date date, Set distributorsWithBonus, Set distributorsWithOpenOrders,
			   Set distributorsWithPayingNotAllowed, Set distributorsWithError, Set distributorsWithoutFirstOrder,
			   Map environment) {
		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);
		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 = 0;
		 
		ret.append("0128AGK" + format(strBlz, "00000000") + "00000000EVOLUTION GMBH             ");
		ret.append(format(day, "00") + format(month, "00") + format(year % 100, "00") + "    ");
		ret.append(format(strKto, "0000000000") + "0000000000               ");
		ret.append(format(day, "00") + format(month, "00") + year + "                        1");
		  
		double nSum    = 0;
		long   c1 = 0;
		long   c2 = 0;  

		StringBuffer strUms1 = new StringBuffer();
		Object[] values = environment.values().toArray();
		Arrays.sort(values, new Comparator() {
		    public int compare(Object o1, Object o2) {
		        DistributorValue dv1 = (DistributorValue) o1;
		        DistributorValue dv2 = (DistributorValue) o2;
		        return dv1.getName().compareTo(dv2.getName());
		    }
		});
		for (int i = 0; i < values.length; i++) {
		    DistributorValue dv = (DistributorValue) values[i];
			
			if (dv.getId().toString().startsWith("49")) {
			    double netto = Math.round(dv.getNettoBonusToPay() * 100) * 0.01;
				// 2010.03.01 MWSt should not be paid anymore
			    double val =  netto;// + Math.round(netto * dv.getVATFactor()) * 0.01;

		      	if (val > 0) {
		      		BankAccountValue ba = dv.getBankAccountValue(); 
		      		if (dv.getHasOpenOrders()) {
		      			distributorsWithOpenOrders.add(dv);
		      		} else if (!dv.getTransferBonus()) {
		      			distributorsWithPayingNotAllowed.add(dv);
		      		} else if (dv.getWithoutFirstOrder()) {
		      			distributorsWithoutFirstOrder.add(dv);
		      		} else if (ba == null || toNumber(ba.getBankCode()) == null || toNumber(ba.getAccountNumber()) == null) {
		      			distributorsWithError.add(dv);
		      		} else {
						strUms1.append("0216C00000000" + format(ba.getBankCode(), "00000000") +  format(ba.getAccountNumber(), "0000000000"));
						strUms1.append("000000000000051888 00000000000"); 
						strUms1.append(format(strBlz, "00000000") + format(strKto, "0000000000") + format(Math.round(val * 100), "00000000000"));
						strUms1.append("   " + format(dv.getName().toUpperCase().replaceAll(",", ""), "                           ") + "        ");       
						strUms1.append("EVOLUTION GMBH            " + format(dv.getName().toUpperCase(), "                            "));
						strUms1.append("1  0102" + format("DNR " + dv.getId(), "                           ") + "                                        ");
	
						nSeg++;
						nSum += val;
						c1 += toNumber(ba.getAccountNumber()).doubleValue();
						c2 += toNumber(ba.getBankCode()).doubleValue();
						
						distributorsWithBonus.add(dv);
		      		}					
				}
			}
		} 
		ret.append(strUms1);
		ret.append("0128E     " + format(nSeg, "0000000") + "0000000000000");
		ret.append(format(c1, "00000000000000000") + format(c2, "00000000000000000"));
		ret.append(format(Math.round(nSum * 100), "0000000000000") + "                                                   ");  
		
		return ret.toString();
	}
}
