package me.teridax.jcash.gui.account;

import me.teridax.jcash.Logging;
import me.teridax.jcash.banking.accounts.Account;
import me.teridax.jcash.banking.accounts.CurrentAccount;
import me.teridax.jcash.banking.accounts.SavingsAccount;
import me.teridax.jcash.banking.management.Profile;
import me.teridax.jcash.decode.StringDecoder;

import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
import java.util.Comparator;

import static javax.swing.SwingConstants.RIGHT;
import static me.teridax.jcash.gui.Utils.addGridBagRow;
import static me.teridax.jcash.lang.Translator.translate;

public class AccountView extends JPanel {

    private JTextField iban;
    private JTextField name;
    private JTextField address;
    private JTextField bankName;
    private JTextField blz;
    private JTextField type;
    private JTextField typeSpecialProperty;
    private JTextField balance;
    private JLabel typeSpecialLabel;
    private JComboBox<String> accountSelection;
    private JButton logout;
    private JButton transfer;
    private JButton deposit;
    private JButton takeoff;

    public AccountView() {
        createComponents();
        createLayout();

        setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
    }

    public void setProfile(Profile profile) {
        this.updateAccountVariables(profile);

        this.accountSelection.removeAllItems();

        var accounts = profile.getAccounts();
        Arrays.stream(accounts).sorted(Comparator.comparingInt(Account::getIban)).forEach(a -> this.accountSelection.addItem(a.getDescription()));

        this.accountSelection.setSelectedItem(profile.getPrimaryAccount().getDescription());
    }

    private void createLayout() {
        var content = new JPanel(new GridBagLayout());

        this.setLayout(new BorderLayout(12, 12));
        this.add(new JScrollPane(content), BorderLayout.CENTER);

        var constraints = new GridBagConstraints();

        constraints.gridwidth = 4;
        constraints.insets = new Insets(12, 12, 12, 12);

        var accountSelectionPanel = new JPanel(new BorderLayout(12, 0));
        accountSelectionPanel.add(iban, BorderLayout.CENTER);
        accountSelectionPanel.add(accountSelection, BorderLayout.EAST);

        addGridBagRow(constraints, content, accountSelectionPanel, 1, translate("IBAN"));
        addGridBagRow(constraints, content, name, 2, translate("Name/Family-name"));
        addGridBagRow(constraints, content, address, 3, translate("Address"));
        addGridBagRow(constraints, content, bankName, 4, translate("Bank"));
        addGridBagRow(constraints, content, blz, 5, translate("BLZ"));
        addGridBagRow(constraints, content, type, 6, translate("Account"));
        addGridBagRow(constraints, content, typeSpecialProperty, 7, typeSpecialLabel);
        addGridBagRow(constraints, content, balance, 8, translate("Balance"));

        var buttonPanel = Box.createHorizontalBox();
        buttonPanel.add(Box.createHorizontalStrut(4));
        buttonPanel.add(logout);
        buttonPanel.add(Box.createHorizontalStrut(4));
        buttonPanel.add(Box.createGlue());
        buttonPanel.add(transfer);
        buttonPanel.add(Box.createHorizontalStrut(4));
        buttonPanel.add(deposit);
        buttonPanel.add(Box.createHorizontalStrut(4));
        buttonPanel.add(takeoff);
        add(buttonPanel, BorderLayout.SOUTH);
    }

    private void createComponents() {
        this.blz = new JTextField();
        this.iban = new JTextField();
        this.address = new JTextField();
        this.bankName = new JTextField();
        this.name = new JTextField();
        this.type = new JTextField();
        this.balance = new JTextField();
        this.typeSpecialProperty = new JTextField();

        this.blz.setEditable(false);
        this.iban.setEditable(false);
        this.address.setEditable(false);
        this.bankName.setEditable(false);
        this.name.setEditable(false);
        this.type.setEditable(false);
        this.balance.setEditable(false);
        this.typeSpecialProperty.setEditable(false);

        this.typeSpecialLabel = new JLabel("", RIGHT);

        this.accountSelection = new JComboBox<>();

        this.logout = new JButton(translate("Logout"));
        this.transfer = new JButton(translate("Transfer"));
        this.deposit = new JButton(translate("Deposit"));
        this.takeoff = new JButton(translate("Takeoff"));
    }

    public JComboBox<String> getAccountSelection() {
        return accountSelection;
    }

    public JButton getLogout() {
        return logout;
    }

    public JButton getTransfer() {
        return transfer;
    }

    public JButton getDeposit() {
        return deposit;
    }

    public JButton getTakeoff() {
        return takeoff;
    }

    public void updateAccountVariables(Profile profile) {
        Logging.LOGGER.finer("Updating account view");
        var bank = profile.getBank();
        var account = profile.getPrimaryAccount();
        var owner = profile.getOwner();

        this.blz.setText(bank.getBlz());
        this.bankName.setText(bank.getName());

        this.iban.setText(String.valueOf(account.getIban()));
        this.name.setText(owner.getName() + " " + owner.getFamilyName());
        this.address.setText(owner.getStreet() + " " + owner.getCity());

        this.balance.setText(StringDecoder.getNumberFormat().format(account.getBalance()) + " €");

        this.type.setText(translate(account.getClass().getSimpleName()));
        if (account instanceof CurrentAccount) {
            this.typeSpecialLabel.setText(translate("Overdraft"));
            this.typeSpecialProperty.setText(StringDecoder.getNumberFormat().format(((CurrentAccount) account).getOverdraft()) + " €");
        } else if (account instanceof SavingsAccount) {
            this.typeSpecialLabel.setText(translate("Interest rate"));
            this.typeSpecialProperty.setText(((SavingsAccount) account).getInterest() + " %");
        } else {
            Logging.LOGGER.severe("Type of new primary account cannot be determined: " + account.getClass().getName());
        }
    }
}
