package lu.tudor.santec.gecamed.importexport.gui.importer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Account;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Settlement;
import lu.tudor.santec.gecamed.billing.ejb.session.beans.SettlementBean;
import lu.tudor.santec.gecamed.billing.ejb.session.interfaces.SettlementInterface;
import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialogImpl;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.i18n.Translatrix;

public class PaymentMethodAssignmentDialog extends GECAMedBaseDialogImpl {
	
	private static final long serialVersionUID = -3679196622639051688L;
	private Map<PaymentMethod, Settlement> usedTypes;
	private Collection<Settlement> allSettlements = null;
	
	public PaymentMethodAssignmentDialog(JFrame parent, Map<PaymentMethod, Settlement> usedTypes) {
		super(parent, Translatrix.getTranslationString("payment.selection.title"), GECAMedBaseDialog.OK_BUTTON_MODE);
		this.usedTypes = usedTypes;
		initComponents();
		JButton addBankAccountButton = new JButton(Translatrix.getTranslationString("payment.selection.add.bank"));
		addBankAccountButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				EnhancedAccountEditorDialog accountEditorDialog = new EnhancedAccountEditorDialog();
				SettlementInterface settlementInterface = (SettlementInterface) ManagerFactory.getRemote(SettlementBean.class);
				Settlement settlement = new Settlement();
				settlement.setTransferAccount(new Account());
				if(accountEditorDialog.editSettlement(settlement)) {
					try {
						settlementInterface.saveSettlement(settlement);
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				}
				//reset the list of settlements as a new one has been added
				allSettlements = null;
				//reset the table model to have an updated view of the data
				mappingTable.setModel(getMappingTableModel());
				mappingTable.setDefaultEditor(Settlement.class, getComboBoxEditor());
			}
		});
		addButton(addBankAccountButton);
	}
	
	@Override
	public int showCenteredDialog() {
		pack();
		return super.showCenteredDialog();
	}

	/**
	 * Initialize this component
	 */
	private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        mappingTable = new javax.swing.JTable();
        infoTextLabel = new javax.swing.JLabel(Translatrix.getTranslationString("payment.selection.text"));

        mappingTable.setModel(getMappingTableModel());
        
        mappingTable.setDefaultEditor(Settlement.class, getComboBoxEditor());
        jScrollPane1.setViewportView(mappingTable);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
            .addComponent(infoTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(infoTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
    }
	
    private TableCellEditor getComboBoxEditor() {
    	//create a jcombobox containing all available payment types
    	JComboBox selectionBox = new JComboBox(getSettlements().toArray());
    	TableCellEditor editor = new DefaultCellEditor(selectionBox);
		return editor;
	}
    
    private Collection<Settlement> getSettlements() {
    	if(allSettlements == null) {
	    	try {
	    		SettlementInterface settlementManager = (SettlementInterface) ManagerFactory.getRemote(SettlementBean.class);
	    		allSettlements = new ArrayList<Settlement>(settlementManager.getAllSettlements());
	    		Collections.sort((List<Settlement>)allSettlements, new Comparator<Settlement>() {
	    			public int compare(Settlement o1, Settlement o2) {
	    				return o1.toString().compareTo(o2.toString());
	    			}
				});
	    		
	    	} catch (Exception ex) {
	    		allSettlements = new ArrayList<Settlement>(0);
	    	}
    	}
    	return allSettlements;
    }

	private TableModel getMappingTableModel() {
    	Object[][] data = new Object[usedTypes.size()][2];
    	int i = 0;
    	for(Entry<PaymentMethod, Settlement> entry : usedTypes.entrySet()) {
			data[i++] = new Object[] {entry.getKey(), entry.getValue()};
		}
		TableModel mappingTableModel = new DefaultTableModel(data, new String[]{Translatrix.getTranslationString("payment.selection.table.keys"), Translatrix.getTranslationString("payment.selection.table.values")}) {
			
			@Override
			public void setValueAt(Object aValue, int row, int column) {
				super.setValueAt(aValue, row, column);
				if(column == 1 && aValue instanceof Settlement) {
					//set the value to the map
					usedTypes.put((PaymentMethod)getValueAt(row, 0), (Settlement)aValue);
				}
			}
			
			@Override
			public Object getValueAt(int row, int column) {
				if(column == 1 && super.getValueAt(row, column) == null && getSettlements().size() > 0) {
					boolean matchFound = false;
					//do some matching
					for(Settlement possibleMatch : getSettlements()) {
						PaymentMethod method = ((PaymentMethod)super.getValueAt(row, 0));
						//bank accounts have to be matched by the iban
						//Other payment methods will be matched by a simple case-insensitive compare
						if((method.isBankAccount() && possibleMatch.getTransferAccount() != null && possibleMatch.getTransferAccount().getIban().replaceAll(" ", "").equalsIgnoreCase(method.getValue().replaceAll(" ", "")))
								|| (possibleMatch.toString().equalsIgnoreCase(super.getValueAt(row, 0).toString()))) {
							
							setValueAt(possibleMatch, row, column);
							matchFound = true;
							break;
						}
					}
					if(!matchFound) {
						//set the value to the first settlement if there is none yet
						setValueAt(getSettlements().iterator().next(), row, column);
					}
				}
				return super.getValueAt(row, column);
			}
			
			@Override
			public Class<?> getColumnClass(int columnIndex) {
				if(columnIndex == 1) {
					return Settlement.class;
				}
				return super.getColumnClass(columnIndex);
			}
		};
		return mappingTableModel;
	}


	// Variables declaration - do not modify
    private javax.swing.JLabel infoTextLabel;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable mappingTable;
    // End of variables declaration
}
