/*
 * This file is part of choco-solver, http://choco-solver.org/
 *
 * Copyright (c) 2024, IMT Atlantique. All rights reserved.
 *
 * Licensed under the BSD 4-clause license.
 *
 * See LICENSE file in the project root for full license information.
 */


import java.util.ArrayList;

/**
 * Represents a bank account with a balance and a transaction history.
 */
public class BankAccount {
    private final Person owner;
    private final int accountNumber;
    private float balance;
    private final ArrayList<Float> history;

    /**
     * Initializes a new instance of the BankAccount class.
     *
     * @param accountNumber: the account number
     */
    public BankAccount(int accountNumber, Person owner) {
        if (owner == null) {
            throw new IllegalArgumentException("Owner must be specified");
        }
        this.accountNumber = accountNumber;
        this.owner = owner;
        this.balance = 0;
        this.history = new ArrayList<>();
        owner.addAccount(this);
    }

    /**
     * Deposits money into the bank account.
     *
     * @param amount: the amount to be deposited
     * @throws IllegalArgumentException if the amount is not positive
     */
    public void deposit(float amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Amount must be positive");
        }
        this.balance += amount;
        this.history.add(amount);
    }

    /**
     * Withdraws money from the bank account.
     *
     * @param amount: the amount to be withdrawn
     * @throws IllegalArgumentException if the amount is not positive or greater than the balance
     */
    public void withdraw(float amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Amount must be positive");
        }
        if (this.balance < amount) {
            throw new IllegalArgumentException("Insufficient funds");
        }
        this.balance -= amount;
        this.history.add(-amount);
    }

    /**
     * Returns the account number of the bank account.
     *
     * @return the account number
     */
    public int getAccountNumber() {
        return this.accountNumber;
    }

    /**
     * Returns the balance of the bank account.
     *
     * @return the balance
     */
    public float getBalance() {
        return this.balance;
    }

    /**
     * Returns the transaction history of the bank account.
     *
     * @return the transaction history
     */
    public ArrayList<Float> getTransactionHistory() {
        return this.history;
    }

    /**
     * Returns the owner of the bank account.
     *
     * @return the owner
     */
    public Person getOwner() {
        return this.owner;
    }

    /**
     * Returns a string representation of the bank account.
     *
     * @return a string representation of the bank account
     */
    // The annotation indicates that the following method overrides a method in the superclass, here Object.
    // This annotation is optional, but it is very good practice to use it.
    @Override
    public String toString() {
        return "Account number " + this.accountNumber + " from " + this.owner.fullName() + " has " +
                this.balance + " € and has done " + this.history.size() + " transactions";
    }
}