// LoopFollow
// SettingsMenuView.swift

import SwiftUI
import UIKit

struct SettingsMenuView: View {
    @ObservedObject private var nightscoutURL = Storage.shared.url

    var body: some View {
        List {
            ForEach(SettingsRoute.menuSections(nightscoutConfigured: !nightscoutURL.value.isEmpty), id: \.0) { section, routes in
                Section(section.rawValue) {
                    ForEach(routes) { route in
                        NavigationRow(title: route.title,
                                      icon: route.icon,
                                      value: route)
                    }
                }
            }
        }
        .navigationTitle("Settings")
        .navigationBarTitleDisplayMode(.large)
    }
}

// MARK: – Sheet routing

enum SettingsSection: String, CaseIterable, Hashable {
    case data = "Data Settings"
    case display = "Display Settings"
    case app = "App Settings"
    case alarms = "Alarms"
    case integrations = "Integrations"
    case advanced = "Advanced Settings"
}

/// A single setting inside a settings screen, exposed to Menu search. Leaves
/// are not navigable on their own — a search hit opens the screen
/// (`SettingsRoute`) that contains it.
struct SettingsLeaf: Hashable {
    let title: String
    let keywords: [String]

    init(_ title: String, _ keywords: [String] = []) {
        self.title = title
        self.keywords = keywords
    }
}

enum SettingsRoute: Hashable, Identifiable {
    case settings
    case units
    case nightscout, dexcom
    case backgroundRefresh
    case general, graph
    case tabSettings
    case infoDisplay
    case alarmSettings
    case apn
    #if !targetEnvironment(macCatalyst)
        case liveActivity
    #endif
    case remote
    case importExport
    case calendar, contact
    case advanced
    case aggregatedStats

    var id: Self { self }

    // MARK: – Row presentation (single source of truth)

    /// Title shown in the Settings list and used for search matching.
    /// Non-row cases (`.settings`, `.aggregatedStats`) return "" and are never
    /// included in `menuSections`.
    var title: String {
        switch self {
        case .nightscout: return "Nightscout"
        case .dexcom: return "Dexcom"
        case .general: return "General"
        case .graph: return "Graph"
        case .infoDisplay: return "Information Display"
        case .units: return "Units and Metrics"
        case .tabSettings: return "Tabs"
        case .backgroundRefresh: return "Background Refresh"
        case .importExport: return "Import/Export"
        case .apn: return "APN"
        #if !targetEnvironment(macCatalyst)
            case .liveActivity: return "Live Activity"
        #endif
        case .remote: return "Remote"
        case .alarmSettings: return "Alarms"
        case .calendar: return "Calendar"
        case .contact: return "Contact"
        case .advanced: return "Advanced"
        case .settings, .aggregatedStats: return ""
        }
    }

    var icon: String {
        switch self {
        case .nightscout: return "network"
        case .dexcom: return "sensor.tag.radiowaves.forward"
        case .general: return "gearshape"
        case .graph: return "chart.xyaxis.line"
        case .infoDisplay: return "info.circle"
        case .units: return "scalemass"
        case .tabSettings: return "rectangle.3.group"
        case .backgroundRefresh: return "arrow.clockwise"
        case .importExport: return "square.and.arrow.down"
        case .apn: return "bell.and.waves.left.and.right"
        #if !targetEnvironment(macCatalyst)
            case .liveActivity: return "dot.radiowaves.left.and.right"
        #endif
        case .remote: return "antenna.radiowaves.left.and.right"
        case .alarmSettings: return "bell.badge"
        case .calendar: return "calendar"
        case .contact: return "person.circle"
        case .advanced: return "exclamationmark.shield"
        case .settings, .aggregatedStats: return ""
        }
    }

    /// Extra synonyms so search finds a page by related terms, not just its title.
    var keywords: [String] {
        switch self {
        case .graph: return ["chart"]
        case .units: return ["mmol", "mgdl", "metrics"]
        case .infoDisplay: return ["info"]
        case .apn: return ["push", "notification"]
        #if !targetEnvironment(macCatalyst)
            case .liveActivity: return ["dynamic island", "lock screen"]
        #endif
        case .importExport: return ["import", "export", "backup"]
        default: return []
        }
    }

    /// The individual settings inside this screen, so Menu search can find a
    /// bottom-level setting (e.g. "Graph Basal") and open the screen containing
    /// it. Titles mirror the row (or section) titles in each screen's view —
    /// keep them in sync when adding or renaming rows.
    var leaves: [SettingsLeaf] {
        switch self {
        case .nightscout: return [
                SettingsLeaf("URL"),
                SettingsLeaf("Access Token", ["token"]),
                SettingsLeaf("Enable WebSocket", ["websocket", "real-time"]),
            ]
        case .dexcom: return [
                SettingsLeaf("User Name", ["username"]),
                SettingsLeaf("Password"),
                SettingsLeaf("Server"),
            ]
        case .general: return [
                SettingsLeaf("Display App Badge", ["badge"]),
                SettingsLeaf("Persistent Notification"),
                SettingsLeaf("Appearance", ["dark mode", "light mode", "theme"]),
                SettingsLeaf("Display Stats"),
                SettingsLeaf("Display Small Graph"),
                SettingsLeaf("Color BG Text"),
                SettingsLeaf("Keep Screen Active", ["screen lock", "screenlock"]),
                SettingsLeaf("Show Display Name"),
                SettingsLeaf("Snoozer emoji"),
                SettingsLeaf("Force portrait mode", ["orientation", "landscape"]),
                SettingsLeaf("Time Zone Override", ["timezone"]),
                SettingsLeaf("Speak BG", ["voice", "speech"]),
                SettingsLeaf("Send anonymous usage stats", ["telemetry", "diagnostics"]),
            ]
        case .graph: return [
                SettingsLeaf("Display Dots"),
                SettingsLeaf("Display Lines"),
                SettingsLeaf("Show DIA Lines", ["dia"]),
                SettingsLeaf("Show −30 min Line", ["-30"]),
                SettingsLeaf("Show −90 min Line", ["-90"]),
                SettingsLeaf("Show Yesterday's BG", ["yesterday"]),
                SettingsLeaf("Show Midnight Lines"),
                SettingsLeaf("Show Carb/Bolus Values", ["carbs"]),
                SettingsLeaf("Show Carb Absorption"),
                SettingsLeaf("Treatments on Small Graph"),
                SettingsLeaf("Small Graph Height", ["height"]),
                SettingsLeaf("Hours of Prediction", ["prediction"]),
                SettingsLeaf("Prediction Style"),
                SettingsLeaf("Min Basal", ["basal scale"]),
                SettingsLeaf("Min BG Scale"),
                SettingsLeaf("Show Days Back", ["history", "days back"]),
            ]
        case .infoDisplay:
            return [SettingsLeaf("Hide Information Table")]
                + InfoType.allCases.map { SettingsLeaf($0.name) }
        case .units: return [
                SettingsLeaf("Glucose Unit"),
                SettingsLeaf("Range Mode", ["tir", "titr", "time in range"]),
                SettingsLeaf("Glycemic Metrics", ["hba1c", "ehba1c", "gmi"]),
                SettingsLeaf("Variability", ["standard deviation", "cv"]),
            ]
        case .backgroundRefresh: return [
                SettingsLeaf("Background Refresh Type", ["silent tune", "bluetooth", "rileylink", "omnipod", "heartbeat"]),
            ]
        case .importExport: return [
                SettingsLeaf("Scan QR Code to Import Settings", ["qr"]),
                SettingsLeaf("Export Settings To QR Code", ["qr"]),
            ]
        case .apn: return [
                SettingsLeaf("APNS Key ID", ["apns"]),
                SettingsLeaf("APNS Key", ["apns", "p8"]),
            ]
        #if !targetEnvironment(macCatalyst)
            case .liveActivity: return [
                    SettingsLeaf("Enable Live Activity"),
                    SettingsLeaf("Restart Live Activity"),
                    SettingsLeaf("Grid Slots", ["carplay", "watch"]),
                ]
        #endif
        case .remote: return [
                SettingsLeaf("Loop Remote Control"),
                SettingsLeaf("Trio Remote Control", ["trc"]),
                SettingsLeaf("Meal with Bolus"),
                SettingsLeaf("Meal with Fat/Protein"),
                SettingsLeaf("Guardrails", ["max bolus", "max carbs", "max fat", "max protein"]),
                SettingsLeaf("Bolus Increment"),
                SettingsLeaf("Shared Secret"),
                SettingsLeaf("QR Code URL", ["qr"]),
            ]
        case .alarmSettings: return [
                SettingsLeaf("All Alerts Snoozed", ["snooze all"]),
                SettingsLeaf("All Sounds Muted", ["mute all"]),
                SettingsLeaf("Day starts", ["schedule", "day/night"]),
                SettingsLeaf("Night starts", ["schedule", "day/night"]),
                SettingsLeaf("Override System Volume", ["volume"]),
                SettingsLeaf("Audio During Calls"),
                SettingsLeaf("Ignore Zero BG"),
                SettingsLeaf("Auto-Snooze CGM Start", ["autosnooze"]),
                SettingsLeaf("Volume Buttons Snooze Alarms"),
            ]
        case .calendar: return [
                SettingsLeaf("Save BG to Calendar", ["watch", "carplay"]),
                SettingsLeaf("Calendar Text"),
            ]
        case .contact: return [
                SettingsLeaf("Enable Contact BG Updates", ["watch face"]),
                SettingsLeaf("Background Color"),
                SettingsLeaf("Color Mode"),
                SettingsLeaf("Text Color"),
                SettingsLeaf("Show Trend"),
                SettingsLeaf("Show Delta"),
                SettingsLeaf("Show IOB"),
            ]
        case .advanced: return [
                SettingsLeaf("Download Treatments"),
                SettingsLeaf("Download Prediction"),
                SettingsLeaf("Graph Basal"),
                SettingsLeaf("Graph Bolus"),
                SettingsLeaf("Graph Carbs"),
                SettingsLeaf("Graph Other Treatments"),
                SettingsLeaf("BG Update Delay", ["delay"]),
                SettingsLeaf("Debug Log Level", ["logging"]),
            ]
        case .tabSettings, .settings, .aggregatedStats: return []
        }
    }

    /// Ordered, grouped list of the routes shown as rows in the Settings menu.
    /// Encodes the conditional visibility in one place so both the list and the
    /// Menu search stay in sync.
    static func menuSections(nightscoutConfigured: Bool) -> [(SettingsSection, [SettingsRoute])] {
        var display: [SettingsRoute] = [.general, .graph]
        if nightscoutConfigured {
            display.append(.infoDisplay)
        }
        display += [.units, .tabSettings]

        var app: [SettingsRoute] = [.backgroundRefresh, .importExport, .apn]
        #if !targetEnvironment(macCatalyst)
            app.append(.liveActivity)
        #endif
        if nightscoutConfigured {
            app.append(.remote)
        }

        return [
            (.data, [.nightscout, .dexcom]),
            (.display, display),
            (.app, app),
            (.alarms, [.alarmSettings]),
            (.integrations, [.calendar, .contact]),
            (.advanced, [.advanced]),
        ]
    }

    @ViewBuilder
    var destination: some View {
        switch self {
        case .settings: SettingsMenuView()
        case .units: UnitsSettingsView()
        case .nightscout: NightscoutSettingsView(viewModel: .init())
        case .dexcom: DexcomSettingsView(viewModel: .init())
        case .backgroundRefresh: BackgroundRefreshSettingsView(viewModel: .init())
        case .general: GeneralSettingsView()
        case .graph: GraphSettingsView()
        case .tabSettings: TabCustomizationModal()
        case .infoDisplay: InfoDisplaySettingsView(viewModel: .init())
        case .alarmSettings: AlarmSettingsView()
        case .apn: APNSettingsView()
        #if !targetEnvironment(macCatalyst)
            case .liveActivity: LiveActivitySettingsView()
        #endif
        case .remote: RemoteSettingsView(viewModel: .init())
        case .importExport: ImportExportSettingsView()
        case .calendar: CalendarSettingsView()
        case .contact: ContactSettingsView(viewModel: .init())
        case .advanced: AdvancedSettingsView(viewModel: .init())
        case .aggregatedStats:
            AggregatedStatsViewWrapper()
        }
    }
}

// Helper view to access MainViewController
struct AggregatedStatsViewWrapper: View {
    @State private var mainViewController: MainViewController?

    var body: some View {
        Group {
            if let mainVC = mainViewController {
                AggregatedStatsContentView(mainViewController: mainVC)
            } else {
                Text("Loading stats...")
                    .onAppear {
                        mainViewController = getMainViewController()
                    }
            }
        }
    }

    private func getMainViewController() -> MainViewController? {
        MainViewController.shared
    }
}

// MARK: – UIKit helpers (unchanged)

extension UIApplication {
    var topMost: UIViewController? {
        // `keyWindow` is deprecated and returns nil on Mac Catalyst / multi-window iPad.
        // Walk connected scenes instead and prefer the foreground-active one.
        let windowScenes = connectedScenes.compactMap { $0 as? UIWindowScene }
        let activeScene = windowScenes.first { $0.activationState == .foregroundActive }
            ?? windowScenes.first
        let rootVC = activeScene?.windows.first(where: \.isKeyWindow)?.rootViewController
            ?? activeScene?.windows.first?.rootViewController
        guard var top = rootVC else { return nil }
        while let presented = top.presentedViewController {
            top = presented
        }
        return top
    }
}

extension UIViewController {
    func presentSimpleAlert(title: String, message: String) {
        let a = UIAlertController(title: title,
                                  message: message,
                                  preferredStyle: .alert)
        a.addAction(UIAlertAction(title: String(localized: "OK"), style: .default))
        present(a, animated: true)
    }
}
