"""
Program to Generate Card Numbers with Expiry and CVV

This program generates a specified number of card numbers with expiry dates and CVV using the Luhn algorithm.

"""

import random
import logging

# Setting up logging to monitor performance and errors
logging.basicConfig(level=logging.INFO)

def generate_card_numbers(amount: int) -> list:
    """
    Generate Card Numbers with Expiry and CVV

    This function generates a specified number of card numbers with expiry dates and CVV using the Luhn algorithm.

    Args:
    amount (int): The number of card numbers to generate.

    Returns:
    list: A list of dictionaries containing card numbers, expiry dates, and CVV.

    Examples:
    >>> generate_card_numbers(3)
    [{'card_number': '4532015112890363', 'expiry_date': '12/23', 'cvv': '123'}, 
    {'card_number': '5186879824520016', 'expiry_date': '06/24', 'cvv': '456'}, 
    {'card_number': '4024007143140731', 'expiry_date': '09/25', 'cvv': '789'}]
    """
    try:
        logging.info(f"Generating {amount} card numbers...")
        card_numbers = []
        for _ in range(amount):
            card_number = generate_card_number()
            expiry_date = generate_expiry_date()
            cvv = generate_cvv()
            card_numbers.append({
                'card_number': card_number,
                'expiry_date': expiry_date,
                'cvv': cvv
            })
        return card_numbers
    except Exception as e:
        logging.error(f"An error occurred: {e}")
        return None

def generate_card_number() -> str:
    """
    Generate Card Number using Luhn Algorithm

    This function generates a random 16-digit card number using the Luhn algorithm.

    Returns:
    str: A 16-digit card number.

    Examples:
    >>> generate_card_number()
    '4532015112890363'
    """
    try:
        # Generate the first 15 digits randomly
        digits = [random.randint(0, 9) for _ in range(15)]
        
        # Calculate the checksum digit using the Luhn algorithm
        checksum = calculate_luhn_checksum(digits)
        
        # Append the checksum digit to the card number
        card_number = ''.join(map(str, digits)) + str(checksum)
        
        return card_number
    except Exception as e:
        logging.error(f"An error occurred: {e}")
        return None

def calculate_luhn_checksum(digits: list) -> int:
    """
    Calculate Luhn Checksum

    This function calculates the Luhn checksum for a list of digits.

    Args:
    digits (list): A list of digits.

    Returns:
    int: The Luhn checksum.

    Examples:
    >>> calculate_luhn_checksum([4, 5, 3, 2, 0, 1, 5, 1, 1, 2, 8, 9, 0, 3])
    3
    """
    try:
        # Double every second digit, starting from the right
        doubled_digits = [2 * digit if index % 2 == 1 else digit for index, digit in enumerate(digits)]
        
        # Subtract 9 from any digits greater than 9
        subtracted_digits = [digit - 9 if digit > 9 else digit for digit in doubled_digits]
        
        # Calculate the sum of all digits
        checksum = sum(subtracted_digits)
        
        # Calculate the checksum digit
        checksum_digit = (10 - (checksum % 10)) % 10
        
        return checksum_digit
    except Exception as e:
        logging.error(f"An error occurred: {e}")
        return None

def generate_expiry_date() -> str:
    """
    Generate Expiry Date

    This function generates a random expiry date in the format MM/YY.

    Returns:
    str: The expiry date in the format MM/YY.

    Examples:
    >>> generate_expiry_date()
    '12/23'
    """
    try:
        # Generate random month and year
        month = random.randint(1, 12)
        year = random.randint(22, 30)
        
        # Format the expiry date
        expiry_date = f"{month:02d}/{year:02d}"
        
        return expiry_date
    except Exception as e:
        logging.error(f"An error occurred: {e}")
        return None

def generate_cvv() -> str:
    """
    Generate CVV

    This function generates a random 3-digit CVV.

    Returns:
    str: The CVV.

    Examples:
    >>> generate_cvv()
    '123'
    """
    try:
        # Generate random 3-digit CVV
        cvv = str(random.randint(100, 999))
        
        return cvv
    except Exception as e:
        logging.error(f"An error occurred: {e}")
        return None

if __name__ == "__main__":
    card_numbers = generate_card_numbers(3)
    if card_numbers:
        for card in card_numbers:
            print(f"Card Number: {card['card_number']}")
            print(f"Expiry Date: {card['expiry_date']}")
            print(f"CVV: {card['cvv']}")
            print()
    else:
        print("Failed to generate card numbers.")