package me.teridax.jcash.gui.deposit;

import me.teridax.jcash.Logging;
import me.teridax.jcash.banking.accounts.Account;
import me.teridax.jcash.gui.InvalidInputException;
import me.teridax.jcash.gui.Utils;

import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.text.ParseException;

/**
 * Class for controlling the deposit operation via a dialog.
 */
public class DepositController {

    private final DepositView view;
    /**
     * Account to deposit money to.
     */
    private final Account account;

    public DepositController(Account account) {
        this.account = account;

        this.view = new DepositView(account.getBalance());

        this.view.getDeposit().addActionListener(e -> depositMoney());
        this.view.getCancel().addActionListener(e -> view.dispose());
        this.view.getValue().getDocument().addDocumentListener(new DocumentListener() {

            /**
             * Validate the amount to deposit and update display
             * variables.
             */
            private void validateInputState() {
                var balance = account.getBalance();
                try {
                    view.getValue().commitEdit();
                    var amount = view.getAmount();
                    view.setCommittedValue(amount, balance + amount);
                    view.getDeposit().setEnabled(true);
                } catch (InvalidInputException | ParseException ex) {
                    view.setCommittedValue(0, balance);
                    view.getDeposit().setEnabled(false);
                }
            }

            @Override
            public void insertUpdate(DocumentEvent documentEvent) {
                validateInputState();
            }

            @Override
            public void removeUpdate(DocumentEvent documentEvent) {
                validateInputState();
            }

            @Override
            public void changedUpdate(DocumentEvent documentEvent) {
                validateInputState();
            }
        });
        this.view.showDialog();
    }

    /**
     * Deposit the last valid value to the account.
     * This method may display error dialogs when no money can be deposited.
     */
    private void depositMoney() {
        try {
            var amount = view.getAmount();
            Logging.LOGGER.fine("Depositing money of account: " + account.getIban() + " amount: " + amount);
            account.deposit(amount);
        } catch (IllegalArgumentException ex) {
            Logging.LOGGER.severe("Cannot deposit money of account: " + account.getIban() + " because: " + ex.getMessage());
            Utils.error(ex.getMessage());
        } catch (InvalidInputException ex) {
            Utils.error(ex.getMessage());
        }
        view.dispose();
    }
}
