//
//  ViewModel.swift
//  dns
//
//  Created by Benjamin Erhart on 14.04.26.
//

import Foundation
import Combine
import NetworkExtension
import OSLog

class ViewModel: NSObject, ObservableObject {

    static let title = "SR2® Cloud DNS"

    // MARK: Public Properties

    @Published
    var blocklist: BlocklistOption = .secure {
        didSet {
            Task {
                manager.dnsSettings = blocklist.settings
                manager.localizedDescription = blocklist.title

                do {
                    try await manager.saveToPreferences()
                }
                catch {
                    log.error("Error storing preferences: \(error)")
                }

                isDnsEnabled = manager.isEnabled
            }
        }
    }

    @Published
    var isDnsEnabled = false

    @Published
    var summaryStatus: SummaryStatus = .pending


    // MARK: Private Properties

    private let manager = NEDNSSettingsManager.shared()

    private let log = Logger(subsystem: String(describing: ViewModel.self), category: String(describing: ViewModel.self))


    override init() {
        super.init()

        Task {
            await refreshConfig()
        }

        Task {
            await fetchServerStatus()
        }
    }


    // MARK: Public Methods

    func refreshConfig() async {
        do {
            try await manager.loadFromPreferences()
        }
        catch {
            log.error("Error loading preferences: \(error)")
        }

        isDnsEnabled = manager.isEnabled

        if let settings = manager.dnsSettings {
            for dnsServer in BlocklistOption.allCases {
                if settings.servers.contains(dnsServer.ipv4) {
                    await MainActor.run {
                        blocklist = dnsServer
                    }

                    break
                }
            }
        }
        else {
            // Trigger `blocklist.didSet` to store right away, so user has something to select.
            blocklist = blocklist
        }
    }

    func fetchServerStatus() async {
        do {
            let (data, _) = try await URLSession.shared.data(for: .init(url: .init(string: "https://status.sr2.uk/index.json")!))

            let status = try JSONDecoder().decode(Status.self, from: data)

            summaryStatus = status.summaryStatus
        }
        catch {
            log.error("Error while checking status: \(error)")
        }
    }
}
