import Foundation
import Combine
import Security

@MainActor
class PDSService: ObservableObject {
    private var credentials: PDSCredentials?
    private var baseURL: URL?
    private var authHeader: String?
    private var session = URLSession.shared
    
    // Published properties for UI to observe
    @Published var isAuthenticated = false
    @Published var inviteCodes: [InviteCode] = []
    @Published var users: [PDSUser] = []
    @Published var isLoading = false
    @Published var errorMessage: String?
    
    // MARK: - Keychain Constants
    private struct KeychainConstants {
        static let service = "com.atproto.pdsmanager"
        static let usernameKey = "username"
        static let passwordKey = "password"
        static let serverURLKey = "serverURL"
        static let authHeaderKey = "authHeader"
    }
    
    init() {
        // Try to restore previous session on launch
        loadCredentialsFromKeychain()
    }
    
    // MARK: - Keychain Access
    
    private func saveToKeychain(key: String, value: String) -> Bool {
        if let data = value.data(using: .utf8) {
            let query: [String: Any] = [
                kSecClass as String: kSecClassGenericPassword,
                kSecAttrService as String: KeychainConstants.service,
                kSecAttrAccount as String: key,
                kSecValueData as String: data
            ]
            
            // First delete any existing item
            SecItemDelete(query as CFDictionary)
            
            // Then add the new item
            let status = SecItemAdd(query as CFDictionary, nil)
            return status == errSecSuccess
        }
        return false
    }
    
    private func loadFromKeychain(key: String) -> String? {
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: KeychainConstants.service,
            kSecAttrAccount as String: key,
            kSecReturnData as String: true,
            kSecMatchLimit as String: kSecMatchLimitOne
        ]
        
        var result: AnyObject?
        let status = SecItemCopyMatching(query as CFDictionary, &result)
        
        if status == errSecSuccess, let data = result as? Data, let value = String(data: data, encoding: .utf8) {
            return value
        }
        return nil
    }
    
    private func deleteFromKeychain(key: String) -> Bool {
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: KeychainConstants.service,
            kSecAttrAccount as String: key
        ]
        
        let status = SecItemDelete(query as CFDictionary)
        return status == errSecSuccess || status == errSecItemNotFound
    }
    
    private func saveCredentialsToKeychain() {
        guard let credentials = credentials else { return }
        
        _ = saveToKeychain(key: KeychainConstants.usernameKey, value: credentials.username)
        _ = saveToKeychain(key: KeychainConstants.passwordKey, value: credentials.password)
        _ = saveToKeychain(key: KeychainConstants.serverURLKey, value: credentials.serverURL)
        
        if let authHeader = authHeader {
            _ = saveToKeychain(key: KeychainConstants.authHeaderKey, value: authHeader)
        }
        
        print("Credentials saved to keychain")
    }
    
    private func loadCredentialsFromKeychain() {
        guard let username = loadFromKeychain(key: KeychainConstants.usernameKey),
              let password = loadFromKeychain(key: KeychainConstants.passwordKey),
              let serverURL = loadFromKeychain(key: KeychainConstants.serverURLKey),
              let authHeader = loadFromKeychain(key: KeychainConstants.authHeaderKey) else {
            print("No credentials found in keychain")
            return
        }
        
        print("Credentials loaded from keychain")
        
        // Restore the credentials
        self.credentials = PDSCredentials(serverURL: serverURL, username: username, password: password)
        self.baseURL = URL(string: serverURL)
        self.authHeader = authHeader
        self.isAuthenticated = true
        
        // Refresh data
        Task {
            await fetchInviteCodes()
            await fetchUsers()
        }
    }
    
    private func clearCredentialsFromKeychain() {
        _ = deleteFromKeychain(key: KeychainConstants.usernameKey)
        _ = deleteFromKeychain(key: KeychainConstants.passwordKey)
        _ = deleteFromKeychain(key: KeychainConstants.serverURLKey)
        _ = deleteFromKeychain(key: KeychainConstants.authHeaderKey)
        print("Credentials cleared from keychain")
    }
    
    // MARK: - Response Structures
    
    // Invite Code structures
    struct InviteCodesResponse: Codable {
        var codes: [InviteCodeResponse]
    }
    
    struct InviteCodeResponse: Codable {
        var code: String
        var available: Int
        var disabled: Bool
        var createdAt: String
        var createdBy: String
        var uses: [CodeUse]?
    }
    
    struct CodeUse: Codable {
        var usedBy: String
        var usedAt: String
    }
    
    struct CreateCodeResponse: Codable {
        var code: String
    }
    
    // User structures
    struct RepoResponse: Codable {
        var cursor: String?
        var repos: [Repo]
    }
    
    struct Repo: Codable {
        var did: String
        var head: String
        var rev: String
        var active: Bool
    }
    
    struct AccountInfo: Codable {
        var did: String
        var handle: String
        var email: String?
        var emailConfirmedAt: String?
        var indexedAt: String
        var invitedBy: InviteInfo?
        var invites: [String]?
        var invitesDisabled: Bool?
        var createdAt: String {
            return indexedAt
        }
    }
    
    struct InviteInfo: Codable {
        var code: String
        var available: Int
        var disabled: Bool
        var forAccount: String
        var createdBy: String
        var createdAt: String
        var uses: [CodeUse]?
    }
    
    struct ProfileResponse: Codable {
        var value: ProfileValue
    }
    
    struct ProfileValue: Codable {
        var displayName: String?
        var description: String?
        var avatar: Avatar?
    }
    
    struct Avatar: Codable {
        var ref: AvatarRef
    }
    
    struct AvatarRef: Codable {
        var link: String
        
        enum CodingKeys: String, CodingKey {
            case link = "$link"
        }
    }
    
    // MARK: - Authentication
    
    private func setAuthenticated(_ value: Bool) {
        print("PDSService: setting isAuthenticated to \(value)")
        self.isAuthenticated = value
    }
    
    func login(credentials: PDSCredentials) async -> Bool {
        print("Attempting to connect to server: \(credentials.serverURL)")
        self.credentials = credentials
        self.isLoading = true
        defer { self.isLoading = false }
        
        // Clear any previous errors
        self.errorMessage = nil
        
        // Validate the URL format
        guard let components = URLComponents(string: credentials.serverURL) else {
            setError("Invalid URL format: The server URL is not properly formatted")
            return false
        }
        
        // Ensure scheme is either http or https
        guard let scheme = components.scheme, (scheme == "http" || scheme == "https") else {
            setError("Invalid URL scheme: URL must begin with http:// or https://")
            return false
        }
        
        // Ensure there's a host
        guard let host = components.host, !host.isEmpty else {
            setError("Invalid URL: Missing or empty host")
            return false
        }
        
        guard let url = URL(string: credentials.serverURL) else {
            setError("Invalid URL format")
            return false
        }
        
        // Test if we can connect to a known reliable server
        if await !testInternetConnectivity() {
            setError("Network connectivity issue: Cannot reach the internet. Please check your network connection.")
            return false
        }
        
        self.baseURL = url
        
        // Create Basic Auth header from credentials
        let authString = "\(credentials.username):\(credentials.password)"
        guard let authData = authString.data(using: .utf8) else {
            setError("Invalid authentication data")
            return false
        }
        
        let base64Auth = authData.base64EncodedString()
        self.authHeader = "Basic \(base64Auth)"
        
        // Just check if the server exists and is running, no auth needed for this endpoint
        guard let testURL = URL(string: "\(credentials.serverURL)/xrpc/com.atproto.server.describeServer") else {
            setError("Invalid server URL")
            return false
        }
        
        print("Testing connectivity to: \(testURL.absoluteString)")
        
        // Create a URLSession with shorter timeouts
        let config = URLSessionConfiguration.default
        config.timeoutIntervalForRequest = 10 // 10 seconds timeout
        config.timeoutIntervalForResource = 10
        let quickTimeoutSession = URLSession(configuration: config)
        
        var request = URLRequest(url: testURL)
        request.httpMethod = "GET"
        
        do {
            print("Sending request...")
            let (data, response) = try await quickTimeoutSession.data(for: request)
            print("Got response: \(response)")
            
            // Debug: print response data as string
            if let dataString = String(data: data, encoding: .utf8) {
                print("Response data: \(dataString)")
            }
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response from server")
                return false
            }
            
            // If the server responds with 200, we consider it a success
            // verify auth credentials when user accesses protected endpoints
            if httpResponse.statusCode == 200 {
                setAuthenticated(true)
                
                // Save credentials securely
                saveCredentialsToKeychain()
                
                self.errorMessage = nil
                print("Login successful!")
                return true
            } else {
                let errorMessage = "Server error: \(httpResponse.statusCode)"
                print(errorMessage)
                setError(errorMessage)
                return false
            }
        } catch let error as NSError {
            // Handle specific network errors with better messages
            print("Connection error: \(error.domain) code: \(error.code) - \(error.localizedDescription)")
            
            if error.domain == NSURLErrorDomain {
                switch error.code {
                case NSURLErrorCannotFindHost:
                    setError("Cannot find host: The server URL appears to be invalid or the server is unreachable")
                case NSURLErrorCannotConnectToHost:
                    setError("Cannot connect to host: The server exists but isn't responding")
                case NSURLErrorNetworkConnectionLost:
                    setError("Connection lost: The network connection was lost during the request")
                case NSURLErrorNotConnectedToInternet:
                    setError("No internet connection: Please check your network settings")
                case NSURLErrorTimedOut:
                    setError("Connection timed out: The server took too long to respond")
                default:
                    setError("Network error (\(error.code)): \(error.localizedDescription)")
                }
            } else {
                setError("Connection error: \(error.localizedDescription)")
            }
            return false
        }
    }
    
    // Test basic internet connectivity by trying to reach a reliable server
    private func testInternetConnectivity() async -> Bool {
        print("Testing general internet connectivity...")
        
        // Use Apple's captive portal detection as a reliable server to test connectivity
        guard let connectivityURL = URL(string: "https://www.apple.com/library/test/success.html") else {
            return false
        }
        
        let config = URLSessionConfiguration.default
        config.timeoutIntervalForRequest = 5
        config.waitsForConnectivity = false
        let session = URLSession(configuration: config)
        
        do {
            let (_, response) = try await session.data(for: URLRequest(url: connectivityURL))
            guard let httpResponse = response as? HTTPURLResponse else {
                return false
            }
            
            print("Internet connectivity test: status code \(httpResponse.statusCode)")
            return httpResponse.statusCode == 200
        } catch {
            print("Internet connectivity test failed: \(error.localizedDescription)")
            return false
        }
    }
    
    func logout() {
        // Clear authentication state
        setAuthenticated(false)
        self.authHeader = nil
        self.credentials = nil
        self.baseURL = nil
        self.users = []
        self.inviteCodes = []
        self.errorMessage = nil
        
        // Clear saved credentials
        clearCredentialsFromKeychain()
    }
    
    // MARK: - Invite Codes
    
    func fetchInviteCodes() async {
        guard isAuthenticated, let baseURL = baseURL, let authHeader = authHeader else { return }
        
        self.isLoading = true
        
        defer {
            self.isLoading = false
        }
        
        // Construct the URL for the invite codes endpoint
        guard let inviteCodesURL = URL(string: "\(baseURL)/xrpc/com.atproto.admin.getInviteCodes") else {
            setError("Invalid invite codes URL")
            return
        }
        
        // Add query parameters
        var components = URLComponents(url: inviteCodesURL, resolvingAgainstBaseURL: true)
        components?.queryItems = [
            URLQueryItem(name: "sort", value: "recent"),
            URLQueryItem(name: "limit", value: "100"),
            URLQueryItem(name: "includeDisabled", value: "true") // Always include disabled codes
        ]
        
        guard let finalURL = components?.url else {
            setError("Invalid invite codes URL with parameters")
            return
        }
        
        var request = URLRequest(url: finalURL)
        request.httpMethod = "GET"
        request.addValue(authHeader, forHTTPHeaderField: "Authorization")
        
        do {
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response from server")
                return
            }
            
            if httpResponse.statusCode == 200 {
                let decoder = JSONDecoder()
                decoder.keyDecodingStrategy = .convertFromSnakeCase
                
                let codesResponse = try decoder.decode(InviteCodesResponse.self, from: data)
                
                let dateFormatter = ISO8601DateFormatter()
                
                let parsedCodes = codesResponse.codes.map { codeResp -> InviteCode in
                    let createdDate = dateFormatter.date(from: codeResp.createdAt) ?? Date()
                    
                    // Convert the uses array
                    let inviteUses = codeResp.uses?.map { use -> PDSMan.CodeUse in
                        return PDSMan.CodeUse(usedBy: use.usedBy, usedAt: use.usedAt)
                    }
                    
                    return InviteCode(
                        id: codeResp.code,
                        uses: inviteUses,
                        createdAt: createdDate,
                        disabled: codeResp.disabled
                    )
                }
                
                self.inviteCodes = parsedCodes
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to fetch invite codes: \(httpResponse.statusCode) - \(responseString)")
            }
        } catch {
            setError("Failed to fetch invite codes: \(error.localizedDescription)")
        }
    }
    
    func createInviteCode(maxUses: Int = 1) async -> InviteCode? {
        guard isAuthenticated, let baseURL = baseURL, let authHeader = authHeader else { return nil }
        
        // Construct the URL for creating an invite code
        guard let createURL = URL(string: "\(baseURL)/xrpc/com.atproto.server.createInviteCode") else {
            setError("Invalid create invite code URL")
            return nil
        }
        
        var request = URLRequest(url: createURL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue(authHeader, forHTTPHeaderField: "Authorization")
        
        let createBody = ["useCount": maxUses]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: createBody)
            request.httpBody = jsonData
            
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response from server")
                return nil
            }
            
            if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
                // Parse the response to get the new code
                let decoder = JSONDecoder()
                let codeResponse = try decoder.decode(CreateCodeResponse.self, from: data)
                
                // Create a new InviteCode object
                let newCode = InviteCode(
                    id: codeResponse.code,
                    uses: [] as [PDSMan.CodeUse]?,
                    createdAt: Date(),
                    disabled: false
                )
                
                // Update the local list
                self.inviteCodes.append(newCode)
                
                return newCode
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to create invite code: \(httpResponse.statusCode) - \(responseString)")
                return nil
            }
        } catch {
            setError("Failed to create invite code: \(error.localizedDescription)")
            return nil
        }
    }
    
    func disableInviteCode(_ code: String) async -> Bool {
        guard isAuthenticated, let baseURL = baseURL, let authHeader = authHeader else { return false }
        
        guard let disableURL = URL(string: "\(baseURL)/xrpc/com.atproto.admin.disableInviteCodes") else {
            setError("Invalid disable invite code URL")
            return false
        }
        
        var request = URLRequest(url: disableURL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue(authHeader, forHTTPHeaderField: "Authorization")
        
        // Create the request body with an array of codes
        let disableBody = ["codes": [code]]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: disableBody)
            request.httpBody = jsonData
            
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response from server")
                return false
            }
            
            if httpResponse.statusCode == 200 {
                // Refresh the invite codes
                await fetchInviteCodes()
                return true
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to disable invite code: \(httpResponse.statusCode) - \(responseString)")
                return false
            }
        } catch {
            setError("Failed to disable invite code: \(error.localizedDescription)")
            return false
        }
    }
    
    // MARK: - Users
    
    func fetchUsers() async {
        guard isAuthenticated, let baseURL = baseURL, let authHeader = authHeader else { return }
        
        self.isLoading = true
        
        defer {
            self.isLoading = false
        }
        
        // Construct the URL for the repos endpoint
        guard let reposURL = URL(string: "\(baseURL)/xrpc/com.atproto.sync.listRepos") else {
            setError("Invalid list repos URL")
            return
        }
        
        // Add query parameters
        var components = URLComponents(url: reposURL, resolvingAgainstBaseURL: true)
        components?.queryItems = [
            URLQueryItem(name: "limit", value: "100")
        ]
        
        guard let finalURL = components?.url else {
            setError("Invalid repos URL with parameters")
            return
        }
        
        var request = URLRequest(url: finalURL)
        request.httpMethod = "GET"
        request.addValue(authHeader, forHTTPHeaderField: "Authorization")
        
        do {
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response from server")
                return
            }
            
            if httpResponse.statusCode == 200 {
                let decoder = JSONDecoder()
                decoder.keyDecodingStrategy = .convertFromSnakeCase
                
                let reposResponse = try decoder.decode(RepoResponse.self, from: data)
                
                // Fetch details for each user
                var fetchedUsers: [PDSUser] = []
                
                for repo in reposResponse.repos {
                    if let user = await fetchUserProfile(did: repo.did, isActive: repo.active) {
                        fetchedUsers.append(user)
                    }
                }
                
                // Sort users by join date (newest first)
                fetchedUsers.sort { $0.joinedAt > $1.joinedAt }
                
                self.users = fetchedUsers
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to fetch users: \(httpResponse.statusCode) - \(responseString)")
            }
        } catch {
            setError("Failed to fetch users: \(error.localizedDescription)")
        }
    }
    
    private func fetchUserProfile(did: String, isActive: Bool = true) async -> PDSUser? {
        guard let baseURL = baseURL, let authHeader = authHeader else { 
            print("Cannot fetch user profile: Missing baseURL or authHeader")
            return nil 
        }
        
        print("Fetching profile for user: \(did)")
        
        // First, fetch account info
        do {
            // 1. Fetch account info
            guard let accountURL = URL(string: "\(baseURL)/xrpc/com.atproto.admin.getAccountInfo?did=\(did)") else {
                print("Invalid account info URL for did: \(did)")
                return nil
            }
            
            print("Requesting account info from: \(accountURL.absoluteString)")
            
            var accountRequest = URLRequest(url: accountURL)
            accountRequest.httpMethod = "GET"
            accountRequest.addValue(authHeader, forHTTPHeaderField: "Authorization")
            
            let (accountData, accountResponse) = try await session.data(for: accountRequest)
            
            guard let httpResponse = accountResponse as? HTTPURLResponse else {
                print("Invalid HTTP response for account info")
                return nil
            }
            
            // Print response status and data for debugging
            print("Account info response status: \(httpResponse.statusCode)")
            if let responseString = String(data: accountData, encoding: .utf8) {
                print("Account info response: \(responseString)")
            }
            
            guard httpResponse.statusCode == 200 else {
                let statusCode = httpResponse.statusCode
                let responseText = String(data: accountData, encoding: .utf8) ?? "Unknown error"
                print("Account info failed with status \(statusCode): \(responseText)")
                return createBasicUser(did: did, handle: did, isActive: isActive)
            }
            
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            
            // Parse the account info
            let accountInfo: AccountInfo
            do {
                accountInfo = try decoder.decode(AccountInfo.self, from: accountData)
                print("Successfully decoded account info for \(accountInfo.handle)")
            } catch {
                print("Error decoding account info: \(error)")
                // If we can't decode the account info, create a basic user with the DID
                return createBasicUser(did: did, handle: did, isActive: isActive)
            }
            
            // 2. Try to fetch profile data (optional)
            var displayName = accountInfo.handle
            var description = ""
            var avatarURL: URL? = nil
            
            // Try to fetch profile record
            let profileURLString = "\(baseURL)/xrpc/com.atproto.repo.getRecord?collection=app.bsky.actor.profile&repo=\(did)&rkey=self"
            guard let profileURL = URL(string: profileURLString) else {
                print("Invalid profile URL: \(profileURLString)")
                // Still return user with account info
                let dateFormatter = ISO8601DateFormatter()
                let joinedDate = dateFormatter.date(from: accountInfo.indexedAt) ?? Date()
                
                return PDSUser(
                    id: accountInfo.did,
                    handle: accountInfo.handle,
                    displayName: displayName,
                    description: description,
                    joinedAt: joinedDate,
                    avatar: avatarURL,
                    isActive: isActive
                )
            }
            
            print("Fetching profile from: \(profileURL.absoluteString)")
            
            var profileRequest = URLRequest(url: profileURL)
            profileRequest.httpMethod = "GET"
            profileRequest.addValue(authHeader, forHTTPHeaderField: "Authorization")
            
            do {
                let (profileData, profileResponse) = try await session.data(for: profileRequest)
                
                if let httpResponse = profileResponse as? HTTPURLResponse {
                    print("Profile response status: \(httpResponse.statusCode)")
                    
                    if let responseString = String(data: profileData, encoding: .utf8) {
                        print("Profile response: \(responseString)")
                    }
                    
                    if httpResponse.statusCode == 200 {
                        // Define the structures to match the expected response
                        do {
                            // Try to decode the profile data
                            let profileRecord = try decoder.decode(ProfileResponse.self, from: profileData)
                            
                            if let name = profileRecord.value.displayName, !name.isEmpty {
                                displayName = name
                            }
                            
                            if let desc = profileRecord.value.description, !desc.isEmpty {
                                description = desc
                            }
                            
                            if let avatar = profileRecord.value.avatar {
                                // Construct avatar URL
                                avatarURL = URL(string: "\(baseURL)/xrpc/com.atproto.sync.getBlob?did=\(did)&cid=\(avatar.ref.link)")
                                print("Avatar URL: \(avatarURL?.absoluteString ?? "nil")")
                            }
                        } catch {
                            print("Error decoding profile: \(error)")
                            // Continue with basic info if profile decoding fails
                        }
                    } else {
                        // Profile fetch failed, but we can still continue with account info
                        print("Profile fetch failed with status \(httpResponse.statusCode)")
                    }
                }
            } catch {
                // Continue without profile data
                print("Error fetching profile: \(error.localizedDescription)")
            }
            
            let dateFormatter = ISO8601DateFormatter()
            let joinedDate = dateFormatter.date(from: accountInfo.indexedAt) ?? Date()
            
            return PDSUser(
                id: accountInfo.did,
                handle: accountInfo.handle,
                displayName: displayName,
                description: description,
                joinedAt: joinedDate,
                avatar: avatarURL,
                isActive: isActive
            )
        } catch {
            print("Error fetching account info: \(error.localizedDescription)")
            return createBasicUser(did: did, handle: did, isActive: isActive)
        }
    }
    
    // Helper method to create a basic user with minimal info
    private func createBasicUser(did: String, handle: String, isActive: Bool) -> PDSUser {
        print("Creating basic user for did: \(did)")
        return PDSUser(
            id: did,
            handle: handle,
            displayName: handle,
            description: "",
            joinedAt: Date(),
            avatar: nil,
            isActive: isActive
        )
    }
    
    func editUserHandle(userId: String, newHandle: String) async -> Bool {
        guard isAuthenticated, let baseURL = baseURL, let authHeader = authHeader else { return false }
        
        guard let updateURL = URL(string: "\(baseURL)/xrpc/com.atproto.admin.updateAccountHandle") else {
            setError("Invalid update handle URL")
            return false
        }
        
        var request = URLRequest(url: updateURL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue(authHeader, forHTTPHeaderField: "Authorization")
        
        // Create the request body
        let updateBody: [String: String] = [
            "did": userId,
            "handle": newHandle
        ]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: updateBody)
            request.httpBody = jsonData
            
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response")
                return false
            }
            
            if httpResponse.statusCode == 200 {
                // Refresh the users list to show the updated handle
                await fetchUsers()
                return true
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to update handle: \(httpResponse.statusCode) - \(responseString)")
                return false
            }
        } catch {
            setError("Failed to update handle: \(error.localizedDescription)")
            return false
        }
    }
    
    func resetUserPassword(userId: String) async -> Bool {
        guard isAuthenticated, let baseURL = baseURL else { return false }
        
        // Construct the URL for resetting a user's password
        guard let resetURL = URL(string: "\(baseURL)/xrpc/com.atproto.admin.resetPassword") else {
            setError("Invalid reset password URL")
            return false
        }
        
        var request = URLRequest(url: resetURL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        let resetBody = ["did": userId]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: resetBody)
            request.httpBody = jsonData
            
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response from server")
                return false
            }
            
            if httpResponse.statusCode == 200 || httpResponse.statusCode == 204 {
                return true
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to reset password: \(httpResponse.statusCode) - \(responseString)")
                return false
            }
        } catch {
            setError("Failed to reset password: \(error.localizedDescription)")
            return false
        }
    }
    
    func sendResetEmail(userId: String) async -> Bool {
        guard isAuthenticated, let baseURL = baseURL else { return false }
        
        // Construct the URL for sending a reset email
        guard let emailURL = URL(string: "\(baseURL)/xrpc/com.atproto.admin.sendEmail") else {
            setError("Invalid send email URL")
            return false
        }
        
        var request = URLRequest(url: emailURL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        let emailBody = [
            "recipientDid": userId,
            "subject": "Password Reset",
            "body": "Click the link to reset your password."
        ]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: emailBody)
            request.httpBody = jsonData
            
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response from server")
                return false
            }
            
            if httpResponse.statusCode == 200 || httpResponse.statusCode == 204 {
                return true
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to send reset email: \(httpResponse.statusCode) - \(responseString)")
                return false
            }
        } catch {
            setError("Failed to send reset email: \(error.localizedDescription)")
            return false
        }
    }
    
    func deleteUser(userId: String) async -> Bool {
        guard isAuthenticated, let baseURL = baseURL else { return false }
        
        // Construct the URL for deleting a user
        guard let deleteURL = URL(string: "\(baseURL)/xrpc/com.atproto.admin.deleteAccount") else {
            setError("Invalid delete user URL")
            return false
        }
        
        var request = URLRequest(url: deleteURL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        let deleteBody = ["did": userId]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: deleteBody)
            request.httpBody = jsonData
            
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response from server")
                return false
            }
            
            if httpResponse.statusCode == 200 || httpResponse.statusCode == 204 {
                // Update the local list
                self.users.removeAll { $0.id == userId }
                return true
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to delete user: \(httpResponse.statusCode) - \(responseString)")
                return false
            }
        } catch {
            setError("Failed to delete user: \(error.localizedDescription)")
            return false
        }
    }
    
    func suspendUser(userId: String, reason: String) async -> Bool {
        guard isAuthenticated, let baseURL = baseURL, let authHeader = authHeader else { return false }
        
        guard let suspendURL = URL(string: "\(baseURL)/xrpc/com.atproto.admin.disableAccountByDid") else {
            setError("Invalid suspend user URL")
            return false
        }
        
        var request = URLRequest(url: suspendURL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue(authHeader, forHTTPHeaderField: "Authorization")
        
        // Create the request body
        let suspendBody: [String: Any] = [
            "did": userId,
            "reason": reason
        ]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: suspendBody)
            request.httpBody = jsonData
            
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response")
                return false
            }
            
            if httpResponse.statusCode == 200 {
                // Refresh the users list to show the updated status
                await fetchUsers()
                return true
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to suspend user: \(httpResponse.statusCode) - \(responseString)")
                return false
            }
        } catch {
            setError("Failed to suspend user: \(error.localizedDescription)")
            return false
        }
    }
    
    func reactivateUser(userId: String) async -> Bool {
        guard isAuthenticated, let baseURL = baseURL, let authHeader = authHeader else { return false }
        
        guard let reactivateURL = URL(string: "\(baseURL)/xrpc/com.atproto.admin.enableAccountByDid") else {
            setError("Invalid reactivate user URL")
            return false
        }
        
        var request = URLRequest(url: reactivateURL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue(authHeader, forHTTPHeaderField: "Authorization")
        
        // Create the request body
        let reactivateBody: [String: String] = [
            "did": userId
        ]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: reactivateBody)
            request.httpBody = jsonData
            
            let (data, response) = try await session.data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse else {
                setError("Invalid response")
                return false
            }
            
            if httpResponse.statusCode == 200 {
                // Refresh the users list to show the updated status
                await fetchUsers()
                return true
            } else {
                let responseString = String(data: data, encoding: .utf8) ?? "Unknown error"
                setError("Failed to reactivate user: \(httpResponse.statusCode) - \(responseString)")
                return false
            }
        } catch {
            setError("Failed to reactivate user: \(error.localizedDescription)")
            return false
        }
    }
    
    // MARK: - Helper Methods
    
    private func setError(_ message: String) {
        self.errorMessage = message
        print("Error: \(message)")
    }
} 
