#include <iostream>
#include <string>

class BankAccount {
private:
    std::string accountHolder;
    int accountNumber;
    int pin;
    double balance;

public:
    // Constructor
    BankAccount(std::string name, int accNum, int userPin, double initialBalance) 
        : accountHolder(name), accountNumber(accNum), pin(userPin), balance(initialBalance) {}

    // Verify PIN
    bool authenticate(int inputPin) const {
        return pin == inputPin;
    }

    // Getters
    double getBalance() const {
        return balance;
    }

    std::string getAccountHolder() const {
        return accountHolder;
    }

    // Account Actions
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            std::cout << "\nSuccessfully deposited $" << amount << "\n";
            std::cout << "New Balance: $" << balance << "\n";
        } else {
            std::cout << "\nInvalid deposit amount.\n";
        }
    }

    bool withdraw(double amount) {
        if (amount <= 0) {
            std::cout << "\nInvalid withdrawal amount.\n";
            return false;
        }
        if (amount > balance) {
            std::cout << "\nInsufficient funds! Current Balance: $" << balance << "\n";
            return false;
        }
        balance -= amount;
        std::cout << "\nPlease collect your cash: $" << amount << "\n";
        std::cout << "Remaining Balance: $" << balance << "\n";
        return true;
    }
};

int main() {
    // Default account setup (Holder, Account No, PIN, Starting Balance)
    BankAccount userAccount("Alex Morgan", 100234, 1234, 500.00);

    int enteredPin;
    int attempts = 0;
    bool authenticated = false;

    std::cout << "====================================\n";
    std::cout << "       WELCOME TO MINI ATM          \n";
    std::cout << "====================================\n";

    // PIN Authentication Loop (Max 3 Attempts)
    while (attempts < 3) {
        std::cout << "Enter your 4-digit PIN: ";
        std::cin >> enteredPin;

        if (userAccount.authenticate(enteredPin)) {
            authenticated = true;
            break;
        } else {
            attempts++;
            std::cout << "Incorrect PIN. Attempts left: " << (3 - attempts) << "\n\n";
        }
    }

    if (!authenticated) {
        std::cout << "Card locked due to multiple incorrect attempts. Exiting...\n";
        return 0;
    }

    // ATM Main Menu
    int choice;
    do {
        std::cout << "\n------------------------------------\n";
        std::cout << "Welcome, " << userAccount.getAccountHolder() << "!\n";
        std::cout << "1. Check Balance\n";
        std::cout << "2. Deposit Money\n";
        std::cout << "3. Withdraw Money\n";
        std::cout << "4. Exit\n";
        std::cout << "Choose an option (1-4): ";
        std::cin >> choice;

        switch (choice) {
            case 1:
                std::cout << "\nYour Current Balance: $" << userAccount.getBalance() << "\n";
                break;

            case 2: {
                double depositAmount;
                std::cout << "Enter amount to deposit: $";
                std::cin >> depositAmount;
                userAccount.deposit(depositAmount);
                break;
            }

            case 3: {
                double withdrawAmount;
                std::cout << "Enter amount to withdraw: $";
                std::cin >> withdrawAmount;
                userAccount.withdraw(withdrawAmount);
                break;
            }

            case 4:
                std::cout << "\nThank you for using Mini ATM. Goodbye!\n";
                break;

            default:
                std::cout << "\nInvalid choice. Please pick between 1 and 4.\n";
        }
    } while (choice != 4);

    return 0;
}