class Customer:
    """
    Tracks the customers data (orders, table number, name, total payments, 
    ordered food, turn in the queue, served or not, and if he left or not), 
    you can get all the required data using 'customer_x.info['attribute']'
    you can also add to his order using 'new_order()', serve him using 'serve()'
    and sign him off using 'leave()'.
    *Note: the customer might sign in and order later
    """
    
    _active_customers={}
    _all_customers={}
    customer_counter=1
    
    def __init__(self, name:str, table:int, *argu, order_code:None|int=None, turn_in_queue:None|int=None):
        self.name=name
        self.table=table
        self.ordered_food=list(argu)
        self.order_code=order_code
        self._total_cost=0        # protected so it can't be changed
        self.turn_in_queue=turn_in_queue
        self._served=False        # protected so it's only true when the customer is served
        self.present=True         # checks if the customer left or still have the table  
        self.customer_id=f"{name}, id:{Customer.customer_counter}"
        # to-do: make table taken
        Customer._active_customers[self.id]=self
        Customer._all_customers[self.id]=self
        Customer.customer_counter+=1
        
    @classmethod
    def active_customers(cls):
        return Customer._active_customers.keys()
        
    @classmethod
    def all_customers(cls):
        return Customer._all_customers.keys()    
        
    @property
    def is_served(self):
        return self._served
        
    @property
    def total_cost(self):    #calculates the total payments by suming each meal cost
        # to-do: calculate the cost of each meal
        return self._total_cost
    
    @property    
    def info(self):
        return {
            "name": self.name,
            "table": self.table,
            "ordered_food": self.ordered_food,
            "order_code": self.order_code,
            "turn_in_queue": self.turn_in_queue,
            "served": self._served,
            "present": self.present
        }        
    
    def serve(self):
        if self.is_served: print(f"Customer {self.name} doesn't need serves!"); return 
        self._served=True
        self.order_code=None
        self.turn_in_queue=None
        print(f"Customer {self.name} was served!")
        
    def leave(self):     # signs off customers and make the table empty
        # to-do: make the table empty 
        self.present=False
        del Customer._active_customers[self.id]
        print(f"Customer {self.name} left!")
        
    def new_order(self, order_code:int, turn_in_queue:int, *argu):
        self.order_code=order_code
        self.ordered_food.extend(argu)
        self.turn_in_queue=turn_in_queue
        self._served=False
        print(f"Customer {self.name} ordered the next: \n{'\n'.join(str(item) for item in argu)}") # to-do: make order table with price of each meal
        
"""
notes: search for 'to-do:' part 
in the code and customise it based
on your part
"""

"""
plans:  add online/offline orders
        add number of customers on the table
"""