import SwiftUI
import HyperKYC

// HyperKYC Status Constants
struct HyperKycConstants {
    static let autoApproved = "auto_approved"
    static let autoDeclined = "auto_declined"
    static let needsReview = "needs_review"
    static let userCancelled = "user_cancelled"
}

struct ContentView: View {
    @State private var resultText = "Ready to start HyperKYC verification"
    @State private var isLoading = false
    @State private var resultStatus: String?
    
    var body: some View {
        NavigationView {
            ScrollView {
                VStack(spacing: 20) {
                    
                    // Header Section
                    VStack(spacing: 16) {
                        Text("HyperKYC Sample App")
                            .font(.largeTitle)
                            .fontWeight(.bold)
                            .multilineTextAlignment(.center)
                            .padding(.top, 20)
                    }
                    
                    Spacer()
                    
                    // Action Section
                    VStack(spacing: 16) {
                        if isLoading {
                            VStack(spacing: 12) {
                                ProgressView()
                                    .scaleEffect(1.2)
                                Text("Processing verification...")
                                    .font(.body)
                                    .foregroundColor(.secondary)
                            }
                        } else {
                            Button(action: {
                                launchHyperKyc()
                            }) {
                                Text("Launch HyperKYC Verification")
                                    .font(.headline)
                                    .foregroundColor(.white)
                                    .frame(maxWidth: .infinity)
                                    .padding()
                                    .background(Color.blue)
                                    .cornerRadius(12)
                            }
                        }
                    }
                    
                    Spacer()
                    
                    // Status Indicator
                    if let status = resultStatus {
                        StatusCard(status: status)
                    }
                    
                    // Result Section
                    VStack(alignment: .leading, spacing: 8) {
                        Text("Verification Details")
                            .font(.headline)
                            .fontWeight(.semibold)
                        
                        ScrollView {
                            Text(resultText)
                                .font(.caption)
                                .foregroundColor(.primary)
                                .frame(maxWidth: .infinity, alignment: .leading)
                                .padding()
                                .background(Color(.systemGray6))
                                .cornerRadius(8)
                        }
                        .frame(minHeight: 120)
                    }
                    
                }
                .padding(.horizontal, 16)
            }
            .navigationBarHidden(true)
        }
    }

    
    private func handleHyperKycResult(_ result: HyperKycResult) {
        isLoading = false
        resultStatus = result.status
        
        print("HyperKYC result callback called with: \(result)")
        
        // Create formatted JSON for detailed logging
        let completeResult = processHyperKycResult(hyperKycResult: result)
        let jsonData = try? JSONSerialization.data(withJSONObject: completeResult, options: .prettyPrinted)
        let dataJson = jsonData != nil ? String(data: jsonData!, encoding: .utf8) ?? "" : ""
        
        print("Full result JSON: \(dataJson)")
        
        // Process result based on status
        resultText = buildResultText(for: result, with: dataJson)
    }
    
    private func buildResultText(for result: HyperKycResult, with dataJson: String) -> String {
        switch result.status {
        case HyperKycConstants.userCancelled:
            print("User cancelled the workflow")
            return buildCancelledResult(result: result, dataJson: dataJson)
            
        case HyperKycConstants.autoApproved:
            print("KYC Auto-approved successfully")
            return buildApprovedResult(result: result, dataJson: dataJson)
            
        case HyperKycConstants.autoDeclined:
            print("KYC Auto-declined")
            return buildDeclinedResult(result: result, dataJson: dataJson)
            
        case HyperKycConstants.needsReview:
            print("KYC requires manual review")
            return buildReviewResult(result: result, dataJson: dataJson)
            
        default:
            print("Unknown status received: \(result.status)")
            return buildUnknownResult(result: result, dataJson: dataJson)
        }
    }
    
    private func buildCancelledResult(result: HyperKycResult, dataJson: String) -> String {
        var text = "🚫 **Workflow Cancelled by User**\n\n"
        text += "**Status:** \(result.status)\n"
        text += "**Transaction ID:** \(result.transactionId)\n"
        
        if !result.details.isEmpty {
            text += "**Details:**\n"
            for (key, value) in result.details {
                text += "  • \(key): \(value)\n"
            }
        }
        
        if let errorCode = result.errorCode {
            text += "**Error Code:** \(errorCode)\n"
        }
        
        if let errorMessage = result.errorMessage {
            text += "**Error Message:** \(errorMessage)\n"
        }
        
        if let latestModule = result.latestModule {
            text += "**Latest Module:** \(latestModule)\n"
        }
        
        text += "\n**Full Response:**\n\(dataJson)"
        return text
    }
    
    private func buildApprovedResult(result: HyperKycResult, dataJson: String) -> String {
        var text = "✅ **KYC Auto-Approved**\n\n"
        text += "**Status:** \(result.status)\n"
        text += "**Transaction ID:** \(result.transactionId)\n"
        
        if !result.details.isEmpty {
            text += "**Details:**\n"
            for (key, value) in result.details {
                text += "  • \(key): \(value)\n"
            }
        }
        
        if let latestModule = result.latestModule {
            text += "**Latest Module:** \(latestModule)\n"
        }
        
        text += "\n🎉 **Verification completed successfully!**\n"
        text += "The user has been automatically approved based on the submitted documents and information.\n\n"
        text += "**Full Response:**\n\(dataJson)"
        return text
    }
    
    private func buildDeclinedResult(result: HyperKycResult, dataJson: String) -> String {
        var text = "❌ **KYC Auto-Declined**\n\n"
        text += "**Status:** \(result.status)\n"
        text += "**Transaction ID:** \(result.transactionId)\n"
        
        if !result.details.isEmpty {
            text += "**Details:**\n"
            for (key, value) in result.details {
                text += "  • \(key): \(value)\n"
            }
        }
        
        if let errorCode = result.errorCode {
            text += "**Error Code:** \(errorCode)\n"
        }
        
        if let errorMessage = result.errorMessage {
            text += "**Error Message:** \(errorMessage)\n"
        }
        
        if let latestModule = result.latestModule {
            text += "**Latest Module:** \(latestModule)\n"
        }
        
        text += "\n⚠️ **Verification declined automatically.**\n"
        text += "The submitted information did not meet the verification criteria. Please review your documents and try again.\n\n"
        text += "**Full Response:**\n\(dataJson)"
        return text
    }
    
    private func buildReviewResult(result: HyperKycResult, dataJson: String) -> String {
        var text = "🔍 **KYC Needs Manual Review**\n\n"
        text += "**Status:** \(result.status)\n"
        text += "**Transaction ID:** \(result.transactionId)\n"
        
        if !result.details.isEmpty {
            text += "**Details:**\n"
            for (key, value) in result.details {
                text += "  • \(key): \(value)\n"
            }
        }
        
        if let latestModule = result.latestModule {
            text += "**Latest Module:** \(latestModule)\n"
        }
        
        text += "\n⏳ **Manual review required.**\n"
        text += "Your verification will be reviewed by our team. You will be notified once the review is complete.\n"
        text += "Please keep your transaction ID for reference.\n\n"
        text += "**Full Response:**\n\(dataJson)"
        return text
    }
    
    private func buildUnknownResult(result: HyperKycResult, dataJson: String) -> String {
        var text = "❓ **Unknown Status: \(result.status)**\n\n"
        text += "**Transaction ID:** \(result.transactionId)\n"
        
        if !result.details.isEmpty {
            text += "**Details:**\n"
            for (key, value) in result.details {
                text += "  • \(key): \(value)\n"
            }
        }
        
        if let errorCode = result.errorCode {
            text += "**Error Code:** \(errorCode)\n"
        }
        
        if let errorMessage = result.errorMessage {
            text += "**Error Message:** \(errorMessage)\n"
        }
        
        if let latestModule = result.latestModule {
            text += "**Latest Module:** \(latestModule)\n"
        }
        
        text += "\n**Full Response:**\n\(dataJson)"
        return text
    }
    
    private func processHyperKycResult(hyperKycResult: HyperKycResult) -> [String: Any] {
        var hyperKycResultDictionary: [String: Any] = [
            "status": hyperKycResult.status,
            "transactionId": hyperKycResult.transactionId,
            "details": hyperKycResult.details
        ]
        
        if let errorCode = hyperKycResult.errorCode {
            hyperKycResultDictionary["errorCode"] = errorCode
        }
        
        if let errorMessage = hyperKycResult.errorMessage {
            hyperKycResultDictionary["errorMessage"] = errorMessage
        }
        
        if let latestModule = hyperKycResult.latestModule {
            hyperKycResultDictionary["latestModule"] = latestModule
        }
        
        return hyperKycResultDictionary
    }
    
    private func randomString(length: Int) -> String {
        let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        return String((0..<length).map { _ in letters.randomElement()! })
    }
}

// Status Card Component
struct StatusCard: View {
    let status: String
    
    var body: some View {
        HStack(spacing: 12) {
            Text(statusEmoji)
                .font(.title2)
            
            VStack(alignment: .leading, spacing: 4) {
                Text(statusTitle)
                    .font(.headline)
                    .fontWeight(.semibold)
                
                Text(statusDescription)
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
            
            Spacer()
        }
        .padding(16)
        .background(statusColor)
        .cornerRadius(12)
    }
    
    private var statusEmoji: String {
        switch status {
        case HyperKycConstants.autoApproved: return "✅"
        case HyperKycConstants.autoDeclined: return "❌"
        case HyperKycConstants.needsReview: return "🔍"
        case HyperKycConstants.userCancelled: return "🚫"
        default: return "❓"
        }
    }
    
    private var statusTitle: String {
        switch status {
        case HyperKycConstants.autoApproved: return "Auto-Approved"
        case HyperKycConstants.autoDeclined: return "Auto-Declined"
        case HyperKycConstants.needsReview: return "Needs Review"
        case HyperKycConstants.userCancelled: return "User Cancelled"
        default: return "Unknown Status"
        }
    }
    
    private var statusDescription: String {
        switch status {
        case HyperKycConstants.autoApproved: return "Verification completed successfully"
        case HyperKycConstants.autoDeclined: return "Verification declined automatically"
        case HyperKycConstants.needsReview: return "Manual review required"
        case HyperKycConstants.userCancelled: return "Process cancelled by user"
        default: return "Unexpected status: \(status)"
        }
    }
    
    private var statusColor: Color {
        switch status {
        case HyperKycConstants.autoApproved: return Color.green.opacity(0.2)
        case HyperKycConstants.autoDeclined: return Color.red.opacity(0.2)
        case HyperKycConstants.needsReview: return Color.orange.opacity(0.2)
        case HyperKycConstants.userCancelled: return Color.gray.opacity(0.2)
        default: return Color.gray.opacity(0.2)
        }
    }
}

// Extension to get top view controller for HyperKYC launch
extension ContentView {
    private func getTopViewController() -> UIViewController? {
        guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
              let window = windowScene.windows.first else {
            return nil
        }
        
        var topController = window.rootViewController
        while let presentedViewController = topController?.presentedViewController {
            topController = presentedViewController
        }
        return topController
    }
}

// App Entry Point - iOS 13 Compatible
@main
struct HyperKycSampleApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

// Helper extension for the main ContentView
private extension ContentView {
    func launchHyperKyc() {
        isLoading = true
        resultText = "Starting HyperKYC verification..."
        
        do {
            // Generate unique identifiers
            let uniqueId = HyperKyc.createUniqueId()
            let transactionId = "txn_\(Int(Date().timeIntervalSince1970))_\(uniqueId)"
            
            print("Creating HyperKYC config with transaction ID: \(transactionId)")
            
            // Create HyperKYC configuration with same settings as Android
            let hyperKycConfig = HyperKycConfig(
                appId: "", // TODO: Add your actual app ID
                appKey: "", // TODO: Add your actual app key
                workflowId: "", // TODO: Add your actual workflow ID
                transactionId: transactionId
            )
            
            // Configure HyperKYC settings (same as Android version)
            hyperKycConfig.setInputs(inputs: ["name": "sample name"])
            //hyperKycConfig.setUseLocation(shouldUse: true) // Ask for location consent
            hyperKycConfig.setDefaultLangCode(language: "en") // Set default language
            hyperKycConfig.setUniqueId(uuid: "12345-abc") // Unique ID for CPR
            
            print("HyperKYC config created successfully")
            
            
            // Launch HyperKYC
            print("Launching HyperKYC with config")
            
            guard let topViewController = getTopViewController() else {
                isLoading = false
                resultText = "❌ Error: Could not find top view controller"
                return
            }
            
            HyperKyc.launch(topViewController, hyperKycConfig: hyperKycConfig) { [self] hyperKycResult in
                DispatchQueue.main.async {
                    self.handleHyperKycResult(hyperKycResult)
                }
            }
            
        } catch {
            isLoading = false
            resultText = "❌ Failed to launch HyperKYC: \(error.localizedDescription)"
            print("Failed to launch HyperKYC: \(error)")
        }
    }
}
