import Foundation
import Observation

@MainActor
@Observable
final class OLTListViewModel {
    var phase: LoadPhase = .idle
    var olts: [OLTStateDoc] = []
    var search = ""

    private let connection: MCMSConnection
    /// Bumped per load so an overlapping/stale fetch can't commit over a newer one.
    private var loadGeneration = 0
    init(connection: MCMSConnection) { self.connection = connection }

    var filtered: [OLTStateDoc] {
        let query = search.trimmingCharacters(in: .whitespaces)
        guard !query.isEmpty else { return olts }
        return olts.filter {
            $0.id.localizedCaseInsensitiveContains(query)
            || ($0.resolvedName?.localizedCaseInsensitiveContains(query) ?? false)
        }
    }

    func load() async {
        loadGeneration += 1
        let gen = loadGeneration
        phase = .loading
        do {
            let fetched = try await connection.olt.allStates()
            let names = (try? await connection.olt.nameMap()) ?? [:]
            let merged: [OLTStateDoc] = fetched
                .map { olt in var olt = olt; olt.resolvedName = names[olt.id]; return olt }
                .sorted { $0.displayName.localizedCaseInsensitiveCompare($1.displayName) == .orderedAscending }
            guard gen == loadGeneration, !Task.isCancelled else { return }
            olts = merged
            phase = .loaded
        } catch {
            guard gen == loadGeneration, !Task.isCancelled else { return }
            phase = .failed((error as? APIError)?.localizedDescription ?? error.localizedDescription)
        }
    }
}
