import AppKit

// MARK: - Slider Menu Item View
class SliderMenuItemView: NSView {
    let slider: NSSlider
    let valueLabel: NSTextField
    private let titleLabel: NSTextField
    var onChanged: ((Double) -> Void)?

    init(title: String, value: Double, minValue: Double, maxValue: Double, width: CGFloat = 280) {
        titleLabel = NSTextField(labelWithString: title)
        slider = NSSlider(value: value, minValue: minValue, maxValue: maxValue,
                          target: nil, action: nil)
        valueLabel = NSTextField(labelWithString: String(format: "%.2fx", value))

        super.init(frame: NSRect(x: 0, y: 0, width: width, height: 50))

        titleLabel.font = NSFont.systemFont(ofSize: 12, weight: .medium)
        titleLabel.textColor = .labelColor
        titleLabel.frame = NSRect(x: 16, y: 28, width: width - 32, height: 16)
        addSubview(titleLabel)

        let sliderW = width - 80
        slider.frame = NSRect(x: 16, y: 4, width: sliderW, height: 20)
        slider.target = self
        slider.action = #selector(sliderMoved)
        slider.isContinuous = true
        addSubview(slider)

        valueLabel.font = NSFont.monospacedSystemFont(ofSize: 11, weight: .regular)
        valueLabel.textColor = .secondaryLabelColor
        valueLabel.alignment = .right
        valueLabel.frame = NSRect(x: sliderW + 20, y: 4, width: 44, height: 20)
        addSubview(valueLabel)
    }

    required init?(coder: NSCoder) { fatalError() }

    @objc private func sliderMoved() {
        let v = slider.doubleValue
        valueLabel.stringValue = String(format: "%.2fx", v)
        onChanged?(v)
    }

    func update(value: Double) {
        slider.doubleValue = value
        valueLabel.stringValue = String(format: "%.2fx", value)
    }
}

// MARK: - Color Swatch Menu Item View
class ColorSwatchMenuItemView: NSView {
    private let titleLabel: NSTextField
    private var swatchButtons: [NSButton] = []
    private var selectedIndex: Int = -1
    var onChanged: ((NSColor) -> Void)?

    static let presetColors: [(String, NSColor)] = [
        ("Teal", .systemTeal),
        ("Blue", .systemBlue),
        ("Purple", .systemPurple),
        ("Pink", .systemPink),
        ("Red", .systemRed),
        ("Orange", .systemOrange),
        ("Yellow", .systemYellow),
        ("Green", .systemGreen),
        ("Indigo", .systemIndigo),
    ]

    init(title: String, currentColor: NSColor, width: CGFloat = 280) {
        titleLabel = NSTextField(labelWithString: title)
        super.init(frame: NSRect(x: 0, y: 0, width: width, height: 56))

        titleLabel.font = NSFont.systemFont(ofSize: 12, weight: .medium)
        titleLabel.textColor = .labelColor
        titleLabel.frame = NSRect(x: 16, y: 34, width: width - 32, height: 16)
        addSubview(titleLabel)

        let swatchSize: CGFloat = 22
        let gap: CGFloat = 4
        let count = Self.presetColors.count
        let totalW = CGFloat(count) * swatchSize + CGFloat(count - 1) * gap
        var x = (width - totalW) / 2

        for (i, (_, color)) in Self.presetColors.enumerated() {
            let btn = NSButton(frame: NSRect(x: x, y: 6, width: swatchSize, height: swatchSize))
            btn.wantsLayer = true
            btn.isBordered = false
            btn.title = ""
            btn.layer?.backgroundColor = color.cgColor
            btn.layer?.cornerRadius = swatchSize / 2
            btn.layer?.borderWidth = 2
            btn.layer?.borderColor = NSColor.clear.cgColor
            btn.tag = i
            btn.target = self
            btn.action = #selector(swatchClicked(_:))
            addSubview(btn)
            swatchButtons.append(btn)
            x += swatchSize + gap
        }

        highlightClosest(to: currentColor)
    }

    required init?(coder: NSCoder) { fatalError() }

    @objc private func swatchClicked(_ sender: NSButton) {
        let idx = sender.tag
        guard idx >= 0 && idx < Self.presetColors.count else { return }
        setSelected(idx)
        onChanged?(Self.presetColors[idx].1)
    }

    private func setSelected(_ index: Int) {
        // Clear previous
        for btn in swatchButtons {
            btn.layer?.borderColor = NSColor.clear.cgColor
        }
        // Highlight new
        if index >= 0 && index < swatchButtons.count {
            swatchButtons[index].layer?.borderColor = NSColor.white.cgColor
            selectedIndex = index
        }
    }

    func highlightClosest(to target: NSColor) {
        let t = target.usingColorSpace(.sRGB) ?? target
        var bestIdx = 0
        var bestDist: CGFloat = .greatestFiniteMagnitude
        for (i, (_, color)) in Self.presetColors.enumerated() {
            let c = color.usingColorSpace(.sRGB) ?? color
            let dr = t.redComponent - c.redComponent
            let dg = t.greenComponent - c.greenComponent
            let db = t.blueComponent - c.blueComponent
            let dist = dr*dr + dg*dg + db*db
            if dist < bestDist { bestDist = dist; bestIdx = i }
        }
        setSelected(bestIdx)
    }

    func update(color: NSColor) {
        highlightClosest(to: color)
    }
}

// MARK: - Settings Menu Builder
class SettingsMenuBuilder {
    private var intensityView: SliderMenuItemView?
    private var durationView: SliderMenuItemView?
    private var colorView: ColorSwatchMenuItemView?

    func buildSettingsSubmenu() -> NSMenuItem {
        let submenu = NSMenu(title: "Settings")

        // Color swatches
        let cv = ColorSwatchMenuItemView(title: "Gradient Color:", currentColor: Settings.shared.gradientColor)
        cv.onChanged = { color in Settings.shared.gradientColor = color }
        colorView = cv
        let colorItem = NSMenuItem()
        colorItem.view = cv
        submenu.addItem(colorItem)

        submenu.addItem(NSMenuItem.separator())

        // Intensity
        let iv = SliderMenuItemView(title: "Intensity", value: Settings.shared.intensityScale,
                                     minValue: 0.25, maxValue: 2.0)
        iv.onChanged = { val in Settings.shared.intensityScale = val }
        intensityView = iv
        let intensityItem = NSMenuItem()
        intensityItem.view = iv
        submenu.addItem(intensityItem)

        submenu.addItem(NSMenuItem.separator())

        // Blink Duration
        let dv = SliderMenuItemView(title: "Blink Duration", value: Settings.shared.blinkDurationScale,
                                     minValue: 0.25, maxValue: 3.0)
        dv.onChanged = { val in Settings.shared.blinkDurationScale = val }
        durationView = dv
        let durationItem = NSMenuItem()
        durationItem.view = dv
        submenu.addItem(durationItem)

        submenu.addItem(NSMenuItem.separator())

        // Reset
        let resetItem = NSMenuItem(title: "Reset to Defaults", action: #selector(resetDefaults), keyEquivalent: "")
        resetItem.target = self
        submenu.addItem(resetItem)

        let parentItem = NSMenuItem(title: "Settings", action: nil, keyEquivalent: ",")
        parentItem.submenu = submenu
        return parentItem
    }

    func refreshValues() {
        let s = Settings.shared
        intensityView?.update(value: s.intensityScale)
        durationView?.update(value: s.blinkDurationScale)
        colorView?.update(color: s.gradientColor)
    }

    @objc private func resetDefaults() {
        Settings.shared.resetToDefaults()
        refreshValues()
    }
}
