package info.johannesgruber.jgnash.plugin.csvimport;

import info.johannesgruber.jgnash.plugin.csvimport.parser.CsvParser;
import info.johannesgruber.jgnash.utils.ResourceUtils;

import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;

import javax.swing.Action;
import javax.swing.JFileChooser;
import javax.swing.SwingWorker;

import jgnash.convert.imports.GenericImport;
import jgnash.convert.imports.ImportBank;
import jgnash.convert.imports.ImportTransaction;
import jgnash.engine.Account;
import jgnash.engine.Engine;
import jgnash.engine.EngineFactory;
import jgnash.ui.StaticUIMethods;
import jgnash.ui.UIApplication;
import jgnash.ui.actions.AbstractEnabledAction;
import jgnash.ui.wizards.imports.ImportDialog;

public class ImportCsvAction extends AbstractEnabledAction {

  private static final long serialVersionUID = -229378377538399612L;
  private static final Logger LOG = Logger.getLogger(ImportCsvAction.class.getName());

	public ImportCsvAction() {
		final ResourceBundle rb = ResourceUtils.getBundle();

		putValue(NAME, rb.getString("Menu.ImportCsv.Name"));
		putValue(Action.SHORT_DESCRIPTION, rb.getString("Menu.ImportCsv.Tooltip"));
		
	}

	public void actionPerformed(ActionEvent e) {
		final ResourceBundle rb = ResourceUtils.getBundle();

		final Engine engine = EngineFactory.getEngine(EngineFactory.DEFAULT);

		if (engine == null || engine.getRootAccount().getChildCount() == 0) {
			StaticUIMethods.displayError(rb
			    .getString("Message.Error.CreateBasicAccounts"));
			return;
		}

		// Choose the file to be imported
		final JFileChooser chooser = new JFileChooser();
		chooser.setMultiSelectionEnabled(false);
		try {
	    chooser.setCurrentDirectory(new File(ImportCsvAction.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()));
    } catch (URISyntaxException e1) {
    	LOG.warning("Could not set the directory correctly");
    }

		if (chooser.showOpenDialog(UIApplication.getFrame()) == JFileChooser.APPROVE_OPTION) {
			File file = chooser.getSelectedFile();
			if (file.exists()) {
				new ImportCsv(file.getAbsolutePath()).execute();
			}
		}
	}

	final static class ImportCsv extends SwingWorker<ImportBank, Void> {
		private final String fileName;

		ImportCsv(String fileName) {
			this.fileName = fileName;
		}

		@Override
		protected ImportBank doInBackground() throws Exception {
			CsvParser parser = new CsvParser();

			try (LineNumberReader reader = new LineNumberReader(
			    new InputStreamReader(new FileInputStream(fileName),
			        StandardCharsets.ISO_8859_1))) {
				CsvFile parsedFile = parser.parse(reader);
				return CsvImporter.convert(parsedFile);
			}
		}

		@Override
		protected void done() {

			try {
				ImportDialog d = new ImportDialog();

				ImportBank bank = get();

				d.setSetting(ImportDialog.Settings.BANK, bank);
				d.setVisible(true);

				if (d.isWizardValid()) {
					final Account account = (Account) d
					    .getSetting(ImportDialog.Settings.ACCOUNT);

					@SuppressWarnings("unchecked")
					final List<ImportTransaction> transactions = (List<ImportTransaction>) d
					    .getSetting(ImportDialog.Settings.TRANSACTIONS);

					GenericImport.importTransactions(transactions, account);
				}
			} catch (InterruptedException | ExecutionException e) {
				throw new RuntimeException(e);
			}
		}
	}
	
}
