import Cocoa

/// 菜单栏控制器：管理状态栏图标和菜单
final class MenuBarController: NSObject {

    private let statusItem: NSStatusItem
    private let menu = NSMenu()
    private var languageMenuItems: [NSMenuItem] = []
    private var modeMenuItems: [NSMenuItem] = []

    // LLM 配置
    private let inputLLMSubmenu = NSMenu()
    private let inputLLMEnabledItem: NSMenuItem
    
    private let assistLLMSubmenu = NSMenu()
    private let assistLLMEnabledItem: NSMenuItem
    
    private let inputSettingsWindow: SettingsWindow
    private let assistSettingsWindow: SettingsWindow
    private let agentSettingsWindow: SettingsWindow
    private let agentLLMEnabledItem: NSMenuItem
    private let agentVoiceInputItem: NSMenuItem
    private let agentTextInputItem: NSMenuItem
    private let memoryWindow: MemoryWindow

    override init() {
        statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)

        inputLLMEnabledItem = NSMenuItem(
            title: "Enable",
            action: #selector(toggleInputLLM),
            keyEquivalent: ""
        )
        
        assistLLMEnabledItem = NSMenuItem(
            title: "Enable",
            action: #selector(toggleAssistLLM),
            keyEquivalent: ""
        )
        
        inputSettingsWindow = SettingsWindow(mode: .input)
        assistSettingsWindow = SettingsWindow(mode: .assist)
        agentSettingsWindow = SettingsWindow(mode: .agent)
        memoryWindow = MemoryWindow()
        agentLLMEnabledItem = NSMenuItem(
            title: "Enable",
            action: #selector(toggleAgentLLM),
            keyEquivalent: ""
        )
        agentVoiceInputItem = NSMenuItem(
            title: "语音输入",
            action: #selector(selectAgentVoiceInput),
            keyEquivalent: ""
        )
        agentTextInputItem = NSMenuItem(
            title: "打字输入",
            action: #selector(selectAgentTextInput),
            keyEquivalent: ""
        )

        super.init()

        configureStatusItem()
        buildMenu()
    }

    private func configureStatusItem() {
        if let button = statusItem.button {
            button.image = NSImage(
                systemSymbolName: "mic.fill",
                accessibilityDescription: "Voice Input"
            )
            button.toolTip = "Voice Input — 按住 Fn 键录音"
        }
    }

    private func buildMenu() {
        // 当前语言显示
        let currentLanguageItem = NSMenuItem(
            title: "Language: \(Config.shared.language.displayName)",
            action: nil,
            keyEquivalent: ""
        )
        currentLanguageItem.isEnabled = false
        menu.addItem(currentLanguageItem)
        menu.addItem(.separator())

        // 语言选择子菜单
        let languageMenu = NSMenu()
        for lang in RecognitionLanguage.allCases {
            let item = NSMenuItem(
                title: lang.displayName,
                action: #selector(selectLanguage(_:)),
                keyEquivalent: ""
            )
            item.target = self
            item.representedObject = lang
            item.state = lang == Config.shared.language ? .on : .off
            languageMenu.addItem(item)
            languageMenuItems.append(item)
        }

        // 禁用 autoenablesItems，防止系统自动禁用菜单项
        languageMenu.autoenablesItems = false
        
        let languageSubmenuItem = NSMenuItem()
        languageSubmenuItem.title = "Language"
        languageSubmenuItem.submenu = languageMenu
        menu.addItem(languageSubmenuItem)
        
        // 调试：打印每个语言菜单项的状态
        for item in languageMenuItems {
            print("[Menu Debug] Language item: '\(item.title)' enabled=\(item.isEnabled) target=\(String(describing: item.target)) action=\(String(describing: item.action))")
        }

        menu.addItem(.separator())

        // ===== 模式切换 =====
        let modeMenu = NSMenu()
        let inputModeItem = NSMenuItem(
            title: "语音输入",
            action: #selector(selectMode(_:)),
            keyEquivalent: ""
        )
        inputModeItem.target = self
        inputModeItem.representedObject = TriggerMode.input
        inputModeItem.state = Config.shared.triggerMode == .input ? .on : .off
        modeMenuItems.append(inputModeItem)
        modeMenu.addItem(inputModeItem)
        
        let assistModeItem = NSMenuItem(
            title: "AI 助手",
            action: #selector(selectMode(_:)),
            keyEquivalent: ""
        )
        assistModeItem.target = self
        assistModeItem.representedObject = TriggerMode.assist
        assistModeItem.state = Config.shared.triggerMode == .assist ? .on : .off
        modeMenuItems.append(assistModeItem)
        modeMenu.addItem(assistModeItem)

        let agentModeItem = NSMenuItem(
            title: "智能体",
            action: #selector(selectMode(_:)),
            keyEquivalent: ""
        )
        agentModeItem.target = self
        agentModeItem.representedObject = TriggerMode.agent
        agentModeItem.state = Config.shared.triggerMode == .agent ? .on : .off
        modeMenuItems.append(agentModeItem)
        modeMenu.addItem(agentModeItem)

        // 禁用 autoenablesItems，防止系统自动禁用菜单项
        modeMenu.autoenablesItems = false
        
        let modeSubmenuItem = NSMenuItem()
        modeSubmenuItem.title = "Mode"
        modeSubmenuItem.submenu = modeMenu
        menu.addItem(modeSubmenuItem)
        
        // 调试：打印每个模式菜单项的状态
        for item in modeMenuItems {
            print("[Menu Debug] Mode item: '\(item.title)' enabled=\(item.isEnabled) target=\(String(describing: item.target)) action=\(String(describing: item.action))")
        }

        menu.addItem(.separator())

        // ===== Input LLM =====
        inputLLMSubmenu.addItem(inputLLMEnabledItem)
        inputLLMEnabledItem.target = self
        inputLLMEnabledItem.action = #selector(toggleInputLLM)
        updateInputLLMMenuState()

        let inputSettingsItem = NSMenuItem(
            title: "Settings...",
            action: #selector(openInputSettings),
            keyEquivalent: ""
        )
        inputSettingsItem.target = self
        inputLLMSubmenu.addItem(inputSettingsItem)

        let inputSubmenuItem = NSMenuItem()
        inputSubmenuItem.title = "Input LLM"
        inputSubmenuItem.submenu = inputLLMSubmenu
        menu.addItem(inputSubmenuItem)

        menu.addItem(.separator())

        // ===== Assist LLM =====
        assistLLMSubmenu.addItem(assistLLMEnabledItem)
        assistLLMEnabledItem.target = self
        assistLLMEnabledItem.action = #selector(toggleAssistLLM)
        updateAssistLLMMenuState()

        let assistSettingsItem = NSMenuItem(
            title: "Settings...",
            action: #selector(openAssistSettings),
            keyEquivalent: ""
        )
        assistSettingsItem.target = self
        assistLLMSubmenu.addItem(assistSettingsItem)

        let assistSubmenuItem = NSMenuItem()
        assistSubmenuItem.title = "Assist LLM"
        assistSubmenuItem.submenu = assistLLMSubmenu
        menu.addItem(assistSubmenuItem)

        menu.addItem(.separator())

        // ===== Agent LLM =====
        let agentLLMSubmenu = NSMenu()
        agentLLMEnabledItem.target = self
        agentLLMSubmenu.addItem(agentLLMEnabledItem)
        updateAgentLLMMenuState()

        agentLLMSubmenu.addItem(.separator())

        agentVoiceInputItem.target = self
        agentVoiceInputItem.state = Config.shared.agentInputMode == "voice" ? .on : .off
        agentLLMSubmenu.addItem(agentVoiceInputItem)

        agentTextInputItem.target = self
        agentTextInputItem.state = Config.shared.agentInputMode == "text" ? .on : .off
        agentLLMSubmenu.addItem(agentTextInputItem)

        agentLLMSubmenu.addItem(.separator())

        let agentSettingsItem = NSMenuItem(
            title: "Settings...",
            action: #selector(openAgentSettings),
            keyEquivalent: ""
        )
        agentSettingsItem.target = self
        agentSettingsItem.isEnabled = true
        agentLLMSubmenu.addItem(agentSettingsItem)

        let agentSubmenuItem = NSMenuItem()
        agentSubmenuItem.title = "Agent LLM"
        agentSubmenuItem.submenu = agentLLMSubmenu
        menu.addItem(agentSubmenuItem)

        menu.addItem(.separator())

        // 助手设置
        let assistantSettingsItem = NSMenuItem(
            title: "助手设置...",
            action: #selector(openAgentSettings),
            keyEquivalent: ""
        )
        assistantSettingsItem.target = self
        menu.addItem(assistantSettingsItem)

        // 记忆管理
        let memoryItem = NSMenuItem(
            title: "记忆管理...",
            action: #selector(openMemoryManager),
            keyEquivalent: ""
        )
        memoryItem.target = self
        menu.addItem(memoryItem)

        menu.addItem(.separator())

        // 退出
        let quitItem = NSMenuItem(
            title: "Quit",
            action: #selector(quit),
            keyEquivalent: "q"
        )
        quitItem.target = self
        menu.addItem(quitItem)

        // 关闭所有菜单的自动验证，改为手动管理
        menu.autoenablesItems = false
        languageMenu.autoenablesItems = false
        modeMenu.autoenablesItems = false
        inputLLMSubmenu.autoenablesItems = false
        assistLLMSubmenu.autoenablesItems = false
        agentLLMSubmenu.autoenablesItems = false

        print("[Menu Debug] Agent Settings item: title=\(agentSettingsItem.title) enabled=\(agentSettingsItem.isEnabled) target=\(String(describing: agentSettingsItem.target)) action=\(String(describing: agentSettingsItem.action)) submenu=\(String(describing: agentSettingsItem.menu))")

        statusItem.menu = menu
    }

    // MARK: - NSMenuItemValidation

    /// 手动验证所有菜单项（替代系统的自动验证）
    @objc func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
        // 所有菜单项统一启用，由 target/action 决定是否响应
        return true
    }

    func refreshModeMenu() {
        updateModeMenuState()
    }

    private func updateInputLLMMenuState() {
        inputLLMEnabledItem.state = Config.shared.inputLLM.enabled ? .on : .off
    }

    private func updateAssistLLMMenuState() {
        assistLLMEnabledItem.state = Config.shared.assistLLM.enabled ? .on : .off
    }

    private func updateAgentLLMMenuState() {
        let modelsFile = Config.shared.loadAgentModels()
        let validModels = modelsFile.models.filter { !$0.url.isEmpty && !$0.name.isEmpty && !$0.apikey.isEmpty && !$0.modes.isEmpty }
        agentLLMEnabledItem.state = validModels.isEmpty ? .off : .on
    }

    private func updateModeMenuState() {
        for item in modeMenuItems {
            guard let mode = item.representedObject as? TriggerMode else { continue }
            item.state = mode == Config.shared.triggerMode ? .on : .off
        }
    }

    private func updateLanguageMenuState() {
        for item in languageMenuItems {
            guard let lang = item.representedObject as? RecognitionLanguage else { continue }
            item.state = lang == Config.shared.language ? .on : .off
        }
        if let first = menu.items.first {
            first.title = "Language: \(Config.shared.language.displayName)"
        }
    }

    @objc private func selectLanguage(_ sender: NSMenuItem) {
        print("[Menu Debug] selectLanguage called! sender.title=\(sender.title) sender.representedObject=\(String(describing: sender.representedObject))")
        guard let lang = sender.representedObject as? RecognitionLanguage else {
            print("[Menu Debug] selectLanguage FAILED: representedObject is not RecognitionLanguage, actual type: \(type(of: sender.representedObject))")
            return
        }
        Config.shared.language = lang
        updateLanguageMenuState()
        print("[Menu] Language switched to: \(lang.displayName)")
    }

    @objc private func selectMode(_ sender: NSMenuItem) {
        print("[Menu Debug] selectMode called! sender.title=\(sender.title) sender.representedObject=\(String(describing: sender.representedObject))")
        guard let mode = sender.representedObject as? TriggerMode else {
            print("[Menu Debug] selectMode FAILED: representedObject is not TriggerMode, actual type: \(type(of: sender.representedObject))")
            return
        }
        Config.shared.triggerMode = mode
        updateModeMenuState()
        print("[Menu] Mode switched to: \(mode)")
    }

    @objc private func toggleInputLLM() {
        var config = Config.shared.inputLLM
        config.enabled.toggle()
        Config.shared.inputLLM = config
        updateInputLLMMenuState()
        print("[Menu] Input LLM: \(config.enabled ? "ON" : "OFF")")
    }

    @objc private func toggleAssistLLM() {
        var config = Config.shared.assistLLM
        config.enabled.toggle()
        Config.shared.assistLLM = config
        updateAssistLLMMenuState()
        print("[Menu] Assist LLM: \(config.enabled ? "ON" : "OFF")")
    }

    @objc private func toggleAgentLLM() {
        let modelsFile = Config.shared.loadAgentModels()
        let validModels = modelsFile.models.filter { !$0.url.isEmpty && !$0.name.isEmpty && !$0.apikey.isEmpty && !$0.modes.isEmpty }
        // 只要有有效模型就视为已配置，点击时打开 Settings
        if validModels.isEmpty {
            openAgentSettings()
        }
    }

    @objc private func openInputSettings() {
        showWindowWithDock(inputSettingsWindow)
    }

    @objc private func openAssistSettings() {
        showWindowWithDock(assistSettingsWindow)
    }

    @objc private func openAgentSettings() {
        print("[MenuBar] openAgentSettings called")
        agentSettingsWindow.refreshAgentModelTable()
        showWindowWithDock(agentSettingsWindow)
    }

    @objc private func openMemoryManager() {
        showWindowWithDock(memoryWindow)
    }

    @objc private func selectAgentVoiceInput() {
        Config.shared.agentInputMode = "voice"
        agentVoiceInputItem.state = .on
        agentTextInputItem.state = .off
    }

    @objc private func selectAgentTextInput() {
        Config.shared.agentInputMode = "text"
        agentVoiceInputItem.state = .off
        agentTextInputItem.state = .on
    }

    /// 显示窗口并临时启用 Dock 图标
    private var dockVisibleWindowCount = 0

    private func showWindowWithDock(_ window: NSWindow) {
        dockVisibleWindowCount += 1
        if NSApp.activationPolicy() != .regular {
            NSApp.setActivationPolicy(.regular)
        }
        window.delegate = self
        window.makeKeyAndOrderFront(nil)
        NSApp.activate(ignoringOtherApps: true)
    }

    @objc private func quit() {
        NSApplication.shared.terminate(nil)
    }
}

// MARK: - NSWindowDelegate（Dock 回收）

extension MenuBarController: NSWindowDelegate {
    func windowWillClose(_ notification: Notification) {
        dockVisibleWindowCount -= 1
        if dockVisibleWindowCount <= 0 {
            dockVisibleWindowCount = 0
            NSApp.setActivationPolicy(.accessory)
        }
    }
}
