import Vapor
import Foundation
import WebKit

@MainActor
final class WebServer: NSObject, ObservableObject, WKNavigationDelegate {

    private var app: Application?

    @Published
    var isRunning = false

    @Published
    var isStarting = false

    @Published
    var port: Int

    @Published
    var webView = WKWebView()

    @Published
    var currentUrl: String = ""

    var isNotReady: Bool {
        isStarting || !isRunning
    }

    init(port: Int) {
        self.port = port
        super.init()

        webView.navigationDelegate = self
    }

    func loadHomeUrl() {
        let url = URL(string: "http://localhost:\(port)/feed")!
        webView.load(URLRequest(url: url))
    }

    func reloadPage() {
        webView.reload()
    }

    func startServer(in directory: String) {
        if let app, !app.didShutdown {
            print("WebServer: Already running")
            return
        }
        guard !isStarting else { return }
        self.isStarting = true

        Task {
            var vaporArgs = CommandLine.arguments
            let allowedCommands = ["serve", "routes"]
            vaporArgs = vaporArgs.filter { allowedCommands.contains($0) || $0 == CommandLine.arguments.first }

            let app = try await Application.make(.detect(arguments: vaporArgs))
            app.logger.logLevel = .warning
            self.app = app

            app.middleware.use(TryFilesMiddleware(publicDirectory: directory))
            app.http.server.configuration.port = 8000

            DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
                self.loadHomeUrl()
                self.isStarting = false
                self.isRunning = true
            }
            print("WebServer: Starting")
            try await app.execute()
            try await app.asyncShutdown()
        }
    }

    func stopServer() {
        guard let app else {
            print("WebServer: Already stopped")
            return
        }
        print("WebServer: Stopping")
        Task {
            do {
                try await app.asyncShutdown()
            } catch {
                print("Failed to stop web server: \(error)")
            }
            DispatchQueue.main.async {
                self.isRunning = false
            }
        }
    }
}

extension WebServer {

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        DispatchQueue.main.async {
            self.currentUrl = webView.url?.absoluteString ?? "Unknown URL"
        }
    }
}
