# API Lấy Thông Tin Ví Của Người Dùng Hiện Tại

## Tổng quan

API này cho phép người dùng lấy thông tin ví điện tử của chính họ dựa trên tài khoản đang đăng nhập. Ví sẽ được tự động xác định từ userId trong token, không cần truyền ID ví.

## Endpoint

```
GET /api/Wallet/GetMyWallet
```

## Authentication

- **Required**: Yes
- **Type**: Bearer Token (JWT)
- **Role**: `Wallet.GetMyWallet`

## Request

### Headers

| Header | Value | Required |
|--------|-------|----------|
| `Authorization` | `Bearer {token}` | ✅ |

### Query Parameters

Không có query parameters.

### Request Body

Không có request body.

## Response

### Success Response (200 OK)

```json
{
  "id": 123,
  "balance": 1500000,
  "walletStatus": "Hoạt động",
  "userId": 456,
  "userName": "nguyenvana",
  "fullName": "Nguyễn Văn A"
}
```

### Response Model: `WalletDetailModel`

| Field | Type | Description |
|-------|------|-------------|
| `id` | `int` | ID của ví |
| `balance` | `decimal` | Số dư hiện tại |
| `walletStatus` | `string` | Trạng thái ví (ví dụ: "Hoạt động", "Tạm khóa") |
| `userId` | `int` | ID người sở hữu ví |
| `userName` | `string` | Tên đăng nhập của người sở hữu |
| `fullName` | `string` | Họ và tên của người sở hữu |

### Error Responses

#### 401 Unauthorized
Người dùng chưa đăng nhập hoặc token không hợp lệ.

```json
{
  "message": "Unauthorized"
}
```

#### 403 Forbidden
Người dùng không có quyền `Wallet.GetMyWallet`.

```json
{
  "message": "Forbidden"
}
```

#### 404 Not Found
Người dùng chưa có ví trong hệ thống.

```json
{
  "message": "Không tìm thấy ví của người dùng"
}
```

## Ví dụ sử dụng

### cURL

```bash
curl -X GET "https://api.example.com/api/Wallet/GetMyWallet" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```

### JavaScript (Fetch API)

```javascript
const getMyWallet = async () => {
  const response = await fetch('/api/Wallet/GetMyWallet', {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  if (!response.ok) {
    if (response.status === 404) {
      throw new Error('Bạn chưa có ví trong hệ thống');
    }
    throw new Error('Không thể lấy thông tin ví');
  }

  return await response.json();
};

// Sử dụng
try {
  const wallet = await getMyWallet();
  console.log(`Số dư: ${wallet.balance.toLocaleString('vi-VN')} VND`);
  console.log(`Trạng thái: ${wallet.walletStatus}`);
} catch (error) {
  console.error('Lỗi:', error.message);
}
```

### C# (HttpClient)

```csharp
public async Task<WalletDetailModel> GetMyWalletAsync()
{
    var response = await _httpClient.GetAsync("/api/Wallet/GetMyWallet");
    
    if (response.StatusCode == HttpStatusCode.NotFound)
    {
        throw new Exception("Bạn chưa có ví trong hệ thống");
    }
    
    response.EnsureSuccessStatusCode();
    return await response.Content.ReadFromJsonAsync<WalletDetailModel>();
}
```

### Vue.js / Nuxt.js

```javascript
// composables/useWallet.js
export const useWallet = () => {
  const wallet = ref(null);
  const loading = ref(false);
  const error = ref(null);

  const fetchMyWallet = async () => {
    loading.value = true;
    error.value = null;
    
    try {
      const response = await $fetch('/api/Wallet/GetMyWallet', {
        headers: {
          Authorization: `Bearer ${token}`
        }
      });
      wallet.value = response;
    } catch (err) {
      error.value = err.message;
    } finally {
      loading.value = false;
    }
  };

  return {
    wallet,
    loading,
    error,
    fetchMyWallet
  };
};

// Sử dụng trong component
const { wallet, loading, fetchMyWallet } = useWallet();
await fetchMyWallet();
```

## So sánh với GetById

| Feature | GetMyWallet | GetById |
|---------|-------------|---------|
| **Endpoint** | `GET /api/Wallet/GetMyWallet` | `GET /api/Wallet/GetById?id={id}` |
| **Parameters** | Không cần | Cần `id` (int) |
| **Permission** | `Wallet.GetMyWallet` | `Wallet.GetById` |
| **Use Case** | Lấy ví của chính mình | Lấy ví bất kỳ (admin/support) |
| **Security** | Tự động lấy từ token | Có thể xem ví của người khác |

## Use Cases

### 1. Hiển thị số dư trên Dashboard

```javascript
// Dashboard.vue
const displayWalletBalance = async () => {
  const wallet = await getMyWallet();
  document.getElementById('balance').textContent = 
    `${wallet.balance.toLocaleString('vi-VN')} VND`;
};
```

### 2. Kiểm tra trước khi chuyển tiền

```javascript
const checkBalanceBeforeTransfer = async (amount) => {
  const wallet = await getMyWallet();
  
  if (wallet.balance < amount) {
    throw new Error(`Số dư không đủ. Hiện tại: ${wallet.balance}, cần: ${amount}`);
  }
  
  if (wallet.walletStatus !== 'Hoạt động') {
    throw new Error('Ví của bạn đang bị khóa, không thể chuyển tiền');
  }
  
  return true;
};
```

### 3. Lấy wallet ID để thực hiện các thao tác khác

```javascript
const getMyWalletId = async () => {
  const wallet = await getMyWallet();
  return wallet.id;
};

// Sử dụng
const walletId = await getMyWalletId();
await performSomeAction(walletId);
```

## Luồng xử lý

```mermaid
sequenceDiagram
    participant Client
    participant API
    participant Auth
    participant WalletService
    participant Database

    Client->>API: GET /api/Wallet/GetMyWallet
    API->>Auth: Xác thực token
    Auth-->>API: User info (userId)
    
    alt Token không hợp lệ
        API-->>Client: 401 Unauthorized
    end
    
    alt Không có quyền
        API-->>Client: 403 Forbidden
    end
    
    API->>WalletService: GetWalletByUserId(userId)
    WalletService->>Database: Query wallet by userId
    Database-->>WalletService: Wallet data
    
    alt Không tìm thấy ví
        WalletService-->>API: null
        API-->>Client: 404 Not Found
    end
    
    WalletService-->>API: WalletDetailModel
    API-->>Client: 200 OK with wallet info
```

## Best Practices

### 1. Cache kết quả
Do thông tin ví không thay đổi thường xuyên, nên cache kết quả:

```javascript
let cachedWallet = null;
let cacheTime = null;
const CACHE_DURATION = 5 * 60 * 1000; // 5 phút

const getMyWalletCached = async () => {
  const now = Date.now();
  
  if (cachedWallet && cacheTime && (now - cacheTime) < CACHE_DURATION) {
    return cachedWallet;
  }
  
  cachedWallet = await getMyWallet();
  cacheTime = now;
  return cachedWallet;
};
```

### 2. Xử lý trường hợp chưa có ví
Một số user mới có thể chưa có ví:

```javascript
const getOrCreateWallet = async () => {
  try {
    return await getMyWallet();
  } catch (error) {
    if (error.status === 404) {
      // Hiển thị UI để tạo ví mới
      return await createWallet();
    }
    throw error;
  }
};
```

### 3. Refresh sau khi thực hiện giao dịch
Sau khi chuyển tiền hoặc nhận tiền, refresh thông tin ví:

```javascript
const transferMoney = async (destinationWalletId, amount) => {
  await transferMoneyAPI(destinationWalletId, amount);
  
  // Invalidate cache và lấy lại thông tin mới
  cachedWallet = null;
  return await getMyWallet();
};
```

## Tính năng

### 1. Bảo mật
- Tự động lấy userId từ token, không thể giả mạo
- Người dùng chỉ có thể xem ví của chính họ
- Yêu cầu authentication và authorization

### 2. Đơn giản
- Không cần biết wallet ID
- Không cần truyền parameters
- Một request đơn giản để lấy thông tin

### 3. Hiệu quả
- Truy vấn trực tiếp theo userId (indexed)
- Response nhẹ, chỉ chứa thông tin cần thiết
- Phù hợp cho mobile apps và SPAs

## Lưu ý

> [!IMPORTANT]
> API này chỉ trả về thông tin ví của người dùng hiện tại. Nếu cần xem ví của người khác (admin/support), sử dụng endpoint `GetById`.

> [!WARNING]
> Nếu người dùng chưa có ví trong hệ thống, API sẽ trả về 404 Not Found. Cần xử lý trường hợp này trong UI.

> [!TIP]
> Nên cache kết quả trong một khoảng thời gian ngắn để giảm số lượng request đến server.
