//
//  MenuContentView.swift
//  SwanDesk — the MenuBarExtra dropdown.
//
//  Each profile row connects/disconnects its own tunnel — several can be up at
//  once. Profiles are listed in priority order (the configuration list order):
//  when active tunnels claim overlapping routes or DNS, the one higher in this
//  menu wins.
//

import SwiftUI

struct MenuContentView: View {
    @Bindable var connection: ConnectionManager
    @Bindable var store: ProfileStore
    @Environment(\.openWindow) private var openWindow

    var body: some View {
        // Status line
        Text(connection.stateText)

        Divider()

        if store.profiles.isEmpty {
            Text("No profiles configured")
            Button("Add a Profile…") { openConfig(.connections) }
        } else {
            ForEach(store.profiles) { profile in
                profileButton(profile)
            }
        }

        if connection.hasActiveTunnel {
            Divider()
            Button("Disconnect All") { connection.disconnectAll() }
                .disabled(connection.busy)
        }
        // The escape hatch for a tunnel the helper lost track of ("disconnected"
        // in the UI but charon still running): SIGKILL every charon/dnsmasq and
        // restore routes/DNS/firewall. Deliberately never disabled by `busy`.
        Button("Forcibly Stop & Kill All SwanDesk VPNs") { confirmForceKill() }

        Divider()

        Button("Configuration…") { openConfig(.connections) }
            .keyboardShortcut(",", modifiers: .command)
        Button("Show Log…") { openConfig(.log) }
        Button("About SwanDesk") { AboutPanel.present() }
        Divider()
        Button("Quit SwanDesk") { NSApp.terminate(nil) }
            .keyboardShortcut("q", modifiers: .command)
        Button("Quit SwanDesk & Stop Helper") { connection.quitAndStopHelper() }
            .help("Disconnects every tunnel, terminates the privileged helper daemon, then quits")
    }

    @ViewBuilder
    private func profileButton(_ profile: VPNProfile) -> some View {
        let state = connection.tunnelStatus(for: profile.id)?.state
        Button {
            // An errored profile retries on click (the connect clears the error);
            // disconnect-on-click is for tunnels that are actually up/underway.
            if connection.isActive(profile.id) && state != .error {
                connection.disconnect(profileID: profile.id)
            } else {
                initiateConnect(profile: profile)
            }
        } label: {
            Text(marker(for: state) + profile.name)
        }
        .disabled(connection.busy)
    }

    /// Textual state marker — MenuBarExtra menus render plain menu items, so
    /// state is conveyed in the title.
    private func marker(for state: VPNConnState?) -> String {
        switch state {
        case .connected:                 return "✓ "
        case .connecting, .reconnecting: return "… "
        case .error:                     return "⚠ "
        case .disconnected, nil:         return ""
        }
    }

    private func initiateConnect(profile: VPNProfile) {
        guard let secrets = connection.resolveSecrets(for: profile) else { return }
        connection.connect(profile: profile, secrets: secrets)
    }

    private func confirmForceKill() {
        NSApp.activate(ignoringOtherApps: true)
        let alert = NSAlert()
        alert.alertStyle = .warning
        alert.messageText = "Forcibly stop all SwanDesk VPNs?"
        alert.informativeText = """
            This immediately kills every strongSwan (charon) and dnsmasq process — \
            including strays SwanDesk lost track of — then removes VPN routes, \
            restores DNS and IPv6, and lifts any kill-switch firewall rules. \
            Tunnels are cut without notifying the gateways.
            """
        alert.addButton(withTitle: "Force Stop & Kill")
        alert.addButton(withTitle: "Cancel")
        guard alert.runModal() == .alertFirstButtonReturn else { return }
        connection.forceKillAll()
    }

    private func openConfig(_ tab: ConfigTab) {
        ConfigWindowModel.shared.selectedTab = tab
        NSApp.activate(ignoringOtherApps: true)
        openWindow(id: "config")
    }
}
