/*
 * 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 person with a name, firstname, age and the list of bank accounts.
 */
public class Person {

    private final String firstName;
    private final String lastName;
    private int age; // not final because it can change
    private final ArrayList<BankAccount> accounts;

    /**
     * Initializes a new instance of the Person class with the specified first name, last name, and age.
     *
     * @param lastName  the last name
     * @param firstName the first name
     * @param age       the age
     */
    public Person(String lastName, String firstName, int age) {
        this.lastName = lastName.toUpperCase();
        this.firstName = firstName;
        this.age = age;
        this.accounts = new ArrayList<>();
    }

    /**
     * Returns the full name of the person.
     *
     * @return the full name
     */
    public String fullName() {
        return this.firstName + " " + this.lastName;
    }

    /**
     * Returns a list that contains all the bank accounts of the person.
     *
     * @return the list of bank accounts
     */
    public ArrayList<BankAccount> getAccounts() {
        return accounts;
    }

    /**
     * Add a bank account to the person.
     * If the account is already added, it will not be added again.
     *
     * @param account the account to add
     * @throws IllegalArgumentException if the account is null
     */
    public void addAccount(BankAccount account) {
        if (account == null) {
            throw new IllegalArgumentException("Account cannot be null");
        }
        if (!this.accounts.contains(account)) {
            this.accounts.add(account);
        }
    }

    /**
     * Remove a bank account from the person, if it exists.
     *
     * @param account the account to remove
     */
    public void removeAccount(BankAccount account) {
        this.accounts.remove(account);
    }

    /**
     * Returns a string representation of the person.
     * @return a string representation of the person
     */
    // 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 firstName + " " + lastName + " (" + age + " old) has " + accounts.size() + " bank accounts";
    }

    /**
     * Compares two Person objects.
     *
     * @param obj the object to compare
     * @return true if the objects are equal, false otherwise.
     * Two persons are equal if they have the same lastname, firstname and age.
     */
    @Override
    public boolean equals(Object obj) {
        // First, check if the object given is an instance of Person
        if (obj instanceof Person) {
            // If it is, cast it to a Person object
            Person person = (Person) obj;
            // Then, compare the fields of the two objects
            return this.firstName.equals(person.firstName) && this.lastName.equals(person.lastName) && this.age == person.age;
        }
        return false;
    }
}
