import Foundation
import Combine

/// Polls /api/health on the C++ backend. Drives the menu-bar indicator.
@MainActor
final class HealthMonitor: ObservableObject {
    enum Status { case unknown, up, down }

    @Published private(set) var status: Status = .unknown
    @Published private(set) var lastChecked: Date?
    @Published private(set) var lastError: String?

    private var timer: Timer?
    private let session = URLSession(configuration: .ephemeral)

    func start(url: String, every interval: TimeInterval = 10) {
        timer?.invalidate()
        check(url: url)
        timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] _ in
            Task { @MainActor in self?.check(url: url) }
        }
    }

    func stop() { timer?.invalidate(); timer = nil }

    func check(url: String) {
        guard let base = URL(string: url),
              let healthURL = URL(string: "/api/health", relativeTo: base) else {
            status = .down
            lastError = "invalid url: \(url)"
            return
        }
        var req = URLRequest(url: healthURL)
        req.timeoutInterval = 5
        session.dataTask(with: req) { [weak self] _, resp, err in
            Task { @MainActor in
                guard let self else { return }
                self.lastChecked = Date()
                if let err = err {
                    self.status = .down
                    self.lastError = err.localizedDescription
                    return
                }
                let code = (resp as? HTTPURLResponse)?.statusCode ?? 0
                if (200..<300).contains(code) {
                    self.status = .up
                    self.lastError = nil
                } else {
                    self.status = .down
                    self.lastError = "HTTP \(code)"
                }
            }
        }.resume()
    }
}
