import Cocoa
import ApplicationServices

@MainActor
class GlobalEventMonitor: ObservableObject {
    private var eventTap: CFMachPort?
    private var runLoopSource: CFRunLoopSource?
    @Published var isEnabled = false
    
    var onMiddleClick: (() -> Void)?
    
    func start() {
        guard !isEnabled else { return }
        
        // Check for accessibility permissions
        let options = [kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String: true] as CFDictionary
        let accessibilityEnabled = AXIsProcessTrustedWithOptions(options)
        
        guard accessibilityEnabled else {
            print("Accessibility permissions not granted")
            return
        }
        
        // Create event tap for middle mouse button
        let eventMask = (1 << CGEventType.otherMouseDown.rawValue)
        
        guard let tap = CGEvent.tapCreate(
            tap: .cgSessionEventTap,
            place: .headInsertEventTap,
            options: .defaultTap,
            eventsOfInterest: CGEventMask(eventMask),
            callback: { (proxy, type, event, refcon) -> Unmanaged<CGEvent>? in
                // Check if it's a middle mouse button click (button 2)
                if type == .otherMouseDown && event.getIntegerValueField(.mouseEventButtonNumber) == 2 {
                    // Call the callback on main thread
                    Task { @MainActor in
                        if let monitor = Unmanaged<GlobalEventMonitor>.fromOpaque(refcon!).takeUnretainedValue() as GlobalEventMonitor? {
                            monitor.onMiddleClick?()
                        }
                    }
                }
                return Unmanaged.passRetained(event)
            },
            userInfo: Unmanaged.passUnretained(self).toOpaque()
        ) else {
            print("Failed to create event tap")
            return
        }
        
        eventTap = tap
        runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0)
        CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes)
        CGEvent.tapEnable(tap: tap, enable: true)
        
        isEnabled = true
        print("Global event monitor started")
    }
    
    func stop() {
        guard isEnabled else { return }
        
        if let tap = eventTap {
            CGEvent.tapEnable(tap: tap, enable: false)
            CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes)
            eventTap = nil
            runLoopSource = nil
        }
        
        isEnabled = false
        print("Global event monitor stopped")
    }
    
    deinit {
        // deinit is nonisolated; schedule cleanup on the main actor
        Task { @MainActor in
            self.stop()
        }
    }
}



