import Combine
import Foundation
import UIKit

/// Settings view model with **cached** state.
///
/// Previously this was `@Observable` with computed properties that read
/// `ProtocolManager`, `SessionManager`, and `AccountManager` directly.
/// Because all tabs are pre-activated, those reads caused SettingsView
/// (inside a NavigationStack) to re-render 6+ times during handshake,
/// producing "Update NavigationRequestObserver tried to update multiple
/// times per frame" → app freeze.
///
/// Now uses `ObservableObject` + `@Published` stored properties.
/// State is refreshed explicitly via `refresh()`.
@MainActor
final class SettingsViewModel: ObservableObject {

    @Published private(set) var displayName: String = ""
    @Published private(set) var username: String = ""
    @Published private(set) var publicKey: String = ""
    @Published private(set) var connectionStatus: String = "Disconnected"
    @Published private(set) var isConnected: Bool = false
    @Published private(set) var deviceCount: Int = 0

    /// Display name for the header. Falls back to first 7 chars of public key.
    var headerName: String {
        if !displayName.isEmpty { return displayName }
        if publicKey.count >= 7 { return String(publicKey.prefix(7)) }
        return publicKey
    }

    var initials: String {
        RosettaColors.initials(name: displayName, publicKey: publicKey)
    }

    var avatarColorIndex: Int {
        RosettaColors.avatarColorIndex(for: displayName, publicKey: publicKey)
    }

    @Published private(set) var verified: Int = 0

    /// Snapshot current state from singletons. Call from `.task {}` or `.onAppear`.
    func refresh() {
        let session = SessionManager.shared
        let account = AccountManager.shared.currentAccount

        displayName = session.displayName.isEmpty
            ? (account?.displayName ?? "")
            : session.displayName

        username = session.username.isEmpty
            ? (account?.username ?? "")
            : session.username

        publicKey = account?.publicKey ?? ""

        // Server-provided verified level + heuristic fallback (Android ProfileScreen parity: else 2)
        let serverVerified = session.verified
        if serverVerified > 0 {
            verified = serverVerified
        } else if (!displayName.isEmpty && displayName.caseInsensitiveCompare("Rosetta") == .orderedSame)
                    || (!username.isEmpty && username.caseInsensitiveCompare("rosetta") == .orderedSame)
                    || (!displayName.isEmpty && displayName.caseInsensitiveCompare("freddy") == .orderedSame)
                    || (!username.isEmpty && username.caseInsensitiveCompare("freddy") == .orderedSame)
                    || SystemAccounts.isSystemAccount(publicKey) {
            verified = 2
        } else {
            verified = 0
        }

        let state = ProtocolManager.shared.connectionState
        isConnected = state == .authenticated
        switch state {
        case .disconnected: connectionStatus = "Disconnected"
        case .connecting: connectionStatus = "Connecting..."
        case .connected: connectionStatus = "Connected"
        case .handshaking: connectionStatus = "Authenticating..."
        case .deviceVerificationRequired: connectionStatus = "Device Verification Required"
        case .authenticated: connectionStatus = "Online"
        }
    }

}
