/**
 * PayUs Integrator Demo — iOS (Swift)
 *
 * Single-file demo showing the full third-party integration flow using URLSession.
 * No external dependencies.
 *
 * Run:  swift IntegratorDemo.swift
 *
 * ⚠️  Replace APP_ID, APP_SECRET, and BRANCH_ID with your real values.
 */

import Foundation

let BASE = "https://payus.co.nz"
let SYSTEM = "pos"
let APP_ID = "YOUR_APP_ID"
let APP_SECRET = "YOUR_APP_SECRET"
let BRANCH_ID = 123

// ── Helpers ──────────────────────────────────────────────────────────────────

func request(_ method: String, _ path: String, body: Data? = nil,
             headers: [String: String] = [:]) async throws -> (Data, Int) {
    var req = URLRequest(url: URL(string: path)!)
    req.httpMethod = method
    req.setValue("application/json", forHTTPHeaderField: "Accept")
    for (k, v) in headers { req.setValue(v, forHTTPHeaderField: k) }
    if let body {
        req.httpBody = body
        req.setValue("application/json", forHTTPHeaderField: "Content-Type")
    }
    let (data, response) = try await URLSession.shared.data(for: req)
    let status = (response as? HTTPURLResponse)?.statusCode ?? 0
    return (data, status)
}

func jsonString(_ data: Data) -> String {
    String(data: data, encoding: .utf8) ?? "<binary>"
}

// ── Main ─────────────────────────────────────────────────────────────────────

func main() async {
    print("═══════════════════════════════════════════════════")
    print("  PayUs Integrator Demo — iOS (Swift)")
    print("═══════════════════════════════════════════════════")

    do {
        // Step 1: Authenticate
        print("\n🔐 Step 1: Authenticating...")
        let creds = Data("\(APP_ID):\(APP_SECRET)".utf8).base64EncodedString()
        let (authData, authStatus) = try await request(
            "POST", "\(BASE)/api/v1/oauth/token",
            headers: ["Authorization": "Basic \(creds)"]
        )
        guard authStatus == 200 else {
            print("   ❌ Auth failed: \(authStatus) \(jsonString(authData))")
            return
        }
        let authJson = try JSONSerialization.jsonObject(with: authData) as? [String: Any]
        let dataObj = authJson?["data"] as? [String: Any]
        let token = (dataObj?["token"] as? String) ?? (authJson?["token"] as? String) ?? ""
        print("   ✅ Token acquired")

        let bearer = ["Authorization": "Bearer \(token)"]

        // Step 2: List terminals
        print("\n📱 Step 2: Listing terminals...")
        let (termData, termStatus) = try await request(
            "GET", "\(BASE)/api/v1/\(SYSTEM)/listTerminals?branchId=\(BRANCH_ID)",
            headers: bearer
        )
        if termStatus == 200 {
            print("   ✅ Response: \(jsonString(termData).prefix(200))...")
        } else {
            print("   ⚠️  Failed: \(termStatus) \(jsonString(termData))")
        }

        // Step 3: Send PRINT trigger
        print("\n🖨️  Step 3: Sending PRINT trigger...")
        let triggerBody = """
        {"terminalId":"TERM001","accessId":"ACCESS001","requestType":"PRINT",
         "body":"Hello from Swift integrator!","branchId":\(BRANCH_ID),"configId":1}
        """.data(using: .utf8)
        let (trigData, trigStatus) = try await request(
            "POST", "\(BASE)/api/v1/\(SYSTEM)/requestTerminal",
            body: triggerBody, headers: bearer
        )
        if trigStatus == 200 {
            print("   ✅ Trigger sent")
        } else {
            print("   ⚠️  Trigger failed: \(trigStatus) \(jsonString(trigData))")
        }

        // Step 4: Process payment
        print("\n💳 Step 4: Processing test payment...")
        let payBody = """
        {"grandTotal":"0.01","referenceId":"swift_demo_\(Int(Date().timeIntervalSince1970))",
         "branchId":\(BRANCH_ID),"configId":1,"terminalId":"TERM001","accessId":"ACCESS001",
         "channel":"WECHAT","qrMode":true}
        """.data(using: .utf8)
        let (payData, payStatus) = try await request(
            "POST", "\(BASE)/api/v1/\(SYSTEM)/payNow",
            body: payBody, headers: bearer
        )
        if payStatus == 200 {
            print("   ✅ Payment: \(jsonString(payData).prefix(200))")
        } else {
            print("   ⚠️  Payment failed: \(payStatus) (expected without payments:direct scope)")
        }

        // Step 5: Query transactions
        print("\n📊 Step 5: Querying transactions...")
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        let today = formatter.string(from: Date())
        let queryBody = """
        {"branchId":\(BRANCH_ID),"startDate":"\(today)","endDate":"\(today)"}
        """.data(using: .utf8)
        let (qData, qStatus) = try await request(
            "POST", "\(BASE)/api/v1/\(SYSTEM)/getRecentTransactions",
            body: queryBody, headers: bearer
        )
        if qStatus == 200 {
            print("   ✅ Transactions: \(jsonString(qData).prefix(200))...")
        } else {
            print("   ⚠️  Query failed: \(qStatus)")
        }

        print("\n✅ Demo complete!")
    } catch {
        print("\n❌ Error: \(error)")
    }
}

await main()
