import AppKit

// MARK: - Settings Keys
private enum SettingsKey {
    static let intensityScale = "pommedoro.intensityScale"
    static let blinkDurationScale = "pommedoro.blinkDurationScale"
    static let gradientColorRed = "pommedoro.gradientColor.red"
    static let gradientColorGreen = "pommedoro.gradientColor.green"
    static let gradientColorBlue = "pommedoro.gradientColor.blue"
}

// MARK: - Settings Manager
class Settings {
    static let shared = Settings()

    /// Notification posted when any setting changes
    static let didChangeNotification = Notification.Name("PommedoroSettingsDidChange")

    private let defaults = UserDefaults.standard

    private init() {
        registerDefaults()
    }

    private func registerDefaults() {
        // Extract default teal components for consistent defaults
        let teal = NSColor.systemTeal.usingColorSpace(.sRGB) ?? NSColor.systemTeal
        defaults.register(defaults: [
            SettingsKey.intensityScale: 1.0,
            SettingsKey.blinkDurationScale: 1.0,
            SettingsKey.gradientColorRed: Double(teal.redComponent),
            SettingsKey.gradientColorGreen: Double(teal.greenComponent),
            SettingsKey.gradientColorBlue: Double(teal.blueComponent),
        ])
    }

    /// Intensity multiplier (0.25 to 2.0, default 1.0)
    var intensityScale: Double {
        get { defaults.double(forKey: SettingsKey.intensityScale) }
        set {
            defaults.set(newValue.clamped(to: 0.25...2.0), forKey: SettingsKey.intensityScale)
            notifyChange()
        }
    }

    /// Blink duration multiplier (0.25 to 3.0, default 1.0)
    var blinkDurationScale: Double {
        get { defaults.double(forKey: SettingsKey.blinkDurationScale) }
        set {
            defaults.set(newValue.clamped(to: 0.25...3.0), forKey: SettingsKey.blinkDurationScale)
            notifyChange()
        }
    }

    /// Gradient color as NSColor
    var gradientColor: NSColor {
        get {
            NSColor(
                srgbRed: CGFloat(defaults.double(forKey: SettingsKey.gradientColorRed)),
                green: CGFloat(defaults.double(forKey: SettingsKey.gradientColorGreen)),
                blue: CGFloat(defaults.double(forKey: SettingsKey.gradientColorBlue)),
                alpha: 1.0
            )
        }
        set {
            let c = newValue.usingColorSpace(.sRGB) ?? newValue
            defaults.set(Double(c.redComponent), forKey: SettingsKey.gradientColorRed)
            defaults.set(Double(c.greenComponent), forKey: SettingsKey.gradientColorGreen)
            defaults.set(Double(c.blueComponent), forKey: SettingsKey.gradientColorBlue)
            notifyChange()
        }
    }

    func resetToDefaults() {
        for key in [
            SettingsKey.intensityScale,
            SettingsKey.blinkDurationScale,
            SettingsKey.gradientColorRed,
            SettingsKey.gradientColorGreen,
            SettingsKey.gradientColorBlue,
        ] {
            defaults.removeObject(forKey: key)
        }
        notifyChange()
    }

    private func notifyChange() {
        NotificationCenter.default.post(name: Settings.didChangeNotification, object: nil)
    }
}

// MARK: - Comparable Clamping
private extension Comparable {
    func clamped(to range: ClosedRange<Self>) -> Self {
        min(max(self, range.lowerBound), range.upperBound)
    }
}
