You are a helpful assistant.
system
Sử dụng C#, thiết kế một trình mô phỏng máy ATM đơn giản với yêu cầu xác thực người dùng thông qua mã PIN và xác thực đa yếu tố, cho phép kiểm tra số dư, gửi tiền, rút tiền trong các giới hạn nhất định, đồng thời xử lý các lỗi liên quan đến mã PIN không hợp lệ và giao dịch thất bại. Hãy đảm bảo rằng giao diện người dùng được thiết kế để nâng cao trải nghiệm người dùng, đồng thời áp dụng mẫu MVC để cấu trúc mã của bạn một cách hiệu quả. Cuối cùng, hãy ghi lại hoạt động của người dùng vì lý do bảo mật và cho phép họ thay đổi mã PIN sau khi đăng nhập thành công.
user
Để thiết kế một trình mô phỏng máy ATM đơn giản bằng C# với các yêu cầu đã nêu, bạn có thể áp dụng mẫu kiến trúc MVC (Model-View-Controller) để tổ chức mã nguồn một cách hiệu quả. Dưới đây là một hướng dẫn cơ bản về cách thực hiện:

### 1. Model

Model sẽ chứa các lớp đại diện cho dữ liệu và logic nghiệp vụ của ứng dụng.

```csharp
public class Account
{
    public string AccountNumber { get; set; }
    public string Pin { get; set; }
    public decimal Balance { get; set; }

    public bool ValidatePin(string inputPin)
    {
        return Pin == inputPin;
    }

    public bool Withdraw(decimal amount)
    {
        if (amount > 0 && amount <= Balance)
        {
            Balance -= amount;
            return true;
        }
        return false;
    }

    public void Deposit(decimal amount)
    {
        if (amount > 0)
        {
            Balance += amount;
        }
    }

    public void ChangePin(string newPin)
    {
        Pin = newPin;
    }
}
```

### 2. View

View sẽ chịu trách nhiệm hiển thị giao diện người dùng và nhận đầu vào từ người dùng.

```csharp
public class AtmView
{
    public void ShowWelcomeMessage()
    {
        Console.WriteLine("Chào mừng đến với máy ATM!");
    }

    public string RequestPin()
    {
        Console.Write("Vui lòng nhập mã PIN: ");
        return Console.ReadLine();
    }

    public void ShowBalance(decimal balance)
    {
        Console.WriteLine($"Số dư hiện tại của bạn là: {balance:C}");
    }

    public decimal RequestAmount(string action)
    {
        Console.Write($"Nhập số tiền bạn muốn {action}: ");
        return decimal.Parse(Console.ReadLine());
    }

    public void ShowTransactionResult(bool success, string action)
    {
        if (success)
        {
            Console.WriteLine($"{action} thành công!");
        }
        else
        {
            Console.WriteLine($"{action} thất bại!");
        }
    }

    public string RequestNewPin()
    {
        Console.Write("Nhập mã PIN mới: ");
        return Console.ReadLine();
    }

    public void ShowErrorMessage(string message)
    {
        Console.WriteLine($"Lỗi: {message}");
    }
}
```

### 3. Controller

Controller sẽ xử lý logic điều khiển, tương tác giữa Model và View.

```csharp
public class AtmController
{
    private Account _account;
    private AtmView _view;

    public AtmController(Account account, AtmView view)
    {
        _account = account;
        _view = view;
    }

    public void Run()
    {
        _view.ShowWelcomeMessage();
        string pin = _view.RequestPin();

        if (_account.ValidatePin(pin))
        {
            // Xác thực đa yếu tố có thể được thêm vào đây

            bool exit = false;
            while (!exit)
            {
                Console.WriteLine("Chọn một tùy chọn: 1. Kiểm tra số dư 2. Rút tiền 3. Gửi tiền 4. Đổi mã PIN 5. Thoát");
                string choice = Console.ReadLine();

                switch (choice)
                {
                    case "1":
                        _view.ShowBalance(_account.Balance);
                        break;
                    case "2":
                        decimal withdrawAmount = _view.RequestAmount("rút");
                        bool withdrawSuccess = _account.Withdraw(withdrawAmount);
                        _view.ShowTransactionResult(withdrawSuccess, "Rút tiền");
                        break;
                    case "3":
                        decimal depositAmount = _view.RequestAmount("gửi");
                        _account.Deposit(depositAmount);
                        _view.ShowTransactionResult(true, "Gửi tiền");
                        break;
                    case "4":
                        string newPin = _view.RequestNewPin();
                        _account.ChangePin(newPin);
                        _view.ShowTransactionResult(true, "Đổi mã PIN");
                        break;
                    case "5":
                        exit = true;
                        break;
                    default:
                        _view.ShowErrorMessage("Lựa chọn không hợp lệ.");
                        break;
                }
            }
        }
        else
        {
            _view.ShowErrorMessage("Mã PIN không hợp lệ.");
        }
    }
}
```

### 4. Main Program

Chương trình chính để khởi chạy ứng dụng.

```csharp
class Program
{
    static void Main(string[] args)
    {
        Account account = new Account { AccountNumber = "123456789", Pin = "1234", Balance = 1000.00m };
        AtmView view = new AtmView();
        AtmController controller = new AtmController(account, view);

        controller.Run();
    }
}
```

### Ghi chú

- **Xác thực đa yếu tố**: Bạn có thể thêm một lớp xác thực thứ hai, ví dụ như mã OTP gửi qua email hoặc SMS.
- **Ghi lại hoạt động của người dùng**: Bạn có thể sử dụng một hệ thống ghi log để lưu lại các hoạt động của người dùng, ví dụ như sử dụng `System.IO` để ghi vào file hoặc sử dụng một thư viện logging như `NLog` hoặc `log4net`.
- **Giao diện người dùng**: Để nâng cao trải nghiệm người dùng, bạn có thể sử dụng các thư viện giao diện đồ họa như Windows Forms hoặc WPF nếu muốn phát triển một ứng dụng có giao diện đồ họa.

Đây chỉ là một mô phỏng đơn giản và có thể mở rộng thêm nhiều tính năng khác tùy theo yêu cầu cụ thể.
assistant