import Foundation

// This Foundation-only contract is compiled into both the Catalyst client and the
// native macOS bundle. Only Objective-C-compatible values cross the bundle boundary.
@MainActor
@objc(SybilQuickQuestionPanelBridging)
protocol SybilQuickQuestionPanelBridging: NSObjectProtocol {
    init()
    var isVisible: Bool { get }
    func start(delegate: any SybilQuickQuestionPanelDelegate) -> Int32
    func updateState(_ data: Data)
    func show()
    func hide()
    func activateForQuickQuestion()
    func activateMainWindow()
    func stop()
}

@MainActor
@objc(SybilQuickQuestionPanelDelegate)
protocol SybilQuickQuestionPanelDelegate: NSObjectProtocol {
    func quickQuestionToggleRequested()
    func quickQuestionPromptChanged(_ prompt: String)
    func quickQuestionSubmitRequested()
    func quickQuestionProviderChanged(_ provider: String)
    func quickQuestionModelChanged(_ model: String)
    func quickQuestionConvertRequested()
    func quickQuestionOpenAppRequested()
    func quickQuestionPanelDismissed()
}

struct SybilQuickQuestionPanelState: Codable, Equatable, Sendable {
    struct ProviderOption: Codable, Equatable, Sendable {
        var id: String
        var title: String
    }

    var prompt = ""
    var answer = ""
    var toolSummaries: [String] = []
    var provider = ""
    var providers: [ProviderOption] = []
    var model = ""
    var models: [String] = []
    var isSending = false
    var isConverting = false
    var canSend = false
    var canConvert = false
    var isAuthenticated = false
    var isCheckingSession = true
    var error: String?

    var isBusy: Bool { isSending || isConverting }
    var hasResponse: Bool { !answer.isEmpty || !toolSummaries.isEmpty || isSending || error != nil }
}

// Carbon can deliver multiple presses while a key is held. Consume one toggle
// per press/release pair, without suppressing a second deliberate press.
struct SybilQuickQuestionHotKeyState {
    private var isPressed = false

    mutating func shouldToggle(isKeyDown: Bool) -> Bool {
        if !isKeyDown {
            isPressed = false
            return false
        }
        guard !isPressed else { return false }
        isPressed = true
        return true
    }
}
