import Foundation

struct URLTemplateProcessor {
    static func processTemplate(_ template: String, with parameters: [String: String]) -> String {
        var processedURL = template
        let extractedParams = extractParameters(from: template)

        for param in extractedParams {
            // Create patterns to match both formats: {name} and {name, default=value}
            let patterns = [
                "\\{\(NSRegularExpression.escapedPattern(for: param.name))\\}",
                "\\{\(NSRegularExpression.escapedPattern(for: param.name))\\s*,\\s*default\\s*=\\s*\(NSRegularExpression.escapedPattern(for: param.defaultValue ?? ""))\\}"
            ]

            let value = parameters[param.name] ?? param.defaultValue ?? ""

            for pattern in patterns {
                if let regex = try? NSRegularExpression(pattern: pattern, options: []) {
                    processedURL = regex.stringByReplacingMatches(in: processedURL, options: [], range: NSRange(location: 0, length: processedURL.utf16.count), withTemplate: value)
                }
            }
        }

        return processedURL
    }

    static func extractParameters(from template: String) -> [TemplateParameter] {
        var parameters: [TemplateParameter] = []
        // Updated pattern to handle optional spaces around comma and default=
        let pattern = "\\{([^,}]+)(?:\\s*,\\s*default\\s*=\\s*([^}]+))?\\}"

        guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
            return parameters
        }

        let matches = regex.matches(in: template, options: [], range: NSRange(location: 0, length: template.utf16.count))

        for match in matches {
            let nameRange = match.range(at: 1)
            let defaultRange = match.range(at: 2)

            if let nameSwiftRange = Range(nameRange, in: template) {
                let name = String(template[nameSwiftRange]).trimmingCharacters(in: .whitespaces)
                var defaultValue: String? = nil

                if defaultRange.location != NSNotFound,
                   let defaultSwiftRange = Range(defaultRange, in: template) {
                    defaultValue = String(template[defaultSwiftRange]).trimmingCharacters(in: .whitespaces)
                }

                parameters.append(TemplateParameter(name: name, defaultValue: defaultValue))
            }
        }

        return parameters
    }

    static func validateTemplate(_ template: String) -> Bool {
        let extractedParams = extractParameters(from: template)

        // Check if all placeholders are valid
        let pattern = "\\{[^{}]*\\}"
        guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
            return false
        }

        let matches = regex.matches(in: template, options: [], range: NSRange(location: 0, length: template.utf16.count))

        // Each match should correspond to a valid parameter
        for match in matches {
            if let matchRange = Range(match.range, in: template) {
                let matchString = String(template[matchRange])
                let isValid = extractedParams.contains { param in
                    matchString.contains(param.name)
                }
                if !isValid {
                    return false
                }
            }
        }

        return true
    }

    static func getRequiredParameters(from template: String) -> [String] {
        return extractParameters(from: template)
            .filter { $0.defaultValue == nil }
            .map { $0.name }
    }

    static func hasParameters(_ template: String) -> Bool {
        return template.contains("{") && template.contains("}")
    }
}

struct TemplateParameter {
    let name: String
    let defaultValue: String?

    var isRequired: Bool {
        return defaultValue == nil
    }
}

// MARK: - Template Examples and Helpers
extension URLTemplateProcessor {
    static let commonTemplates: [TemplateExample] = [
        TemplateExample(
            name: "Google Search",
            template: "https://google.com/search?q={query}",
            description: "Search Google with a custom query"
        ),
        TemplateExample(
            name: "GitHub Repository",
            template: "https://github.com/{user}/{repo}",
            description: "Open a GitHub repository"
        ),
        TemplateExample(
            name: "YouTube Video",
            template: "https://youtube.com/watch?v={videoId}",
            description: "Open a YouTube video"
        ),
        TemplateExample(
            name: "Maps Location",
            template: "https://maps.apple.com/?q={location,default=New York}",
            description: "Open a location in Apple Maps"
        ),
        TemplateExample(
            name: "Wikipedia Article",
            template: "https://en.wikipedia.org/wiki/{article}",
            description: "Open a Wikipedia article"
        )
    ]

    static func suggestTemplate(for url: String) -> String? {
        // Simple template suggestion based on common patterns
        if url.contains("google.com/search") {
            return url.replacingOccurrences(of: "q=[^&]*", with: "q={query}", options: .regularExpression)
        } else if url.contains("github.com") && url.components(separatedBy: "/").count >= 5 {
            let components = url.components(separatedBy: "/")
            if components.count >= 5 {
                return "https://github.com/{user}/{repo}"
            }
        } else if url.contains("youtube.com/watch") {
            return url.replacingOccurrences(of: "v=[^&]*", with: "v={videoId}", options: .regularExpression)
        }

        return nil
    }
}

struct TemplateExample {
    let name: String
    let template: String
    let description: String

    var parameters: [TemplateParameter] {
        return URLTemplateProcessor.extractParameters(from: template)
    }
}
