import CoreData
import Foundation
import LoopKit
import SwiftUI
import Swinject

extension SettingsExport {
    final class StateModel: BaseStateModel<Provider> {
        @Injected() private var broadcaster: Broadcaster!
        @Injected() private var fileManager: FileManager!
        @Injected() private var storage: FileStorage!
        @Injected() var overrideStorage: OverrideStorage!
        @Injected() var tempTargetsStorage: TempTargetsStorage!

        // Help Sheet
        var isHelpSheetPresented: Bool = false
        var helpSheetDetent = PresentationDetent.large

        // Version information
        private var versionNumber: String = ""
        private var buildNumber: String = ""
        private var branch: String = ""

        let viewContext = CoreDataStack.shared.persistentContainer.viewContext

        override func subscribe() {
            versionNumber = Bundle.main.appDevVersion ?? "Unknown"
            buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "Unknown"
            branch = BuildDetails.shared.branchAndSha
        }

        // Export categories for selective export
        enum ExportCategory: String, CaseIterable, Identifiable {
            var id: String { rawValue }

            case metadata = "Metadata"
            case devices = "Devices"
            case therapy = "Therapy"
            case algorithm = "Algorithm"
            case features = "Features"
            case notifications = "Notifications"
            case services = "Services"
            case tempTargetPresets = "Temp Target Presets"
            case overridePresets = "Override Presets"
            case mealPresets = "Meal Presets"
        }

        // Published state for UI binding
        @Published var selectedCategories: Set<ExportCategory> = Set(ExportCategory.allCases)
        @Published var isExporting: Bool = false

        enum ExportError: LocalizedError {
            case documentsDirectoryNotFound
            case fileWriteError(Error)
            case unknown(String)

            var errorDescription: String? {
                switch self {
                case .documentsDirectoryNotFound:
                    return String(localized: "Could not access documents directory")
                case let .fileWriteError(error):
                    return String(localized: "Failed to write export file: \(error.localizedDescription)")
                case let .unknown(message):
                    return String(localized: "Export failed: \(message)")
                }
            }
        }

        /// Exports selected Trio settings to a CSV file
        ///
        /// This function creates an export of the user's selected Trio configuration categories including:
        /// - Export metadata (date, app version, build) [optional]
        /// - Device settings (CGM, pump information) [optional]
        /// - Therapy profiles (basal rates, ISF, carb ratios, targets) [optional]
        /// - Algorithm settings (SMB, autosens, dynamic settings, etc.) [optional]
        /// - Features and UI preferences [optional]
        /// - Notification settings [optional]
        /// - Service configurations [optional]
        /// - Preset data [optional]
        ///
        /// - Parameter categories: Set of categories to include in export. If nil, exports all categories.
        /// - Parameter format: Export format to use. If nil, uses currently selected format.
        /// - Returns: A Result containing either the file URL on success or an ExportError on failure
        func exportSettings(
            categories: Set<ExportCategory>? = nil
        ) async -> Result<URL, ExportError> {
            debug(.default, "🔄 EXPORT: Starting settings export...")

            await MainActor.run { isExporting = true }

            defer { Task { @MainActor in isExporting = false } }

            let categoriesToExport = categories ?? selectedCategories
            debug(
                .default,
                "🔄 EXPORT: Exporting categories: \(categoriesToExport.map(\.rawValue).joined(separator: ", ")) in .CSV format"
            )

            let formatter = DateFormatter()
            formatter.dateFormat = "yyyyMMdd_HHmmss"
            let timestamp = formatter.string(from: Date())
            let fileName = "TrioSettings_\(timestamp).csv"

            // Use the Documents directory for better sharing compatibility
            guard let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
                return .failure(.documentsDirectoryNotFound)
            }
            let fileURL = documentsDirectory.appendingPathComponent(fileName)
            debug(.default, "Export file path: \(fileURL.path)")

            var exportSettings: [ExportSetting] = []

            let trioSettings = settingsManager.settings
            let preferences = settingsManager.preferences
            debug(.default, "🔄 EXPORT: Settings managers initialized")

            // Helper function to add a setting
            func addSetting(category: String, subcategory: String = "", name: String, value: String, unit: String = "") {
                exportSettings.append(ExportSetting(
                    category: category,
                    subcategory: subcategory,
                    name: name,
                    value: value,
                    unit: unit
                ))
            }

            // Export metadata - always include basic export info
            if categoriesToExport.contains(.metadata) {
                let exportCategory = String(localized: "Metadata")
                addSetting(
                    category: exportCategory,
                    name: String(localized: "Export Date"),
                    value: DateFormatter.localizedString(from: Date(), dateStyle: .medium, timeStyle: .medium)
                )
                addSetting(category: exportCategory, name: String(localized: "App Version"), value: versionNumber)
                addSetting(category: exportCategory, name: String(localized: "Build Number"), value: buildNumber)
                addSetting(category: exportCategory, name: String(localized: "Branch"), value: branch)
            }

            // Devices
            if categoriesToExport.contains(.devices) {
                let devicesCategory = String(localized: "Devices", comment: "Devices menu item in the Settings main view.")
                addSetting(category: devicesCategory, name: String(localized: "CGM"), value: trioSettings.cgm.rawValue)
                addSetting(
                    category: devicesCategory,
                    name: String(localized: "Smooth Glucose Value"),
                    value: trioSettings.smoothGlucose ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                // Pump Information
                if let pumpManager = provider.deviceManager.pumpManager {
                    addSetting(category: devicesCategory, name: String(localized: "Pump Type"), value: pumpManager.localizedTitle)

                    // Get insulin type from pump manager if available, otherwise from preferences
                    let insulinTypeValue: String
                    if let pumpManager = provider.deviceManager.pumpManager,
                       let insulinType = pumpManager.status.insulinType
                    {
                        insulinTypeValue = insulinType.title
                    } else {
                        insulinTypeValue = preferences.curve.rawValue
                        // technically, this gets set only when a pump is onboared
                        // leaving this here as a backup, because you theoretically could
                        // have removed your PM instance, but are just within pumps and
                        // insulin type stays the same.
                        // however, this theoretically could be a stale type.
                    }
                    addSetting(
                        category: devicesCategory,
                        name: String(localized: "Insulin Type"),
                        value: insulinTypeValue
                    )
                } else {
                    addSetting(
                        category: devicesCategory,
                        name: String(localized: "Pump Type"),
                        value: String(localized: "Not Connected")
                    )
                }
            }

            // Therapy Settings
            if categoriesToExport.contains(.therapy) {
                let therapyCategory = String(localized: "Therapy", comment: "Therapy menu item in the Settings main view.")

                // Units and Limits subcategory
                let unitsLimitsSubcategory = String(localized: "Units and Limits")
                addSetting(
                    category: therapyCategory,
                    subcategory: unitsLimitsSubcategory,
                    name: String(localized: "Glucose Units"),
                    value: trioSettings.units.rawValue
                )
                addSetting(
                    category: therapyCategory,
                    subcategory: unitsLimitsSubcategory,
                    name: String(localized: "Maximum Insulin on Board (IOB)"),
                    value: String(describing: preferences.maxIOB),
                    unit: "U"
                )

                // Add missing pump settings from PumpSettings
                let pumpSettings = settingsManager.pumpSettings
                addSetting(
                    category: therapyCategory,
                    subcategory: unitsLimitsSubcategory,
                    name: String(localized: "Maximum Bolus"),
                    value: String(describing: pumpSettings.maxBolus),
                    unit: "U"
                )
                addSetting(
                    category: therapyCategory,
                    subcategory: unitsLimitsSubcategory,
                    name: String(localized: "Maximum Basal Rate"),
                    value: String(describing: pumpSettings.maxBasal),
                    unit: String(localized: "U/hr", comment: "Insulin unit per hour abbreviation")
                )
                addSetting(
                    category: therapyCategory,
                    subcategory: unitsLimitsSubcategory,
                    name: String(localized: "Maximum Carbs on Board (COB)"),
                    value: String(describing: preferences.maxCOB),
                    unit: String(localized: "g", comment: "Units for carbs")
                )
                addSetting(
                    category: therapyCategory,
                    subcategory: unitsLimitsSubcategory,
                    name: String(localized: "Minimum Safety Threshold"),
                    value: trioSettings
                        .units == .mgdL ? String(describing: preferences.threshold_setting) :
                        String(describing: preferences.threshold_setting.asMmolL),
                    unit: trioSettings.units.rawValue
                )

                // Get therapy profiles from storage
                let basalProfile = storage.retrieve(OpenAPS.Settings.basalProfile, as: [BasalProfileEntry].self) ?? []
                let isfProfileContainer = storage.retrieve(OpenAPS.Settings.insulinSensitivities, as: InsulinSensitivities.self)
                let crProfileContainer = storage.retrieve(OpenAPS.Settings.carbRatios, as: CarbRatios.self)
                let targetProfileContainer = storage.retrieve(OpenAPS.Settings.bgTargets, as: BGTargets.self)

                // Glucose Targets subcategory
                let glucoseTargetsSubcategory = String(localized: "Glucose Targets")
                if let targetContainer = targetProfileContainer {
                    for entry in targetContainer.targets {
                        // Export single target value since high==low in Trio
                        let targetValue = trioSettings.units == .mgdL ? entry.low : entry.low.asMmolL
                        addSetting(
                            category: therapyCategory,
                            subcategory: glucoseTargetsSubcategory,
                            name: String(localized: "Target (\(entry.start.formattedHourMinuteFromTimeString()))"),
                            value: String(describing: targetValue),
                            unit: trioSettings.units.rawValue
                        )
                    }
                }

                // Basal Rates subcategory
                let basalRatesSubcategory = String(localized: "Basal Rates")
                for entry in basalProfile {
                    addSetting(
                        category: therapyCategory,
                        subcategory: basalRatesSubcategory,
                        name: String(localized: "Basal Rate (\(entry.start.formattedHourMinuteFromTimeString()))"),
                        value: String(describing: entry.rate),
                        unit: String(localized: "U/hr", comment: "Insulin unit per hour abbreviation")
                    )
                }

                // Carb Ratios subcategory
                let carbRatiosSubcategory = String(localized: "Carb Ratios")
                if let crContainer = crProfileContainer {
                    for entry in crContainer.schedule {
                        addSetting(
                            category: therapyCategory,
                            subcategory: carbRatiosSubcategory,
                            name: String(localized: "Carb Ratio (\(entry.start.formattedHourMinuteFromTimeString()))"),
                            value: String(describing: entry.ratio),
                            unit: String(localized: "g/U")
                        )
                    }
                }

                // Insulin Sensitivities subcategory
                let insulinSensitivitiesSubcategory = String(localized: "Insulin Sensitivities")
                if let isfContainer = isfProfileContainer {
                    for entry in isfContainer.sensitivities {
                        let isfValue = trioSettings.units == .mgdL ? entry.sensitivity : entry.sensitivity.asMmolL
                        addSetting(
                            category: therapyCategory,
                            subcategory: insulinSensitivitiesSubcategory,
                            name: String(localized: "ISF (\(entry.start.formattedHourMinuteFromTimeString()))"),
                            value: String(describing: isfValue),
                            unit: trioSettings.units.rawValue
                        )
                    }
                }
            }

            // Algorithm Settings
            if categoriesToExport.contains(.algorithm) {
                let algorithmCategory = String(localized: "Algorithm", comment: "Algorithm menu item in the Settings main view.")
                let pumpSettings = settingsManager.pumpSettings

                // Autosens Settings
                let autosensSubcategory = String(localized: "Autosens")
                addSetting(
                    category: algorithmCategory,
                    subcategory: autosensSubcategory,
                    name: String(localized: "Autosens Max"),
                    value: String(format: "%.0f", (preferences.autosensMax as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: autosensSubcategory,
                    name: String(localized: "Autosens Min"),
                    value: String(format: "%.0f", (preferences.autosensMin as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: autosensSubcategory,
                    name: String(localized: "Rewind Resets Autosens"),
                    value: preferences.rewindResetsAutosens ? String(localized: "Enabled") : String(localized: "Disabled")
                )

                // SMB Settings
                let smbSubcategory = String(localized: "SMB")
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Enable SMB Always"),
                    value: preferences.enableSMBAlways ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Enable SMB With COB"),
                    value: preferences.enableSMBWithCOB ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Enable SMB With Temptarget"),
                    value: preferences.enableSMBWithTemptarget ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Enable SMB After Carbs"),
                    value: preferences.enableSMBAfterCarbs ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Enable SMB With High Glucose"),
                    value: preferences.enableSMB_high_bg ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                if preferences.enableSMB_high_bg {
                    addSetting(
                        category: algorithmCategory,
                        subcategory: smbSubcategory,
                        name: String(localized: "High Glucose Target"),
                        value: trioSettings
                            .units == .mgdL ? String(describing: preferences.enableSMB_high_bg_target) :
                            String(describing: preferences.enableSMB_high_bg_target.asMmolL),
                        unit: trioSettings.units.rawValue
                    )
                }
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Allow SMB With High Temptarget"),
                    value: preferences.allowSMBWithHighTemptarget ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Enable UAM"),
                    value: preferences.enableUAM ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Max SMB Basal Minutes"),
                    value: String(describing: preferences.maxSMBBasalMinutes),
                    unit: String(localized: "minutes")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Max UAM Basal Minutes"),
                    value: String(describing: preferences.maxUAMSMBBasalMinutes),
                    unit: String(localized: "minutes")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: smbSubcategory,
                    name: String(localized: "Max Allowed Glucose Rise for SMB"),
                    value: String(format: "%.0f", (preferences.maxDeltaBGthreshold as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )

                // Dynamic Settings
                let dynamicSubcategory = String(localized: "Dynamic Settings")

                // Proper Dynamic ISF handling using the current enum logic
                let dynamicISFValue: String
                if !preferences.useNewFormula {
                    dynamicISFValue = String(localized: "Disabled")
                } else if preferences.sigmoid {
                    dynamicISFValue = String(localized: "Sigmoid")
                } else {
                    dynamicISFValue = String(localized: "Logarithmic")
                }
                addSetting(
                    category: algorithmCategory,
                    subcategory: dynamicSubcategory,
                    name: String(localized: "Dynamic ISF"),
                    value: dynamicISFValue
                )

                // Show adjustment factors as percentages with proper labels
                if preferences.useNewFormula {
                    if !preferences.sigmoid {
                        addSetting(
                            category: algorithmCategory,
                            subcategory: dynamicSubcategory,
                            name: String(localized: "Adjustment Factor (AF)"),
                            value: String(format: "%.0f", (preferences.adjustmentFactor as NSDecimalNumber).doubleValue * 100),
                            unit: "%"
                        )
                    } else {
                        addSetting(
                            category: algorithmCategory,
                            subcategory: dynamicSubcategory,
                            name: String(localized: "Sigmoid Adjustment Factor"),
                            value: String(
                                format: "%.0f",
                                (preferences.adjustmentFactorSigmoid as NSDecimalNumber).doubleValue * 100
                            ),
                            unit: "%"
                        )
                    }
                }

                // Weighted Average of TDD is shown for both logarithmic and sigmoid when Dynamic ISF is enabled
                addSetting(
                    category: algorithmCategory,
                    subcategory: dynamicSubcategory,
                    name: String(localized: "Weighted Average of TDD"),
                    value: String(format: "%.0f", (preferences.weightPercentage as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: dynamicSubcategory,
                    name: String(localized: "Adjust Basal"),
                    value: preferences.tddAdjBasal ? String(localized: "Enabled") : String(localized: "Disabled")
                )

                // Target Behavior
                let targetBehaviorSubcategory = String(localized: "Target Behavior")
                addSetting(
                    category: algorithmCategory,
                    subcategory: targetBehaviorSubcategory,
                    name: String(localized: "High Temptarget Raises Sensitivity"),
                    value: preferences
                        .highTemptargetRaisesSensitivity ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: targetBehaviorSubcategory,
                    name: String(localized: "Low Temptarget Lowers Sensitivity"),
                    value: preferences
                        .lowTemptargetLowersSensitivity ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: targetBehaviorSubcategory,
                    name: String(localized: "Sensitivity Raises Target"),
                    value: preferences.sensitivityRaisesTarget ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: targetBehaviorSubcategory,
                    name: String(localized: "Resistance Lowers Target"),
                    value: preferences.resistanceLowersTarget ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: targetBehaviorSubcategory,
                    name: String(localized: "Half Basal Exercise Target"),
                    value: trioSettings
                        .units == .mgdL ? String(describing: preferences.halfBasalExerciseTarget) :
                        String(describing: preferences.halfBasalExerciseTarget.asMmolL),
                    unit: trioSettings.units.rawValue
                )

                // Additional Algorithm Settings
                let additionalsSubcategory = String(localized: "Additionals")

                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Max Daily Safety Multiplier"),
                    value: String(format: "%.0f", (preferences.maxDailySafetyMultiplier as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Current Basal Safety Multiplier"),
                    value: String(
                        format: "%.0f",
                        (preferences.currentBasalSafetyMultiplier as NSDecimalNumber).doubleValue * 100
                    ),
                    unit: "%"
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Use Custom Peak Time"),
                    value: preferences.useCustomPeakTime ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Duration of Insulin Action"),
                    value: String(describing: pumpSettings.insulinActionCurve),
                    unit: String(localized: "hours")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Insulin Peak Time"),
                    value: String(describing: preferences.insulinPeakTime),
                    unit: String(localized: "minutes")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Skip Neutral Temps"),
                    value: preferences.skipNeutralTemps ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Unsuspend If No Temp"),
                    value: preferences.unsuspendIfNoTemp ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Suspend Zeros IOB"),
                    value: preferences.suspendZerosIOB ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                // SMB settings that belong in Additionals (correct order based on UI)
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "SMB Delivery Ratio"),
                    value: String(format: "%.0f", (preferences.smbDeliveryRatio as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "SMB Interval"),
                    value: String(describing: preferences.smbInterval),
                    unit: String(localized: "minutes")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Min 5m Carb Impact"),
                    value: trioSettings
                        .units == .mgdL ? String(describing: preferences.min5mCarbimpact) :
                        String(describing: preferences.min5mCarbimpact.asMmolL),
                    unit: trioSettings.units.rawValue
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Remaining Carbs Percentage"),
                    value: String(format: "%.0f", (preferences.remainingCarbsFraction as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Remaining Carbs Cap"),
                    value: String(describing: preferences.remainingCarbsCap),
                    unit: String(localized: "g", comment: "Units for carbs")
                )
                addSetting(
                    category: algorithmCategory,
                    subcategory: additionalsSubcategory,
                    name: String(localized: "Noisy CGM Target Increase"),
                    value: String(format: "%.0f", (preferences.noisyCGMTargetMultiplier as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )
            }

            // Features
            if categoriesToExport.contains(.features) {
                let featuresCategory = String(localized: "Features", comment: "Features menu item in the Settings main view.")

                // Trio Features subcategory - Treatments (Bolus Calculator, Quick-Pick Boluses, Meal Settings)
                let treatmentsSubcategory = String(localized: "Treatments")
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Display Meal Presets"),
                    value: trioSettings.displayPresets ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Recommended Bolus Percentage"),
                    value: String(format: "%.0f", (trioSettings.overrideFactor as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Enable Reduced Bolus Option"),
                    value: trioSettings.fattyMeals ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                if trioSettings.fattyMeals {
                    addSetting(
                        category: featuresCategory,
                        subcategory: treatmentsSubcategory,
                        name: String(localized: "Reduced Bolus Percentage"),
                        value: String(format: "%.0f", (trioSettings.fattyMealFactor as NSDecimalNumber).doubleValue * 100),
                        unit: "%"
                    )
                }
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Enable Super Bolus Option"),
                    value: trioSettings.sweetMeals ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                if trioSettings.sweetMeals {
                    addSetting(
                        category: featuresCategory,
                        subcategory: treatmentsSubcategory,
                        name: String(localized: "Super Bolus Percentage"),
                        value: String(format: "%.0f", (trioSettings.sweetMealFactor as NSDecimalNumber).doubleValue * 100),
                        unit: "%"
                    )
                }
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Very Low Glucose Warning"),
                    value: trioSettings.confirmBolus ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Enable Quick-Pick Boluses"),
                    value: trioSettings.enableQuickBolus ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Max Carbs"),
                    value: String(describing: trioSettings.maxCarbs),
                    unit: String(localized: "g", comment: "Units for carbs")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Max Fat"),
                    value: String(describing: trioSettings.maxFat),
                    unit: String(localized: "g", comment: "Units for carbs")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Max Protein"),
                    value: String(describing: trioSettings.maxProtein),
                    unit: String(localized: "g", comment: "Units for carbs")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Max Meal Absorption Time"),
                    value: String(describing: preferences.maxMealAbsorptionTime),
                    unit: String(localized: "hours")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Enable Fat and Protein Entries"),
                    value: trioSettings.useFPUconversion ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Fat and Protein Delay"),
                    value: String(describing: trioSettings.delay),
                    unit: String(localized: "minutes")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Spread Interval"),
                    value: String(describing: trioSettings.minuteInterval),
                    unit: String(localized: "minutes")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: treatmentsSubcategory,
                    name: String(localized: "Fat and Protein Percentage"),
                    value: String(format: "%.0f", (trioSettings.individualAdjustmentFactor as NSDecimalNumber).doubleValue * 100),
                    unit: "%"
                )

                // Trio Features subcategory - Shortcuts
                let shortcutsSubcategory = String(localized: "Shortcuts")
                addSetting(
                    category: featuresCategory,
                    subcategory: shortcutsSubcategory,
                    name: String(localized: "Allow Bolusing with Shortcuts"),
                    value: trioSettings
                        .bolusShortcut != .notAllowed ? String(localized: "Enabled") : String(localized: "Disabled")
                )

                // Trio Features subcategory - Remote Control
                let remoteControlSubcategory = String(localized: "Remote Control")
                let isRemoteControlEnabled = UserDefaults.standard.bool(forKey: "isTrioRemoteControlEnabled")
                addSetting(
                    category: featuresCategory,
                    subcategory: remoteControlSubcategory,
                    name: String(localized: "Enable Remote Control"),
                    value: isRemoteControlEnabled ? String(localized: "Enabled") : String(localized: "Disabled")
                )

                // Trio Personalization subcategory - User Interface
                let userInterfaceSubcategory = String(localized: "User Interface")
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Show X-Axis Grid Lines"),
                    value: trioSettings.xGridLines ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Show Y-Axis Grid Lines"),
                    value: trioSettings.yGridLines ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Show Low and High Thresholds"),
                    value: trioSettings.rulerMarks ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Low Threshold"),
                    value: trioSettings
                        .units == .mgdL ? String(describing: trioSettings.low) : String(describing: trioSettings.low.asMmolL),
                    unit: trioSettings.units.rawValue
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "High Threshold"),
                    value: trioSettings
                        .units == .mgdL ? String(describing: trioSettings.high) : String(describing: trioSettings.high.asMmolL),
                    unit: trioSettings.units.rawValue
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "eA1c/GMI Display Unit"),
                    value: trioSettings.eA1cDisplayUnit.rawValue
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Show Carbs Required Badge"),
                    value: trioSettings.showCarbsRequiredBadge ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Carbs Required Threshold"),
                    value: String(describing: trioSettings.carbsRequiredThreshold),
                    unit: String(localized: "g", comment: "Units for carbs")
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Forecast Display Type"),
                    value: trioSettings.forecastDisplayType.rawValue
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Glucose Color Scheme"),
                    value: trioSettings.glucoseColorScheme.rawValue
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Time in Range Type"),
                    value: trioSettings.timeInRangeType.rawValue
                )
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Require Adjustments Confirmation"),
                    value: trioSettings
                        .requireAdjustmentsConfirmation ? String(localized: "Enabled") : String(localized: "Disabled")
                )

                // Appearance setting from UserDefaults
                let colorSchemePreference = UserDefaults.standard.string(forKey: "colorSchemePreference") ?? "systemDefault"
                let appearanceValue: String
                switch colorSchemePreference {
                case "systemDefault":
                    appearanceValue = String(localized: "System Default")
                case "light":
                    appearanceValue = String(localized: "Light")
                case "dark":
                    appearanceValue = String(localized: "Dark")
                default:
                    appearanceValue = String(localized: "System Default")
                }
                addSetting(
                    category: featuresCategory,
                    subcategory: userInterfaceSubcategory,
                    name: String(localized: "Appearance"),
                    value: appearanceValue
                )
            }

            // Notifications
            if categoriesToExport.contains(.notifications) {
                let notificationsCategory = String(
                    localized: "Notifications",
                    comment: "Notifications menu item in the Settings main view."
                )

                // Trio Notifications subcategory
                let trioNotificationsSubcategory = String(localized: "Trio Notifications")
                addSetting(
                    category: notificationsCategory,
                    subcategory: trioNotificationsSubcategory,
                    name: String(localized: "Show Glucose App Badge"),
                    value: trioSettings.glucoseBadge ? String(localized: "Enabled") : String(localized: "Disabled")
                )

                // Live Activity subcategory
                let liveActivitySubcategory = String(localized: "Live Activity")
                addSetting(
                    category: notificationsCategory,
                    subcategory: liveActivitySubcategory,
                    name: String(localized: "Enable Live Activity"),
                    value: trioSettings.useLiveActivity ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: notificationsCategory,
                    subcategory: liveActivitySubcategory,
                    name: String(localized: "Lock Screen Widget Style"),
                    value: trioSettings.lockScreenView.rawValue
                )
                addSetting(
                    category: notificationsCategory,
                    subcategory: liveActivitySubcategory,
                    name: String(localized: "Display Glucose Forecasts"),
                    value: trioSettings.displayGlucoseForecasts ? String(localized: "Enabled") : String(localized: "Disabled")
                )
            }

            // Services
            if categoriesToExport.contains(.services) {
                let servicesCategory = String(localized: "Services", comment: "Services menu item in the Settings main view.")

                // Nightscout subcategory
                let nightscoutSubcategory = String(localized: "Nightscout")
                addSetting(
                    category: servicesCategory,
                    subcategory: nightscoutSubcategory,
                    name: String(localized: "Allow Uploading to Nightscout"),
                    value: trioSettings.isUploadEnabled ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: servicesCategory,
                    subcategory: nightscoutSubcategory,
                    name: String(localized: "Upload Glucose"),
                    value: trioSettings.uploadGlucose ? String(localized: "Enabled") : String(localized: "Disabled")
                )
                addSetting(
                    category: servicesCategory,
                    subcategory: nightscoutSubcategory,
                    name: String(localized: "Allow Fetching From Nightscout"),
                    value: trioSettings.isDownloadEnabled ? String(localized: "Enabled") : String(localized: "Disabled")
                )

                // Apple Health subcategory
                let appleHealthSubcategory = String(localized: "Apple Health")
                addSetting(
                    category: servicesCategory,
                    subcategory: appleHealthSubcategory,
                    name: String(localized: "Apple Health"),
                    value: trioSettings.useAppleHealth ? String(localized: "Enabled") : String(localized: "Disabled")
                )
            }

            // Temp Target Presets
            if categoriesToExport.contains(.tempTargetPresets) {
                let category = String(localized: "Temp Target Presets")
                debug(.default, "🔄 EXPORT: Fetching temp target presets...")

                let tempTargetPresetIDs = (try? await tempTargetsStorage.fetchForTempTargetPresets()) ?? []
                debug(.default, "🔄 EXPORT: Found \(tempTargetPresetIDs.count) temp target preset IDs")

                if !tempTargetPresetIDs.isEmpty {
                    do {
                        let tempTargetPresets: [ExportSetting] = try await viewContext.perform {
                            let fetchedTempTargetPresets: [TempTargetStored] = try tempTargetPresetIDs.map {
                                guard let obj = try self.viewContext.existingObject(with: $0) as? TempTargetStored else {
                                    throw ExportError.unknown("TempTargetStored type mismatch for objectID \($0)")
                                }
                                return obj
                            }

                            var processedTempTargetPresets: [ExportSetting] = []
                            processedTempTargetPresets.reserveCapacity(fetchedTempTargetPresets.count * 10)

                            for preset in fetchedTempTargetPresets {
                                let presetName = preset.name ?? "Unknown Temp Target"

                                if let target = preset.target {
                                    let targetValue = trioSettings.units == .mgdL
                                        ? target.description
                                        : target.decimalValue.formattedAsMmolL

                                    processedTempTargetPresets.append(.init(
                                        category: category,
                                        subcategory: presetName,
                                        name: "Target",
                                        value: targetValue,
                                        unit: trioSettings.units.rawValue
                                    ))
                                }

                                if let duration = preset.duration {
                                    processedTempTargetPresets.append(.init(
                                        category: category,
                                        subcategory: presetName,
                                        name: "Duration",
                                        value: String(describing: duration),
                                        unit: String(localized: "minutes")
                                    ))
                                }

                                if let halfBasalTarget = preset.halfBasalTarget {
                                    let halfBasalValue = trioSettings.units == .mgdL
                                        ? halfBasalTarget.description
                                        : halfBasalTarget.decimalValue.formattedAsMmolL

                                    processedTempTargetPresets.append(.init(
                                        category: category,
                                        subcategory: presetName,
                                        name: "Half Basal Target",
                                        value: halfBasalValue,
                                        unit: trioSettings.units.rawValue
                                    ))
                                }
                            }

                            return processedTempTargetPresets
                        }

                        exportSettings.append(contentsOf: tempTargetPresets)
                        debug(.default, "✅ EXPORT: Added \(tempTargetPresets.count) temp target preset rows")
                    } catch {
                        // STRICT: surface the real issue
                        return .failure(.unknown("Failed to extract Temp Targets: \(error.localizedDescription)"))
                    }
                }
            }

            // Override Presets
            if categoriesToExport.contains(.overridePresets) {
                let category = String(localized: "Override Presets")
                debug(.default, "🔄 EXPORT: Fetching override presets...")

                do {
                    let overridePresetIDs = try await overrideStorage.fetchForOverridePresets()
                    debug(.default, "🔄 EXPORT: Found \(overridePresetIDs.count) override preset IDs")

                    if !overridePresetIDs.isEmpty {
                        let overridePresets: [ExportSetting] = try await viewContext.perform {
                            let fetchedOverridePresets: [OverrideStored] = try overridePresetIDs.map {
                                guard let obj = try self.viewContext.existingObject(with: $0) as? OverrideStored else {
                                    throw ExportError.unknown("OverrideStored type mismatch for objectID \($0)")
                                }
                                return obj
                            }

                            var processedOverridePresets: [ExportSetting] = []
                            processedOverridePresets.reserveCapacity(fetchedOverridePresets.count * 10)

                            for preset in fetchedOverridePresets {
                                let presetName = preset.name ?? "Unknown Override"

                                processedOverridePresets.append(.init(
                                    category: category,
                                    subcategory: presetName,
                                    name: String(localized: "Basal Rate Adjustment"),
                                    value: String(format: "%.0f%%", preset.percentage),
                                    unit: ""
                                ))

                                processedOverridePresets.append(.init(
                                    category: category,
                                    subcategory: presetName,
                                    name: "Duration",
                                    value: preset.indefinite
                                        ? String(localized: "Indefinite")
                                        : String(describing: preset.duration ?? 0),
                                    unit: preset.indefinite ? "" : String(localized: "minutes")
                                ))

                                if let target = preset.target, target != 0 {
                                    processedOverridePresets.append(.init(
                                        category: category,
                                        subcategory: presetName,
                                        name: "Target",
                                        value: trioSettings.units == .mgdL
                                            ? target.description
                                            : target.decimalValue.formattedAsMmolL,
                                        unit: trioSettings.units.rawValue
                                    ))
                                }

                                if preset.advancedSettings {
                                    processedOverridePresets.append(.init(
                                        category: category,
                                        subcategory: presetName,
                                        name: "Advanced Settings",
                                        value: String(localized: "Enabled"),
                                        unit: ""
                                    ))
                                    if let smbMinutes = preset.smbMinutes {
                                        processedOverridePresets.append(.init(
                                            category: category,
                                            subcategory: presetName,
                                            name: "SMB Minutes",
                                            value: String(describing: smbMinutes),
                                            unit: String(localized: "minutes")
                                        ))
                                    }
                                    if let uamMinutes = preset.uamMinutes {
                                        processedOverridePresets.append(.init(
                                            category: category,
                                            subcategory: presetName,
                                            name: "UAM Minutes",
                                            value: String(describing: uamMinutes),
                                            unit: String(localized: "minutes")
                                        ))
                                    }
                                }

                                if preset.smbIsOff {
                                    processedOverridePresets.append(.init(
                                        category: category,
                                        subcategory: presetName,
                                        name: "SMB",
                                        value: String(localized: "Disabled"),
                                        unit: ""
                                    ))
                                }

                                if preset.smbIsScheduledOff {
                                    processedOverridePresets.append(.init(
                                        category: category,
                                        subcategory: presetName,
                                        name: "SMB Scheduled",
                                        value: String(localized: "Disabled"),
                                        unit: ""
                                    ))
                                    if let start = preset.start {
                                        processedOverridePresets.append(.init(
                                            category: category,
                                            subcategory: presetName,
                                            name: "SMB Schedule Start",
                                            value: String(describing: start),
                                            unit: String(localized: "hours")
                                        ))
                                    }
                                    if let end = preset.end {
                                        processedOverridePresets.append(.init(
                                            category: category,
                                            subcategory: presetName,
                                            name: "SMB Schedule End",
                                            value: String(describing: end),
                                            unit: String(localized: "hours")
                                        ))
                                    }
                                }

                                // affects logic...
                                let affects: String? = {
                                    if preset.isfAndCr { return String(localized: "ISF and CR") }
                                    if preset.isf, preset.cr { return String(localized: "ISF and CR") }
                                    if preset.isf { return String(localized: "ISF") }
                                    if preset.cr { return String(localized: "CR") }
                                    return nil
                                }()
                                if let affects {
                                    processedOverridePresets.append(.init(
                                        category: category,
                                        subcategory: presetName,
                                        name: "Affects",
                                        value: affects,
                                        unit: ""
                                    ))
                                }
                            }

                            return processedOverridePresets
                        }

                        exportSettings.append(contentsOf: overridePresets)
                        debug(.default, "✅ EXPORT: Added \(overridePresets.count) override preset rows")
                    }
                } catch {
                    return .failure(.unknown("Failed to fetch override presets: \(error.localizedDescription)"))
                }
            }

            // Meal Presets
            if categoriesToExport.contains(.mealPresets) {
                let presetsCategory = String(localized: "Meal Presets")

                // Meal Presets (from Core Data)
                do {
                    debug(.default, "Fetching meal presets...")

                    let mealPresetData = try await viewContext.perform {
                        let request: NSFetchRequest<MealPresetStored> = MealPresetStored.fetchRequest()
                        let mealPresets = try self.viewContext.fetch(request)

                        return mealPresets.map { preset -> (dish: String, carbs: Decimal?, fat: Decimal?, protein: Decimal?) in
                            (
                                dish: preset.dish ?? "Unknown Meal",
                                carbs: preset.carbs?.decimalValue,
                                fat: preset.fat?.decimalValue,
                                protein: preset.protein?.decimalValue
                            )
                        }
                    }

                    debug(.default, "Found \(mealPresetData.count) meal presets")

                    if !mealPresetData.isEmpty {
                        for mealPreset in mealPresetData {
                            if let carbs = mealPreset.carbs, carbs > 0 {
                                addSetting(
                                    category: presetsCategory,
                                    subcategory: mealPreset.dish,
                                    name: "Carbs",
                                    value: String(describing: carbs),
                                    unit: String(localized: "g", comment: "Units for carbs")
                                )
                            }

                            if let fat = mealPreset.fat, fat > 0 {
                                addSetting(
                                    category: presetsCategory,
                                    subcategory: mealPreset.dish,
                                    name: "Fat",
                                    value: String(describing: fat),
                                    unit: String(localized: "g", comment: "Units for carbs")
                                )
                            }

                            if let protein = mealPreset.protein, protein > 0 {
                                addSetting(
                                    category: presetsCategory,
                                    subcategory: mealPreset.dish,
                                    name: "Protein",
                                    value: String(describing: protein),
                                    unit: String(localized: "g", comment: "Units for carbs")
                                )
                            }
                        }
                    }
                } catch {
                    debug(.default, "Failed to fetch meal presets: \(error)")
                }
            }

            // Convert data to the selected format and write to file
            do {
                let content: String
                // Helper function to escape CSV values
                func csvEscape(_ value: String) -> String {
                    if value.contains(",") || value.contains("\"") || value.contains("\n") || value.contains("\r") {
                        return "\"\(value.replacingOccurrences(of: "\"", with: "\"\""))\""
                    }
                    return value
                }

                var csvContent = "\u{FEFF}Setting Category,Subcategory,Setting Name,Value,Unit\n"

                for setting in exportSettings {
                    csvContent +=
                        "\(csvEscape(setting.category)),\(csvEscape(setting.subcategory)),\(csvEscape(setting.name)),\(csvEscape(setting.value)),\(csvEscape(setting.unit))\n"
                }
                content = csvContent

                debug(
                    .default,
                    "📝 EXPORT: Writing .CSV content (\(content.count) characters) to file: \(fileURL.path)"
                )
                debug(.default, "📝 EXPORT: Temporary directory: \(FileManager.default.temporaryDirectory.path)")
                debug(.default, "📝 EXPORT: File URL: \(fileURL)")

                try content.write(to: fileURL, atomically: true, encoding: .utf8)
                debug(.default, "✅ EXPORT: Content written to file successfully")

                // Set file attributes for better sharing compatibility
                try fileManager.setAttributes([
                    .posixPermissions: 0o644,
                    .extensionHidden: false
                ], ofItemAtPath: fileURL.path)
                debug(.default, "✅ EXPORT: File attributes set successfully")

                // Verify file was written successfully
                let fileExists = fileManager.fileExists(atPath: fileURL.path)
                let fileAttributes = try? fileManager.attributesOfItem(atPath: fileURL.path)
                let fileSize = (fileAttributes?[.size] as? NSNumber)?.intValue ?? 0

                debug(.default, "📊 EXPORT: File verification - Exists: \(fileExists), Size: \(fileSize) bytes")

                if !fileExists {
                    debug(.default, "❌ EXPORT: CRITICAL - File does not exist after writing!")
                    return .failure(.unknown("File was not created successfully"))
                }

                if fileSize == 0 {
                    debug(.default, "❌ EXPORT: CRITICAL - File exists but has 0 bytes!")
                    return .failure(.unknown("File was created but is empty"))
                }

                return .success(fileURL)
            } catch {
                debug(.default, "Failed to write settings export file: \(error)")
                return .failure(.fileWriteError(error))
            }
        }

        /// Exports settings using the currently selected categories and format
        func exportSelectedSettings() async -> Result<URL, ExportError> {
            await exportSettings(categories: selectedCategories)
        }

        /// Toggle all categories on or off
        func toggleAllCategories(_ enabled: Bool) {
            if enabled {
                selectedCategories = Set(ExportCategory.allCases)
            } else {
                selectedCategories = []
            }
        }

        /// Check if all categories are selected
        var allCategoriesSelected: Bool {
            selectedCategories.count == ExportCategory.allCases.count
        }
    }
}
