import Foundation
import os

/**
 * Deep Link Router — Swift
 * Handles routing from push notification deep links to app screens
 */

public struct BLDeepLinkRoute {
    public let screen: String
    public let params: [String: String]
    
    public init(screen: String, params: [String: String] = [:]) {
        self.screen = screen
        self.params = params
    }
}

public typealias BLDeepLinkHandler = (BLDeepLinkRoute) -> Void

/**
 * Deep Link Router class
 */
@available(iOS 15.0, *)
public class BLDeepLinkRouter {
    private var handlers: [String: BLDeepLinkHandler] = [:]
    private var fallbackHandler: BLDeepLinkHandler?
    
    public init() {}
    
    /**
     * Register a handler for a specific screen
     */
    public func register(screen: String, handler: @escaping BLDeepLinkHandler) {
        handlers[screen] = handler
    }
    
    /**
     * Set a fallback handler for unregistered screens
     */
    public func setFallback(handler: @escaping BLDeepLinkHandler) {
        fallbackHandler = handler
    }
    
    /**
     * Parse a deep link URL and extract route
     */
    public func parseDeepLink(_ urlString: String) -> BLDeepLinkRoute? {
        guard let url = URL(string: urlString) else {
            return nil
        }
        
        // Handle app-specific URLs: myapp://screen/params
        if url.scheme != "http" && url.scheme != "https" {
            let pathComponents = url.pathComponents.filter { $0 != "/" && !$0.isEmpty }
            let screen = pathComponents.first ?? "home"
            
            var params: [String: String] = [:]
            if let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems {
                for item in queryItems {
                    if let value = item.value {
                        params[item.name] = value
                    }
                }
            }
            
            return BLDeepLinkRoute(screen: screen, params: params)
        }
        
        // Handle web URLs with deep link params
        if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
           let dlParam = components.queryItems?.first(where: { $0.name == "dl" })?.value {
            return parseDeepLink(dlParam)
        }
        
        // Handle path-based routing: /screen/params
        let pathComponents = url.pathComponents.filter { $0 != "/" && !$0.isEmpty }
        if !pathComponents.isEmpty {
            let screen = pathComponents[0]
            
            var params: [String: String] = [:]
            if let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems {
                for item in queryItems {
                    if let value = item.value {
                        params[item.name] = value
                    }
                }
            }
            
            return BLDeepLinkRoute(screen: screen, params: params)
        }
        
        return nil
    }
    
    /**
     * Handle a deep link route
     */
    @discardableResult
    public func handle(_ route: BLDeepLinkRoute) -> Bool {
        if let handler = handlers[route.screen] {
            handler(route)
            return true
        }
        
        if let fallback = fallbackHandler {
            fallback(route)
            return true
        }
        
        Logger.deepLink.warning("No handler for screen: \(route.screen)")
        return false
    }
    
    /**
     * Process a deep link URL end-to-end
     */
    @discardableResult
    public func process(_ urlString: String) -> Bool {
        guard let route = parseDeepLink(urlString) else {
            Logger.deepLink.warning("Failed to parse deep link: \(urlString)")
            return false
        }
        return handle(route)
    }
}

/**
 * Create a broadcast deep link URL
 */
public func createBroadcastDeepLink(
    baseURL: String,
    screen: String,
    params: [String: String] = [:],
    broadcastId: String? = nil
) -> String? {
    guard var components = URLComponents(string: baseURL) else {
        return nil
    }
    
    components.path = "/\(screen)"
    
    var queryItems: [URLQueryItem] = params.map { URLQueryItem(name: $0.key, value: $0.value) }
    
    if let broadcastId = broadcastId {
        queryItems.append(URLQueryItem(name: "broadcastId", value: broadcastId))
    }
    
    if !queryItems.isEmpty {
        components.queryItems = queryItems
    }
    
    return components.string
}

/**
 * Common deep link screens
 */
public struct BLDeepLinkScreens {
    // Broadcasts
    public static let broadcast = "broadcast"
    public static let announcements = "announcements"
    
    // Surveys
    public static let survey = "survey"
    public static let surveyList = "surveys"
    
    // Product-specific
    public static let settings = "settings"
    public static let profile = "profile"
    public static let upgrade = "upgrade"
    public static let support = "support"
    
    // Fallback
    public static let home = "home"
}

// Logger extension
@available(iOS 15.0, *)
extension Logger {
    static let deepLink = Logger(subsystem: "com.bytelyst.platform", category: "DeepLink")
}
