package me.teridax.jcash.gui.login;

import me.teridax.jcash.Logging;
import me.teridax.jcash.banking.management.BankingManagementSystem;
import me.teridax.jcash.gui.Utils;

import java.awt.event.ActionEvent;
import java.util.Optional;

import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.showMessageDialog;
import static me.teridax.jcash.lang.Translator.translate;

public class LoginController {

    private final LoginView view;
    private final LoginData data;

    private AccountSelectionListener listener;

    public LoginController() {
        this.view = new LoginView();
        this.data = new LoginData();

        addActionListeners();
    }

    public void setBankingManagementSystem(BankingManagementSystem bms) {
        this.data.setBms(bms);
    }

    private void addActionListeners() {
        this.view.getLogin().addActionListener(this::login);
    }

    private Optional<Integer> getIban() {
        try {
            var iban = this.view.getIban().getText();
            return Optional.of(Integer.parseUnsignedInt(iban));
        } catch (NumberFormatException e) {
            Logging.LOGGER.warning("IBAN text field contains invalid value: " + this.view.getIban().getText());
            return Optional.empty();
        }
    }

    private Optional<Integer> getPin() {
        try {
            var iban = this.view.getPin().getPassword();
            return Optional.of(Integer.parseUnsignedInt(new String(iban)));
        } catch (NumberFormatException e) {
            Logging.LOGGER.severe("PIN text field contains invalid value: " + String.valueOf(view.getPin().getPassword()));
            return Optional.empty();
        }
    }

    private void login(ActionEvent ignored) {
        var blz = this.view.getBlz().getText();
        var iban = this.getIban();
        if (iban.isEmpty()) {
            Utils.error("invalid IBAN entered");
            return;
        }

        var pin = this.getPin();
        if (pin.isEmpty()) {
            Utils.error("invalid PIN entered");
            return;
        }

        var account = this.data.authenticateAccount(blz, iban.get(), pin.get());
        if (account.isPresent()) {
            this.listener.onAccountSelected(account.get());
        } else {
            Logging.LOGGER.warning("invalid login credentials: " + iban + " / " + pin);
         }
    }

    public void addAccountSelectionListener(AccountSelectionListener listener) {
        this.listener = listener;
    }

    public LoginView getView() {
        return view;
    }

    public LoginData getData() {
        return data;
    }

    public void logout() {
        this.view.getPin().setText("");
    }
}
