//
//  APIUsageExamples.swift
//  AppClientBaseSwift
//
//  Examples of using APIResponse wrapper
//  Ví dụ sử dụng APIResponse wrapper
//

import Foundation

/*
 
 HƯỚNG DẪN SỬ DỤNG API RESPONSE WRAPPER
 ======================================
 
 Server của bạn trả về response với format:
 {
   "success": true,
   "data": { ... } hoặc [ ... ],
   "error": null,
   "pagination": null
 }
 
 Tất cả API calls phải sử dụng wrapper tương ứng.
 
 */

// MARK: - Example 1: Single Object Response
// Ví dụ 1: Response trả về 1 object

/*
 GET /api/v1/users/me
 Response:
 {
   "success": true,
   "data": {
     "id": "...",
     "email": "...",
     "name": "..."
   },
   "error": null,
   "pagination": null
 }
 */

func exampleFetchUser() async throws -> User {
    // Cách 1: Dùng unwrap() helper (recommended)
    let response: APIResponse<User> = try await APIService.shared.get(
        endpoint: "/users/me"
    )
    let user = try response.unwrap()
    return user
    
    // Cách 2: Manual check
    // let response: APIResponse<User> = try await APIService.shared.get(endpoint: "/users/me")
    // guard response.success, let user = response.data else {
    //     throw APIError.serverError(statusCode: 400, message: response.error ?? "Failed")
    // }
    // return user
}

// MARK: - Example 2: List/Array Response
// Ví dụ 2: Response trả về danh sách

/*
 GET /api/v1/users?page=1
 Response:
 {
   "success": true,
   "data": [
     { "id": "1", "email": "...", "name": "..." },
     { "id": "2", "email": "...", "name": "..." }
   ],
   "error": null,
   "pagination": {
     "currentPage": 1,
     "pageSize": 20,
     "totalPages": 5,
     "totalItems": 100
   }
 }
 */

func exampleFetchUsers() async throws -> [User] {
    // Dùng ListResponse wrapper
    let response: ListResponse<User> = try await APIService.shared.get(
        endpoint: "/users?page=1"
    )
    
    // Unwrap để lấy array
    let users = try response.unwrap()
    
    // Có thể access pagination info
    if let pagination = response.pagination {
        print("Page \(pagination.currentPage ?? 0) of \(pagination.totalPages ?? 0)")
        print("Total items: \(pagination.totalItems ?? 0)")
    }
    
    return users
}

// MARK: - Example 3: POST Request with Response Data
// Ví dụ 3: POST request có response data

/*
 POST /api/v1/posts
 Body: { "title": "...", "content": "..." }
 Response:
 {
   "success": true,
   "data": {
     "id": "post_123",
     "title": "...",
     "content": "...",
     "createdAt": "..."
   },
   "error": null,
   "pagination": null
 }
 */

struct Post: Codable {
    let id: String
    let title: String
    let content: String
    let createdAt: Date?
}

struct CreatePostRequest: Encodable {
    let title: String
    let content: String
}

func exampleCreatePost(title: String, content: String) async throws -> Post {
    let request = CreatePostRequest(title: title, content: content)
    
    let response: APIResponse<Post> = try await APIService.shared.post(
        endpoint: "/posts",
        body: request
    )
    
    return try response.unwrap()
}

// MARK: - Example 4: DELETE/UPDATE Requests
// Ví dụ 4: DELETE/UPDATE requests

/*
 DELETE /api/v1/posts/123
 Response:
 {
   "success": true,
   "data": null,
   "error": null,
   "pagination": null
 }
 */

func exampleDeletePost(id: String) async throws {
    // Dùng SimpleResponse khi không cần data
    let response: SimpleResponse = try await APIService.shared.delete(
        endpoint: "/posts/\(id)"
    )
    
    if !response.success {
        throw APIError.serverError(
            statusCode: 400,
            message: response.error ?? response.message ?? "Delete failed"
        )
    }
}

// MARK: - Example 5: PUT/PATCH Request
// Ví dụ 5: PUT/PATCH request

/*
 PUT /api/v1/users/profile
 Body: { "name": "New Name", "phoneNumber": "..." }
 Response:
 {
   "success": true,
   "data": {
     "id": "...",
     "email": "...",
     "name": "New Name",
     ...
   },
   "error": null,
   "pagination": null
 }
 */

struct UpdateProfileRequest: Encodable {
    let name: String?
    let phoneNumber: String?
}

func exampleUpdateProfile(name: String?, phoneNumber: String?) async throws -> User {
    let request = UpdateProfileRequest(name: name, phoneNumber: phoneNumber)
    
    let response: APIResponse<User> = try await APIService.shared.put(
        endpoint: "/users/profile",
        body: request
    )
    
    return try response.unwrap()
}

// MARK: - Example 6: Error Handling
// Ví dụ 6: Xử lý lỗi

func exampleWithErrorHandling() async {
    do {
        let response: APIResponse<User> = try await APIService.shared.get(
            endpoint: "/users/me"
        )
        let user = try response.unwrap()
        print("Success: \(user.email)")
        
    } catch let error as APIError {
        switch error {
        case .decodingError(let decodingError):
            print("❌ Decoding error: \(decodingError)")
            // Server response structure doesn't match expected model
            
        case .unauthorized:
            print("❌ Unauthorized - token invalid or expired")
            // Need to login again
            
        case .networkError(let networkError):
            print("❌ Network error: \(networkError)")
            // No internet connection or server unreachable
            
        case .serverError(let statusCode, let message):
            print("❌ Server error \(statusCode): \(message ?? "Unknown")")
            // Server returned error response
            
        case .noData:
            print("❌ No data received")
            
        default:
            print("❌ Unknown error: \(error)")
        }
        
    } catch {
        print("❌ Unexpected error: \(error)")
    }
}

// MARK: - Example 7: Nested Objects
// Ví dụ 7: Objects lồng nhau

/*
 GET /api/v1/posts/123/comments
 Response:
 {
   "success": true,
   "data": [
     {
       "id": "comment_1",
       "content": "Great post!",
       "author": {
         "id": "user_1",
         "name": "John Doe",
         "avatarUrl": "..."
       },
       "createdAt": "..."
     }
   ],
   "error": null,
   "pagination": { ... }
 }
 */

struct Comment: Codable {
    let id: String
    let content: String
    let author: CommentAuthor
    let createdAt: Date?
}

struct CommentAuthor: Codable {
    let id: String
    let name: String
    let avatarUrl: String?
}

func exampleFetchComments(postId: String) async throws -> [Comment] {
    let response: ListResponse<Comment> = try await APIService.shared.get(
        endpoint: "/posts/\(postId)/comments"
    )
    return try response.unwrap()
}

// MARK: - Example 8: Search/Filter with Query Parameters
// Ví dụ 8: Search/Filter với query parameters

/*
 GET /api/v1/posts?search=swift&category=tutorial&page=1&pageSize=20
 */

func exampleSearchPosts(
    search: String?,
    category: String?,
    page: Int = 1,
    pageSize: Int = 20
) async throws -> [Post] {
    var queryItems: [String] = []
    
    if let search = search {
        queryItems.append("search=\(search)")
    }
    if let category = category {
        queryItems.append("category=\(category)")
    }
    queryItems.append("page=\(page)")
    queryItems.append("pageSize=\(pageSize)")
    
    let queryString = queryItems.joined(separator: "&")
    let endpoint = "/posts?\(queryString)"
    
    let response: ListResponse<Post> = try await APIService.shared.get(
        endpoint: endpoint
    )
    
    return try response.unwrap()
}

// MARK: - Example 9: Upload File (if needed)
// Ví dụ 9: Upload file (nếu cần)

/*
 POST /api/v1/users/avatar
 Content-Type: multipart/form-data
 
 Note: Cần implement multipart form data nếu cần upload file
 Hiện tại APIService chỉ hỗ trợ JSON
 */

// MARK: - Example 10: Custom Headers
// Ví dụ 10: Custom headers

func exampleWithCustomHeaders() async throws -> User {
    // Nếu cần thêm headers đặc biệt
    let response: APIResponse<User> = try await APIService.shared.request(
        endpoint: "/users/me",
        method: .get,
        body: nil as String?,
        headers: [
            "X-Custom-Header": "custom-value",
            "X-Request-ID": UUID().uuidString
        ]
    )
    
    return try response.unwrap()
}

// MARK: - Best Practices
// Các best practices

/*
 
 ✅ DO - Nên làm:
 
 1. Luôn dùng APIResponse<T> hoặc ListResponse<T>
 2. Dùng unwrap() helper để code ngắn gọn
 3. Handle errors properly với do-catch
 4. Log errors trong development
 5. Validate request data trước khi gọi API
 6. Cache data khi cần (như User data)
 
 ❌ DON'T - Không nên làm:
 
 1. Không decode trực tiếp thành Model mà không wrapper
 2. Không ignore errors
 3. Không hardcode URLs, dùng Constants
 4. Không lưu sensitive data vào UserDefaults (dùng Keychain)
 5. Không block main thread với synchronous calls
 
 */

// MARK: - Testing Tips
// Tips test API

/*
 
 Test APIs trong development:
 
 1. Dùng APITestView để test từng endpoint
 2. Check Console logs với DebugLogger
 3. Verify JSON response structure
 4. Test error cases (401, 404, 500, etc.)
 5. Test với slow network / offline
 
 Mock data cho UI testing:
 
 #if DEBUG
 func mockFetchUser() async -> User {
     return User.sample
 }
 #endif
 
 */

