//
//  APIDebugView.swift
//  AppClientBaseSwift
//
//  Comprehensive API debugging view
//  View debug API toàn diện
//

import SwiftUI

// MARK: - API Debug View
// View Debug API

struct APIDebugView: View {
    @State private var endpoint: String = "/users/me"
    @State private var method: HTTPMethod = .get
    @State private var requestBody: String = ""
    @State private var customHeaders: String = ""
    @State private var useAccessToken: Bool = true
    
    @State private var responseStatus: String = "Chưa gửi request"
    @State private var responseJSON: String = ""
    @State private var decodingResult: String = ""
    @State private var isLoading: Bool = false
    
    var body: some View {
        NavigationView {
            Form {
                // Endpoint Section
                Section(header: Text("Request Configuration")) {
                    TextField("Endpoint (vd: /users/me)", text: $endpoint)
                        .autocapitalization(.none)
                    
                    Picker("Method", selection: $method) {
                        Text("GET").tag(HTTPMethod.get)
                        Text("POST").tag(HTTPMethod.post)
                        Text("PUT").tag(HTTPMethod.put)
                        Text("DELETE").tag(HTTPMethod.delete)
                    }
                    
                    Toggle("Use Access Token", isOn: $useAccessToken)
                }
                
                // Request Body Section
                if method == .post || method == .put {
                    Section(header: Text("Request Body (JSON)")) {
                        TextEditor(text: $requestBody)
                            .frame(height: 150)
                            .font(.system(.body, design: .monospaced))
                        
                        Button("Load Sample Body") {
                            requestBody = sampleRequestBody
                        }
                        .font(.caption)
                    }
                }
                
                // Custom Headers Section
                Section(header: Text("Custom Headers (optional)")) {
                    TextEditor(text: $customHeaders)
                        .frame(height: 100)
                        .font(.system(.caption, design: .monospaced))
                    
                    Text("Format: Key: Value (mỗi header trên một dòng)")
                        .font(.caption2)
                        .foregroundColor(.secondary)
                }
                
                // Action Button
                Section {
                    Button(action: {
                        Task {
                            await sendRequest()
                        }
                    }) {
                        HStack {
                            if isLoading {
                                ProgressView()
                            }
                            Text(isLoading ? "Đang gửi..." : "Gửi Request")
                                .frame(maxWidth: .infinity)
                        }
                    }
                    .disabled(isLoading || endpoint.isEmpty)
                    
                    Button("Clear Results") {
                        clearResults()
                    }
                    .foregroundColor(.red)
                }
                
                // Response Status Section
                Section(header: Text("Response Status")) {
                    Text(responseStatus)
                        .font(.system(.body, design: .monospaced))
                        .foregroundColor(responseStatusColor)
                }
                
                // Raw JSON Section
                if !responseJSON.isEmpty {
                    Section(header: HStack {
                        Text("Raw JSON Response")
                        Spacer()
                        Button("Copy") {
                            UIPasteboard.general.string = responseJSON
                        }
                        .font(.caption)
                    }) {
                        ScrollView {
                            Text(responseJSON)
                                .font(.system(.caption, design: .monospaced))
                                .frame(maxWidth: .infinity, alignment: .leading)
                                .padding(8)
                        }
                        .frame(height: 200)
                    }
                }
                
                // Decoding Result Section
                if !decodingResult.isEmpty {
                    Section(header: Text("Decoding Analysis")) {
                        ScrollView {
                            Text(decodingResult)
                                .font(.system(.caption, design: .monospaced))
                                .frame(maxWidth: .infinity, alignment: .leading)
                                .padding(8)
                        }
                        .frame(height: 200)
                    }
                }
                
                // Quick Actions
                Section(header: Text("Quick Actions")) {
                    Button("Test /users/me") {
                        endpoint = "/users/me"
                        method = .get
                        useAccessToken = true
                    }
                    
                    Button("Test /auth/register") {
                        endpoint = "/auth/register"
                        method = .post
                        useAccessToken = false
                        requestBody = """
                        {
                            "firstName": "Test",
                            "lastName": "User",
                            "email": "test@example.com",
                            "password": "Test123!"
                        }
                        """
                    }
                }
                
                // Debugging Tips
                Section(header: Text("Debugging Tips")) {
                    VStack(alignment: .leading, spacing: 8) {
                        tipText("1. Kiểm tra Raw JSON để xem server trả về gì")
                        tipText("2. Xem Decoding Analysis để biết field nào bị sai")
                        tipText("3. So sánh tên field trong JSON với model")
                        tipText("4. Kiểm tra có wrapper {success, data} không")
                        tipText("5. Verify snake_case/camelCase conversion")
                    }
                    .font(.caption)
                }
            }
            .navigationTitle("API Debugger")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
    
    // MARK: - Helpers
    
    private var responseStatusColor: Color {
        if responseStatus.contains("✅") || responseStatus.contains("200") {
            return .green
        } else if responseStatus.contains("❌") || responseStatus.contains("Error") {
            return .red
        } else {
            return .primary
        }
    }
    
    private func tipText(_ text: String) -> some View {
        HStack(alignment: .top, spacing: 4) {
            Text("💡")
            Text(text)
        }
    }
    
    private var sampleRequestBody: String {
        """
        {
            "name": "Sample Value",
            "email": "test@example.com"
        }
        """
    }
    
    private func clearResults() {
        responseStatus = "Đã xóa kết quả"
        responseJSON = ""
        decodingResult = ""
    }
    
    // MARK: - Network Request
    
    private func sendRequest() async {
        isLoading = true
        responseStatus = "🔄 Đang gửi request..."
        responseJSON = ""
        decodingResult = ""
        
        do {
            // Build URL
            guard let url = URL(string: APIConfig.baseURL + APIConfig.apiVersion + endpoint) else {
                responseStatus = "❌ Invalid URL"
                isLoading = false
                return
            }
            
            // Create request
            var request = URLRequest(url: url)
            request.httpMethod = method.rawValue
            request.timeoutInterval = APIConfig.timeout
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")
            request.setValue("application/json", forHTTPHeaderField: "Accept")
            
            // Add access token if needed
            if useAccessToken, let token = AuthManager.shared.accessToken {
                request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
            }
            
            // Parse and add custom headers
            let headerLines = customHeaders.components(separatedBy: "\n")
            for line in headerLines {
                let parts = line.components(separatedBy: ":")
                if parts.count == 2 {
                    let key = parts[0].trimmingCharacters(in: .whitespaces)
                    let value = parts[1].trimmingCharacters(in: .whitespaces)
                    request.setValue(value, forHTTPHeaderField: key)
                }
            }
            
            // Add request body
            if !requestBody.isEmpty, let bodyData = requestBody.data(using: .utf8) {
                request.httpBody = bodyData
            }
            
            // Send request
            let (data, response) = try await URLSession.shared.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                responseStatus = "❌ Invalid response"
                isLoading = false
                return
            }
            
            // Store raw JSON
            if let jsonString = String(data: data, encoding: .utf8) {
                responseJSON = jsonString.prettyPrintedJSON ?? jsonString
            }
            
            // Update status
            let statusEmoji = httpResponse.statusCode >= 200 && httpResponse.statusCode < 300 ? "✅" : "❌"
            responseStatus = """
            \(statusEmoji) Status Code: \(httpResponse.statusCode)
            URL: \(url.absoluteString)
            Method: \(method.rawValue)
            """
            
            // Analyze decoding
            if httpResponse.statusCode >= 200 && httpResponse.statusCode < 300 {
                analyzeResponse(data)
            }
            
        } catch {
            responseStatus = "❌ Error: \(error.localizedDescription)"
        }
        
        isLoading = false
    }
    
    private func analyzeResponse(_ data: Data) {
        var analysis = "🔍 Response Analysis:\n\n"
        
        // Try to parse as JSON
        guard let jsonObject = try? JSONSerialization.jsonObject(with: data) else {
            analysis += "❌ Cannot parse as JSON"
            decodingResult = analysis
            return
        }
        
        // Check if it's a dictionary
        if let dict = jsonObject as? [String: Any] {
            analysis += "✅ Response is a Dictionary\n"
            analysis += "📊 Keys: \(dict.keys.count)\n\n"
            
            // List all keys with types
            analysis += "🔑 Available Fields:\n"
            for (key, value) in dict.sorted(by: { $0.key < $1.key }) {
                let valueType = type(of: value)
                let preview = previewValue(value)
                analysis += "  • \(key): \(valueType)\(preview)\n"
            }
            
            // Check for wrapper format
            let hasSuccess = dict["success"] != nil
            let hasData = dict["data"] != nil
            let hasError = dict["error"] != nil
            
            analysis += "\n📦 Wrapper Detection:\n"
            analysis += "  • Has 'success': \(hasSuccess ? "✅" : "❌")\n"
            analysis += "  • Has 'data': \(hasData ? "✅" : "❌")\n"
            analysis += "  • Has 'error': \(hasError ? "✅" : "❌")\n"
            
            if hasData, let dataValue = dict["data"] {
                analysis += "\n📊 Data Content:\n"
                if let dataDict = dataValue as? [String: Any] {
                    analysis += "  Type: Dictionary\n"
                    analysis += "  Keys: \(dataDict.keys.joined(separator: ", "))\n"
                } else if let dataArray = dataValue as? [Any] {
                    analysis += "  Type: Array\n"
                    analysis += "  Count: \(dataArray.count)\n"
                } else {
                    analysis += "  Type: \(type(of: dataValue))\n"
                }
            }
            
            // Suggestions for User model
            if endpoint.contains("/users") {
                analysis += "\n💡 User Model Mapping:\n"
                let userFields = ["id", "email", "name", "firstName", "lastName", 
                                 "avatarUrl", "phoneNumber", "isEmailVerified", 
                                 "emailConfirmed", "createdAt", "updatedAt", "roles"]
                
                for field in userFields {
                    if dict[field] != nil {
                        analysis += "  ✅ \(field)\n"
                    } else {
                        // Try snake_case version
                        let snakeCase = field.toSnakeCase()
                        if dict[snakeCase] != nil {
                            analysis += "  ⚠️ \(field) → found as '\(snakeCase)'\n"
                        } else {
                            analysis += "  ❌ \(field) → not found\n"
                        }
                    }
                }
            }
            
        } else if let array = jsonObject as? [[String: Any]] {
            analysis += "✅ Response is an Array\n"
            analysis += "📊 Count: \(array.count)\n"
            if let firstItem = array.first {
                analysis += "🔑 First Item Keys:\n"
                for key in firstItem.keys.sorted() {
                    analysis += "  • \(key)\n"
                }
            }
        } else {
            analysis += "⚠️ Unknown response format\n"
        }
        
        decodingResult = analysis
    }
    
    private func previewValue(_ value: Any) -> String {
        switch value {
        case let string as String:
            let preview = string.prefix(30)
            return preview.count < string.count ? " = \"\(preview)...\"" : " = \"\(preview)\""
        case let number as NSNumber:
            return " = \(number)"
        case let bool as Bool:
            return " = \(bool)"
        case is NSNull:
            return " = null"
        default:
            return ""
        }
    }
}

// MARK: - Preview

#Preview {
    APIDebugView()
}
