from __future__ import annotations

from typing import *

if TYPE_CHECKING:
    from bankaccount import BankAccount

class Person:
    """ Represents a person with a name, firstname, age and the list of bank accounts.
    """
    def __init__(self, name: str, firstname: str, age: int): # The constructor
        """ Constructs a new Person object with the specified lastname, firstname, age, and his/her accounts.
        """
        self.__lastname = name.upper();
        self.__firstname = firstname
        self.__age = age
        self.__accounts = []

    def fullname(self) -> str:
        return f"{self.__firstname} {self.__lastname}"

    def get_accounts(self) -> List[BankAccount]:
        """ Returns the list of bank accounts of the person.
        """
        return self.__accounts

    def add_account(self, account: BankAccount):
        """ Adds the specified bank account to the list of bank accounts of the person if it is not already present.
        Args:
            account (BankAccount): The bank account to add.
        Raises:
            ValueError: If the specified bank account is `None`.
        """
        if account is None:
            raise ValueError("Account cannot be None")

        if account not in self.__accounts:
            self.__accounts.append(account)

    def remove_account(self, account: BankAccount):
        """ Removes the specified bank account from the list of bank accounts of the person.
        Args:
            account (BankAccount): The bank account to remove.
        """
        if account in self.__accounts:
            self.__accounts.remove(account)


    def __str__(self) -> str:
        """ Returns a string representation of the Person object.
        """
        return f"{self.__firstname} {self.__lastname} ({self.__age} old) has {len(self.__accounts)} bank accounts"

    def __eq__(self, other: object) -> bool:
        """ Compares two Person objects.
        Args:
            other (object): The object to compare with.
        Returns:
            bool: `True` if the objects are equal, `False` otherwise.
            Two persons are equal if they have the same lastname, firstname and age.
        """
        if not isinstance(other, Person):
            return False
        return self.__firstname == other.__firstname and self.__lastname == other.__lastname and self.__age == other.__age