import SwiftUI

/// Category for grouping contact field types in the picker
enum ContactFieldCategory: String, CaseIterable, Sendable {
    case contact
    case social
    case developer
    case messaging
    case payment
    case creator
    case scheduling
    case other
    
    var displayName: String {
        switch self {
        case .contact: return String(localized: "Contact")
        case .social: return String(localized: "Social Media")
        case .developer: return String(localized: "Developer")
        case .messaging: return String(localized: "Messaging")
        case .payment: return String(localized: "Payment")
        case .creator: return String(localized: "Support & Funding")
        case .scheduling: return String(localized: "Scheduling")
        case .other: return String(localized: "Other")
        }
    }
}

/// Defines a contact field type with all its configuration
struct ContactFieldType: Identifiable, Hashable, Sendable {
    let id: String
    let displayName: String
    let systemImage: String
    let isCustomSymbol: Bool  // true = asset catalog symbol, false = SF Symbol
    let iconColor: Color
    let category: ContactFieldCategory
    let valueLabel: String
    let valuePlaceholder: String
    let titleSuggestions: [String]
    let keyboardType: UIKeyboardType
    let autocapitalization: TextInputAutocapitalization
    let urlBuilder: @Sendable (String) -> URL?
    let displayValueFormatter: @Sendable (String) -> String
    
    init(
        id: String,
        displayName: String,
        systemImage: String,
        isCustomSymbol: Bool = false,
        iconColor: Color,
        category: ContactFieldCategory,
        valueLabel: String,
        valuePlaceholder: String,
        titleSuggestions: [String],
        keyboardType: UIKeyboardType,
        autocapitalization: TextInputAutocapitalization = .never,
        urlBuilder: @escaping @Sendable (String) -> URL?,
        displayValueFormatter: @escaping @Sendable (String) -> String = { $0 }
    ) {
        self.id = id
        self.displayName = displayName
        self.systemImage = systemImage
        self.isCustomSymbol = isCustomSymbol
        self.iconColor = iconColor
        self.category = category
        self.valueLabel = valueLabel
        self.valuePlaceholder = valuePlaceholder
        self.titleSuggestions = titleSuggestions
        self.keyboardType = keyboardType
        self.autocapitalization = autocapitalization
        self.urlBuilder = urlBuilder
        self.displayValueFormatter = displayValueFormatter
    }
    
    /// Returns an Image view for this field type's icon
    @MainActor
    func iconImage() -> Image {
        if isCustomSymbol {
            return Image(systemImage)
        } else {
            return Image(systemName: systemImage)
        }
    }
    
    // MARK: - Hashable & Equatable
    
    static func == (lhs: ContactFieldType, rhs: ContactFieldType) -> Bool {
        lhs.id == rhs.id
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    // MARK: - URL Building
    
    func buildURL(value: String) -> URL? {
        urlBuilder(value)
    }
    
    // MARK: - Display Value Formatting
    
    /// Returns a formatted display value for the given raw value
    func formattedDisplayValue(_ value: String) -> String {
        displayValueFormatter(value)
    }
}

// MARK: - All Field Types

extension ContactFieldType {
    
    /// All available field types
    static let allCases: [ContactFieldType] = [
        // Contact
        .phone, .email, .website, .address,
        // Social
        .linkedIn, .twitter, .instagram, .facebook, .tiktok, .threads,
        .youtube, .snapchat, .pinterest, .twitch, .bluesky, .mastodon, .reddit,
        // Developer
        .github, .gitlab, .stackoverflow,
        // Messaging
        .telegram, .whatsapp, .signal, .discord, .slack, .matrix,
        // Payment
        .venmo, .cashApp, .paypal, .zelle,
        // Creator
        .patreon, .kofi,
        // Scheduling
        .calendly,
        // Other
        .customLink
    ]
    
    /// Field types grouped by category
    static var byCategory: [ContactFieldCategory: [ContactFieldType]] {
        Dictionary(grouping: allCases, by: { $0.category })
    }
    
    
    // MARK: - Contact
    
    static let phone = ContactFieldType(
        id: "phone",
        displayName: String(localized: "Phone Number"),
        systemImage: "phone.fill",
        iconColor: Color(red: 0.2, green: 0.2, blue: 0.2),
        category: .contact,
        valueLabel: String(localized: "Phone Number"),
        valuePlaceholder: "+1 (555) 123-4567",
        titleSuggestions: [String(localized: "Cell"), String(localized: "Work"), String(localized: "Home")],
        keyboardType: .phonePad,
        urlBuilder: { value in
            let digits = value.filter { $0.isNumber || $0 == "+" }
            return URL(string: "tel:\(digits)")
        }
    )
    
    static let email = ContactFieldType(
        id: "email",
        displayName: String(localized: "Email"),
        systemImage: "envelope.fill",
        iconColor: Color(red: 0.2, green: 0.2, blue: 0.2),
        category: .contact,
        valueLabel: String(localized: "Email"),
        valuePlaceholder: "you@example.com",
        titleSuggestions: [String(localized: "Work"), String(localized: "Personal")],
        keyboardType: .emailAddress,
        urlBuilder: { URL(string: "mailto:\($0)") }
    )
    
    static let website = ContactFieldType(
        id: "website",
        displayName: String(localized: "Company Website"),
        systemImage: "globe",
        iconColor: Color(red: 0.2, green: 0.2, blue: 0.2),
        category: .contact,
        valueLabel: String(localized: "Website URL"),
        valuePlaceholder: "https://company.com",
        titleSuggestions: [String(localized: "Company Website"), String(localized: "Portfolio")],
        keyboardType: .URL,
        urlBuilder: { buildWebURL($0) }
    )
    
    static let address = ContactFieldType(
        id: "address",
        displayName: String(localized: "Address"),
        systemImage: "location.fill",
        iconColor: Color(red: 0.2, green: 0.2, blue: 0.2),
        category: .contact,
        valueLabel: String(localized: "Address"),
        valuePlaceholder: "123 Main St, City, State",
        titleSuggestions: [String(localized: "Work"), String(localized: "Home")],
        keyboardType: .default,
        urlBuilder: { value in
            // Try to parse as PostalAddress JSON first for proper formatting
            let searchQuery: String
            if let address = PostalAddress.decode(from: value) {
                searchQuery = address.singleLineString
            } else {
                searchQuery = value
            }
            let encoded = searchQuery.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? searchQuery
            return URL(string: "maps://?q=\(encoded)")
        },
        displayValueFormatter: formatAddressForDisplay
    )
    
    // MARK: - Social Media
    
    static let linkedIn = ContactFieldType(
        id: "linkedIn",
        displayName: "LinkedIn",
        systemImage: "linkedin",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "linkedin.com/in/username",
        titleSuggestions: ["Connect with me on LinkedIn"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "linkedin.com") }
    )
    
    static let twitter = ContactFieldType(
        id: "twitter",
        displayName: "X",
        systemImage: "x-twitter",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "x.com/username",
        titleSuggestions: ["Follow me on X"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "x.com") }
    )
    
    static let instagram = ContactFieldType(
        id: "instagram",
        displayName: "Instagram",
        systemImage: "instagram",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "instagram.com/username",
        titleSuggestions: ["Follow me on Instagram"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "instagram.com") }
    )
    
    static let facebook = ContactFieldType(
        id: "facebook",
        displayName: "Facebook",
        systemImage: "facebook",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "facebook.com/username",
        titleSuggestions: ["Connect on Facebook"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "facebook.com") }
    )
    
    static let tiktok = ContactFieldType(
        id: "tiktok",
        displayName: "TikTok",
        systemImage: "tiktok",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "tiktok.com/@username",
        titleSuggestions: ["Follow me on TikTok"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "tiktok.com") }
    )
    
    static let threads = ContactFieldType(
        id: "threads",
        displayName: "Threads",
        systemImage: "threads",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "threads.net/@username",
        titleSuggestions: ["Follow me on Threads"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "threads.net") }
    )
    
    static let youtube = ContactFieldType(
        id: "youtube",
        displayName: "YouTube",
        systemImage: "youtube",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "youtube.com/@channel",
        titleSuggestions: ["Subscribe to my channel"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "youtube.com") }
    )
    
    static let snapchat = ContactFieldType(
        id: "snapchat",
        displayName: "Snapchat",
        systemImage: "camera.fill",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "snapchat.com/add/username",
        titleSuggestions: ["Add me on Snapchat"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "snapchat.com") }
    )
    
    static let pinterest = ContactFieldType(
        id: "pinterest",
        displayName: "Pinterest",
        systemImage: "pin.fill",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "pinterest.com/username",
        titleSuggestions: ["Follow me on Pinterest"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "pinterest.com") }
    )
    
    static let twitch = ContactFieldType(
        id: "twitch",
        displayName: "Twitch",
        systemImage: "twitch",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "twitch.tv/username",
        titleSuggestions: ["Watch me on Twitch"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "twitch.tv") }
    )
    
    static let bluesky = ContactFieldType(
        id: "bluesky",
        displayName: "Bluesky",
        systemImage: "bluesky",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "bsky.app/profile/username",
        titleSuggestions: ["Follow me on Bluesky"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "bsky.app") }
    )
    
    static let mastodon = ContactFieldType(
        id: "mastodon",
        displayName: "Mastodon",
        systemImage: "mastodon",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "mastodon.social/@username",
        titleSuggestions: ["Follow me on Mastodon"],
        keyboardType: .URL,
        urlBuilder: { value in
            if value.hasPrefix("http://") || value.hasPrefix("https://") {
                return URL(string: value)
            }
            if value.contains(".") {
                return URL(string: "https://\(value)")
            }
            let username = value.hasPrefix("@") ? String(value.dropFirst()) : value
            return URL(string: "https://mastodon.social/@\(username)")
        }
    )
    
    static let reddit = ContactFieldType(
        id: "reddit",
        displayName: "Reddit",
        systemImage: "reddit",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .social,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "reddit.com/user/username",
        titleSuggestions: ["Follow me on Reddit"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "reddit.com") }
    )
    
    // MARK: - Developer
    
    static let github = ContactFieldType(
        id: "github",
        displayName: "GitHub",
        systemImage: "github.fill",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .developer,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "github.com/username",
        titleSuggestions: ["View our work on GitHub", "View our GitHub Repo"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "github.com") }
    )
    
    static let gitlab = ContactFieldType(
        id: "gitlab",
        displayName: "GitLab",
        systemImage: "chevron.left.forwardslash.chevron.right",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .developer,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "gitlab.com/username",
        titleSuggestions: ["View our work on GitLab"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "gitlab.com") }
    )
    
    static let stackoverflow = ContactFieldType(
        id: "stackoverflow",
        displayName: "Stack Overflow",
        systemImage: "text.bubble.fill",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .developer,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "stackoverflow.com/users/id",
        titleSuggestions: ["Ask me on Stack Overflow"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "stackoverflow.com") }
    )
    
    // MARK: - Messaging
    
    static let telegram = ContactFieldType(
        id: "telegram",
        displayName: "Telegram",
        systemImage: "telegram",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .messaging,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "t.me/username",
        titleSuggestions: ["Connect with me on Telegram"],
        keyboardType: .URL,
        urlBuilder: { value in
            if value.hasPrefix("t.me/") || value.hasPrefix("https://t.me/") {
                return URL(string: value.hasPrefix("https://") ? value : "https://\(value)")
            }
            return URL(string: "tg://resolve?domain=\(value)")
        }
    )
    
    static let whatsapp = ContactFieldType(
        id: "whatsapp",
        displayName: "WhatsApp",
        systemImage: "message.fill",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .messaging,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "+1 555 123 4567",
        titleSuggestions: ["Message me on WhatsApp"],
        keyboardType: .phonePad,
        urlBuilder: { value in
            let digits = value.filter { $0.isNumber }
            return URL(string: "https://wa.me/\(digits)")
        }
    )
    
    static let signal = ContactFieldType(
        id: "signal",
        displayName: "Signal",
        systemImage: "bubble.left.fill",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .messaging,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "+1 555 123 4567",
        titleSuggestions: ["Message me on Signal"],
        keyboardType: .phonePad,
        urlBuilder: { value in
            let digits = value.filter { $0.isNumber || $0 == "+" }
            return URL(string: "sgnl://signal.me/#p/\(digits)")
        }
    )
    
    static let discord = ContactFieldType(
        id: "discord",
        displayName: "Discord",
        systemImage: "discord",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .messaging,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "discord.gg/invite",
        titleSuggestions: ["Join my Discord"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "discord.gg") }
    )
    
    static let slack = ContactFieldType(
        id: "slack",
        displayName: "Slack",
        systemImage: "slack",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .messaging,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "yourworkspace.slack.com",
        titleSuggestions: ["Join our Slack"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "slack.com") }
    )
    
    static let matrix = ContactFieldType(
        id: "matrix",
        displayName: "Matrix",
        systemImage: "matrix",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .messaging,
        valueLabel: String(localized: "Username/Link"),
        valuePlaceholder: "@username:matrix.org",
        titleSuggestions: ["Chat with me on Matrix"],
        keyboardType: .URL,
        urlBuilder: { value in
            if value.contains("matrix.to") || value.contains("element.io") {
                return URL(string: value.hasPrefix("https://") ? value : "https://\(value)")
            }
            let encoded = value.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? value
            return URL(string: "https://matrix.to/#/\(encoded)")
        }
    )
    
    // MARK: - Payment
    
    static let venmo = ContactFieldType(
        id: "venmo",
        displayName: "Venmo",
        systemImage: "dollarsign.circle.fill",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .payment,
        valueLabel: String(localized: "Username"),
        valuePlaceholder: "@username",
        titleSuggestions: ["Pay via Venmo"],
        keyboardType: .default,
        urlBuilder: { value in
            let username = value.hasPrefix("@") ? String(value.dropFirst()) : value
            return URL(string: "venmo://users/\(username)")
        }
    )
    
    static let cashApp = ContactFieldType(
        id: "cashApp",
        displayName: "Cash App",
        systemImage: "dollarsign.square.fill",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .payment,
        valueLabel: String(localized: "Username"),
        valuePlaceholder: "$cashtag",
        titleSuggestions: ["Pay via Cash App"],
        keyboardType: .default,
        urlBuilder: { value in
            let cashtag = value.hasPrefix("$") ? String(value.dropFirst()) : value
            return URL(string: "cashapp://cash.app/$\(cashtag)")
        }
    )
    
    static let paypal = ContactFieldType(
        id: "paypal",
        displayName: "PayPal",
        systemImage: "creditcard.fill",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .payment,
        valueLabel: String(localized: "Email or Username"),
        valuePlaceholder: "paypal.me/username",
        titleSuggestions: ["Pay via PayPal"],
        keyboardType: .emailAddress,
        urlBuilder: { URL(string: "https://paypal.me/\($0)") }
    )
    
    static let zelle = ContactFieldType(
        id: "zelle",
        displayName: "Zelle",
        systemImage: "dollarsign.arrow.circlepath",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .payment,
        valueLabel: String(localized: "Phone or Email"),
        valuePlaceholder: "email@example.com",
        titleSuggestions: ["Pay via Zelle"],
        keyboardType: .phonePad,
        urlBuilder: { _ in nil }  // Zelle has no universal deep link
    )
    
    // MARK: - Creator/Funding
    
    static let patreon = ContactFieldType(
        id: "patreon",
        displayName: "Patreon",
        systemImage: "patreon.fill",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .creator,
        valueLabel: String(localized: "Profile Link"),
        valuePlaceholder: "patreon.com/username",
        titleSuggestions: ["Support me on Patreon"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "patreon.com") }
    )
    
    static let kofi = ContactFieldType(
        id: "kofi",
        displayName: "Ko-fi",
        systemImage: "ko-fi",
        isCustomSymbol: true,
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .creator,
        valueLabel: String(localized: "Profile Link"),
        valuePlaceholder: "ko-fi.com/username",
        titleSuggestions: ["Buy me a coffee"],
        keyboardType: .URL,
        urlBuilder: { buildSocialURL($0, webBase: "ko-fi.com") }
    )
    
    // MARK: - Scheduling
    
    static let calendly = ContactFieldType(
        id: "calendly",
        displayName: "Calendly",
        systemImage: "calendar",
        iconColor: Color(red: 0.0, green: 0.0, blue: 0.0),
        category: .scheduling,
        valueLabel: String(localized: "Calendly Link"),
        valuePlaceholder: "calendly.com/username",
        titleSuggestions: ["Schedule a meeting"],
        keyboardType: .URL,
        urlBuilder: { buildWebURL($0) }
    )
    
    // MARK: - Other
    
    static let customLink = ContactFieldType(
        id: "customLink",
        displayName: String(localized: "Link"),
        systemImage: "link",
        iconColor: Color(red: 0.2, green: 0.2, blue: 0.2),
        category: .other,
        valueLabel: String(localized: "URL"),
        valuePlaceholder: "https://example.com",
        titleSuggestions: [],
        keyboardType: .URL,
        urlBuilder: { buildWebURL($0) }
    )
}

// MARK: - Display Value Formatters

/// Formats an address for multi-line display
/// Tries to parse as structured PostalAddress JSON first, falls back to legacy format
nonisolated private func formatAddressForDisplay(_ value: String) -> String {
    let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
    guard !trimmed.isEmpty else { return value }
    
    // Parse as structured PostalAddress
    if let address = PostalAddress.decode(from: trimmed), address.hasValue {
        return address.formattedString
    }
    
    // Not a valid address format
    return trimmed
}

// MARK: - URL Helper Functions

nonisolated private func buildWebURL(_ value: String) -> URL? {
    let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
    guard !trimmed.isEmpty else { return nil }
    
    if trimmed.hasPrefix("http://") || trimmed.hasPrefix("https://") {
        return URL(string: trimmed)
    }
    return URL(string: "https://\(trimmed)")
}

nonisolated private func buildSocialURL(_ value: String, webBase: String) -> URL? {
    let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
    guard !trimmed.isEmpty else { return nil }
    
    // If already a full URL, use it
    if trimmed.hasPrefix("http://") || trimmed.hasPrefix("https://") {
        return URL(string: trimmed)
    }
    
    // If contains the base domain, add https
    if trimmed.contains(webBase) {
        return URL(string: "https://\(trimmed)")
    }
    
    // Otherwise, treat as username and build URL
    let username = trimmed.hasPrefix("@") ? String(trimmed.dropFirst()) : trimmed
    return URL(string: "https://\(webBase)/\(username)")
}
