import AppKit
@preconcurrency import ApplicationServices
import CoreGraphics
import Foundation
import AlignerCore

final class CGWindowAXWindowService: WindowServiceProtocol, WindowRestorationServiceProtocol, WindowActivationServiceProtocol, WindowCloseServiceProtocol {
    weak var delegate: WindowServiceDelegate?

    private let appCategorizer: any AppCategorizer
    private let spaceIDsByWindowIDProvider: ([UInt32]) -> [UInt32: [UInt64]]
    private let fullscreenSpaceIDs: Set<UInt64>
    private let privateActivationBridge: PrivateWindowActivationBridge?
    private let privateSpaceActivationBridge: PrivateSpaceActivationBridge?
    private var restorableAXWindowsByID: [UInt32: RestorableAXWindow] = [:]

    init(
        spaceIDsByWindowIDProvider: @escaping ([UInt32]) -> [UInt32: [UInt64]],
        appCategorizer: any AppCategorizer = BundleIDAppCategorizer(),
        fullscreenSpaceIDs: Set<UInt64> = [],
        privateActivationBridge: PrivateWindowActivationBridge? = .shared,
        privateSpaceActivationBridge: PrivateSpaceActivationBridge? = .shared
    ) {
        self.appCategorizer = appCategorizer
        self.fullscreenSpaceIDs = fullscreenSpaceIDs
        self.spaceIDsByWindowIDProvider = spaceIDsByWindowIDProvider
        self.privateActivationBridge = privateActivationBridge
        self.privateSpaceActivationBridge = privateSpaceActivationBridge
    }

    func allWindows() throws -> [AlignerWindow] {
        let records = try windowRecords()
        return records.compactMap(WindowEnumerationPolicy.window)
    }

    func windows(for space: AlignerSpace) throws -> [AlignerWindow] {
        try allWindows().filter { window in
            window.spaceIDs.contains(space.id)
        }
    }

    func refresh() {}

    func startObserving() {}

    func stopObserving() {}

    func restore(windowID: UInt32) throws -> WindowRestoreResult {
        guard let restorableWindow = restorableAXWindowsByID[windowID] else {
            DevelopmentDiagnostics.log("windowActivation.restore.windowNotFound", [
                "windowID": windowID
            ])
            return .windowNotFound
        }
        DevelopmentDiagnostics.log("windowActivation.restore.start", [
            "windowID": windowID,
            "pid": restorableWindow.processIdentifier
        ])

        let minimizeResult = AXUIElementSetAttributeValue(
            restorableWindow.element,
            kAXMinimizedAttribute as CFString,
            kCFBooleanFalse
        )
        guard minimizeResult == .success else {
            DevelopmentDiagnostics.log("windowActivation.restore.setMinimizedFailed", [
                "windowID": windowID,
                "pid": restorableWindow.processIdentifier,
                "axError": String(describing: minimizeResult)
            ])
            throw AXWindowRestoreError.setMinimizedFailed(minimizeResult)
        }

        let focusedBeforeActivateResult = focusWindowResult(
            restorableWindow.element,
            processIdentifier: restorableWindow.processIdentifier
        )
        let raisedBeforeActivateResult = raiseWindowResult(restorableWindow.element)
        let focusedBeforeActivate = focusedBeforeActivateResult.success
        let raisedBeforeActivate = raisedBeforeActivateResult.success

        guard activateApplication(processIdentifier: restorableWindow.processIdentifier) else {
            DevelopmentDiagnostics.log("windowActivation.restore.activateApplicationFailed", [
                "windowID": windowID,
                "pid": restorableWindow.processIdentifier,
                "focusedBeforeActivate": focusedBeforeActivate,
                "focusBeforeAXError": String(describing: focusedBeforeActivateResult.error),
                "raisedBeforeActivate": raisedBeforeActivate,
                "raiseBeforeAXError": String(describing: raisedBeforeActivateResult.error)
            ])
            return .activationFailed
        }

        let focusedAfterActivateResult = focusWindowResult(
            restorableWindow.element,
            processIdentifier: restorableWindow.processIdentifier
        )
        let raisedAfterActivateResult = raiseWindowResult(restorableWindow.element)
        let focusedAfterActivate = focusedAfterActivateResult.success
        let raisedAfterActivate = raisedAfterActivateResult.success

        let restored = focusedBeforeActivate || focusedAfterActivate || raisedBeforeActivate || raisedAfterActivate
        DevelopmentDiagnostics.log("windowActivation.restore.end", [
            "windowID": windowID,
            "pid": restorableWindow.processIdentifier,
            "focusedBeforeActivate": focusedBeforeActivate,
            "focusBeforeAXError": String(describing: focusedBeforeActivateResult.error),
            "raisedBeforeActivate": raisedBeforeActivate,
            "raiseBeforeAXError": String(describing: raisedBeforeActivateResult.error),
            "focusedAfterActivate": focusedAfterActivate,
            "focusAfterAXError": String(describing: focusedAfterActivateResult.error),
            "raisedAfterActivate": raisedAfterActivate,
            "raiseAfterAXError": String(describing: raisedAfterActivateResult.error),
            "result": restored ? "restored" : "activationFailed"
        ])
        return focusedBeforeActivate || focusedAfterActivate || raisedBeforeActivate || raisedAfterActivate
            ? .restored
            : .activationFailed
    }

    func activate(window: AlignerWindow) throws -> WindowActivationResult {
        DevelopmentDiagnostics.log("windowActivation.activate.start", [
            "windowID": window.id,
            "identifierSource": String(describing: window.identifierSource),
            "titleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
            "titleLength": window.title.count,
            "titleIsEmpty": window.title.isEmpty,
            "appName": window.app.name,
            "bundleIdentifier": window.app.bundleIdentifier,
            "pid": window.app.processIdentifier,
            "isMinimized": window.isMinimized,
            "isFullscreen": window.isFullscreen
        ])
        if window.isMinimized {
            let refreshedWindows = try allWindows()
            DevelopmentDiagnostics.log("windowActivation.activate.refreshedBeforeRestore", [
                "windowID": window.id,
                "refreshedWindowCount": refreshedWindows.count
            ])
            let restoreResult = try restore(windowID: window.id)
            DevelopmentDiagnostics.log("windowActivation.activate.restoreResult", [
                "windowID": window.id,
                "result": Self.restoreResultString(restoreResult)
            ])
            switch restoreResult {
            case .restored:
                return .restored
            case .windowNotFound:
                return activateApplication(for: window) ? .activationFailed : .windowNotFound
            case .unsupported:
                return .unsupported
            case .activationFailed:
                return .activationFailed
            }
        }

        let spaceFocusOutcome = focusTargetSpaceIfNeeded(for: window)
        if spaceFocusOutcome?.didRequestFocus == true {
            Thread.sleep(forTimeInterval: 0.12)
        }

        let privateActivationOutcome = activateViaPrivateWindowServerAPI(window)
        let didPrivatelyActivate = privateActivationOutcome?.succeeded == true

        let axWindow = AXWindowMetadataReader
            .metadata(appCategorizer: appCategorizer)
            .first { metadata in
                if let windowID = metadata.windowID {
                    return windowID == window.id
                }

                return metadata.processIdentifier == window.app.processIdentifier
                    && metadata.title == window.title
            }

        DevelopmentDiagnostics.log("windowActivation.activate.axLookup", [
            "windowID": window.id,
            "titleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
            "titleLength": window.title.count,
            "titleIsEmpty": window.title.isEmpty,
            "pid": window.app.processIdentifier,
            "found": axWindow != nil,
            "matchedWindowID": axWindow?.windowID,
            "matchedTitleHash": DevelopmentDiagnostics.stableFingerprint(axWindow?.title),
            "matchedTitleLength": axWindow?.title?.count,
            "matchedTitleIsEmpty": axWindow?.title?.isEmpty,
            "matchedPID": axWindow?.processIdentifier,
            "spaceFocusTargetSpaceID": spaceFocusOutcome?.targetSpaceID,
            "spaceFocusDisplayIdentifier": spaceFocusOutcome?.displayIdentifier,
            "spaceFocusPreviousSpaceID": spaceFocusOutcome?.previousCurrentSpaceID,
            "spaceFocusRequested": spaceFocusOutcome?.didRequestFocus,
            "spaceFocusError": spaceFocusOutcome?.error
        ])
        guard let axWindow else {
            let activated = activateApplication(for: window)
            DevelopmentDiagnostics.log("windowActivation.activate.axMissing", [
                "windowID": window.id,
                "appName": window.app.name,
                "pid": window.app.processIdentifier,
                "privateActivated": didPrivatelyActivate,
                "applicationActivated": activated,
                "result": didPrivatelyActivate ? "activated" : (activated ? "appActivatedOnly" : "windowNotFound")
            ])
            if didPrivatelyActivate {
                return .activated
            }

            return activated ? .appActivatedOnly : .windowNotFound
        }

        let focusedBeforeActivateResult = focusWindowResult(
            axWindow.element,
            processIdentifier: axWindow.processIdentifier
        )
        let raisedBeforeActivateResult = raiseWindowResult(axWindow.element)
        let focusedBeforeActivate = focusedBeforeActivateResult.success
        let raisedBeforeActivate = raisedBeforeActivateResult.success

        guard didPrivatelyActivate || activateApplication(for: window) else {
            DevelopmentDiagnostics.log("windowActivation.activate.applicationActivationFailed", [
                "windowID": window.id,
                "pid": window.app.processIdentifier,
                "privateActivated": didPrivatelyActivate,
                "focusedBeforeActivate": focusedBeforeActivate,
                "focusBeforeAXError": String(describing: focusedBeforeActivateResult.error),
                "raisedBeforeActivate": raisedBeforeActivate,
                "raiseBeforeAXError": String(describing: raisedBeforeActivateResult.error)
            ])
            return .activationFailed
        }

        let focusedAfterActivateResult = focusWindowResult(
            axWindow.element,
            processIdentifier: axWindow.processIdentifier
        )
        let raisedAfterActivateResult = raiseWindowResult(axWindow.element)
        let focusedAfterActivate = focusedAfterActivateResult.success
        let raisedAfterActivate = raisedAfterActivateResult.success

        let didFocusOrRaise = focusedBeforeActivate || focusedAfterActivate || raisedBeforeActivate || raisedAfterActivate
        DevelopmentDiagnostics.log("windowActivation.activate.end", [
            "windowID": window.id,
            "pid": window.app.processIdentifier,
            "privateActivated": didPrivatelyActivate,
            "focusedBeforeActivate": focusedBeforeActivate,
            "focusBeforeAXError": String(describing: focusedBeforeActivateResult.error),
            "raisedBeforeActivate": raisedBeforeActivate,
            "raiseBeforeAXError": String(describing: raisedBeforeActivateResult.error),
            "focusedAfterActivate": focusedAfterActivate,
            "focusAfterAXError": String(describing: focusedAfterActivateResult.error),
            "raisedAfterActivate": raisedAfterActivate,
            "raiseAfterAXError": String(describing: raisedAfterActivateResult.error),
            "result": (didFocusOrRaise || didPrivatelyActivate) ? "activated" : "appActivatedOnly"
        ])
        return didPrivatelyActivate || focusedBeforeActivate || focusedAfterActivate || raisedBeforeActivate || raisedAfterActivate
            ? .activated
            : .appActivatedOnly
    }

    func close(window: AlignerWindow) throws -> WindowCloseResult {
        DevelopmentDiagnostics.log("windowClose.window.start", [
            "windowID": window.id,
            "identifierSource": String(describing: window.identifierSource),
            "titleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
            "titleLength": window.title.count,
            "titleIsEmpty": window.title.isEmpty,
            "appName": window.app.name,
            "bundleIdentifier": window.app.bundleIdentifier,
            "pid": window.app.processIdentifier
        ])

        let axMetadata = AXWindowMetadataReader.metadata(appCategorizer: appCategorizer)
        var matchedAXWindow = axWindow(for: window, in: axMetadata)
        var finalAXMetadata = axMetadata

        if matchedAXWindow == nil {
            Thread.sleep(forTimeInterval: 0.12)
            finalAXMetadata = AXWindowMetadataReader.metadata(appCategorizer: appCategorizer)
            matchedAXWindow = axWindow(for: window, in: finalAXMetadata, matchAttempt: "retry")
        }

        guard let matchedAXWindow else {
            DevelopmentDiagnostics.log("windowClose.window.axMissing", [
                "windowID": window.id,
                "appName": window.app.name,
                "pid": window.app.processIdentifier,
                "candidateCount": finalAXMetadata.filter { $0.processIdentifier == window.app.processIdentifier }.count,
                "matchingTitleCandidateCount": matchingAXTitleCandidateCount(for: window, in: finalAXMetadata),
                "matchingSizeCandidateCount": matchingAXSizeCandidateCount(for: window, in: finalAXMetadata)
            ])
            return .windowNotFound
        }

        guard let closeButton = closeButton(for: matchedAXWindow) else {
            Thread.sleep(forTimeInterval: 0.12)
            let retryMetadata = AXWindowMetadataReader.metadata(appCategorizer: appCategorizer)
            if let retryAXWindow = axWindow(for: window, in: retryMetadata, matchAttempt: "closeButtonRetry"),
               let retryCloseButton = closeButton(for: retryAXWindow) {
                return performCloseButtonPress(
                    retryCloseButton,
                    window: window,
                    processIdentifier: retryAXWindow.processIdentifier,
                    attempt: "closeButtonRetry"
                )
            }
            DevelopmentDiagnostics.log("windowClose.window.closeButtonMissing", [
                "windowID": window.id,
                "pid": matchedAXWindow.processIdentifier,
                "appName": window.app.name
            ])
            return .windowNotFound
        }

        return performCloseButtonPress(
            closeButton,
            window: window,
            processIdentifier: matchedAXWindow.processIdentifier,
            attempt: "initial"
        )
    }

    private func closeButton(for axWindow: AXWindowMetadata) -> AXUIElement? {
        var closeButtonValue: CFTypeRef?
        let closeButtonLookupResult = AXUIElementCopyAttributeValue(
            axWindow.element,
            kAXCloseButtonAttribute as CFString,
            &closeButtonValue
        )
        guard closeButtonLookupResult == .success,
              let closeButton = closeButtonValue,
              CFGetTypeID(closeButton) == AXUIElementGetTypeID()
        else {
            DevelopmentDiagnostics.log("windowClose.window.closeButtonLookupFailed", [
                "pid": axWindow.processIdentifier,
                "axError": String(describing: closeButtonLookupResult)
            ])
            return nil
        }

        return (closeButton as! AXUIElement)
    }

    private func performCloseButtonPress(
        _ closeButton: AXUIElement,
        window: AlignerWindow,
        processIdentifier: Int32,
        attempt: String
    ) -> WindowCloseResult {
        let closeResult = AXUIElementPerformAction(closeButton, kAXPressAction as CFString)
        DevelopmentDiagnostics.log("windowClose.window.result", [
            "windowID": window.id,
            "pid": processIdentifier,
            "attempt": attempt,
            "axError": String(describing: closeResult)
        ])

        switch closeResult {
        case .success:
            return .requested
        case .actionUnsupported, .notImplemented:
            return .unsupported
        default:
            return .failed(String(describing: closeResult))
        }
    }

    private func axWindow(
        for window: AlignerWindow,
        in axMetadata: [AXWindowMetadata],
        matchAttempt: String = "initial"
    ) -> AXWindowMetadata? {
        if let directMatch = axMetadata.first(where: { $0.windowID == window.id }) {
            DevelopmentDiagnostics.log("windowClose.axMatch.directWindowID", [
                "windowID": window.id,
                "pid": window.app.processIdentifier,
                "attempt": matchAttempt
            ])
            return directMatch
        }

        guard let processIdentifier = window.app.processIdentifier else {
            return nil
        }

        if let cgFingerprint = cgWindowFingerprint(for: window) {
            let fingerprintMatches = axMetadata.filter { metadata in
                AXWindowFingerprint(metadata) == cgFingerprint
            }
            if fingerprintMatches.count == 1 {
                DevelopmentDiagnostics.log("windowClose.axMatch.fingerprint", [
                    "windowID": window.id,
                    "pid": processIdentifier,
                    "attempt": matchAttempt
                ])
                return fingerprintMatches[0]
            }

            if fingerprintMatches.count > 1 {
                DevelopmentDiagnostics.log("windowClose.axMatch.fingerprintAmbiguous", [
                    "windowID": window.id,
                    "pid": processIdentifier,
                    "candidateCount": fingerprintMatches.count
                ])
            }
        }

        let normalizedTitle = normalizedWindowTitle(window.title)
        let titleMatches = axMetadata.filter { metadata in
            metadata.processIdentifier == processIdentifier
                && normalizedWindowTitle(metadata.title ?? "") == normalizedTitle
        }
        if titleMatches.count == 1 {
            DevelopmentDiagnostics.log("windowClose.axMatch.normalizedTitle", [
                "windowID": window.id,
                "pid": processIdentifier,
                "attempt": matchAttempt
            ])
            return titleMatches[0]
        }

        if window.app.bundleIdentifier == "com.apple.finder",
           let finderMatch = finderFallbackAXWindow(
            for: window,
            processIdentifier: processIdentifier,
            in: axMetadata
           ) {
            DevelopmentDiagnostics.log("windowClose.axMatch.finderFallback", [
                "windowID": window.id,
                "pid": processIdentifier,
                "attempt": matchAttempt
            ])
            return finderMatch
        }

        if titleMatches.count > 1 {
            DevelopmentDiagnostics.log("windowClose.axMatch.titleAmbiguous", [
                "windowID": window.id,
                "pid": processIdentifier,
                "candidateCount": titleMatches.count
            ])
        }

        return nil
    }

    private func finderFallbackAXWindow(
        for window: AlignerWindow,
        processIdentifier: Int32,
        in axMetadata: [AXWindowMetadata]
    ) -> AXWindowMetadata? {
        let normalizedTitle = normalizedWindowTitle(window.title)
        guard !normalizedTitle.isEmpty else { return nil }

        let finderCandidates = axMetadata.filter { metadata in
            metadata.processIdentifier == processIdentifier
                && normalizedWindowTitle(metadata.title ?? "") == normalizedTitle
                && metadata.subrole == .standard
        }
        return finderCandidates.count == 1 ? finderCandidates[0] : nil
    }

    private func cgWindowFingerprint(for window: AlignerWindow) -> AXWindowFingerprint? {
        guard let rawWindows = CGWindowListCopyWindowInfo(
            [.optionIncludingWindow],
            CGWindowID(window.id)
        ) as? [[String: Any]],
              let rawWindow = rawWindows.first,
              let ownerPID = int32Value(rawWindow[kCGWindowOwnerPID as String])
        else {
            return nil
        }

        return AXWindowFingerprint(
            processIdentifier: ownerPID,
            title: normalizedWindowTitle(title(rawWindow: rawWindow, axWindow: nil)),
            size: bounds(rawWindow[kCGWindowBounds as String]).size
        )
    }

    private func matchingAXTitleCandidateCount(
        for window: AlignerWindow,
        in axMetadata: [AXWindowMetadata]
    ) -> Int {
        guard let processIdentifier = window.app.processIdentifier else { return 0 }
        let normalizedTitle = normalizedWindowTitle(window.title)
        return axMetadata.filter { metadata in
            metadata.processIdentifier == processIdentifier
                && normalizedWindowTitle(metadata.title ?? "") == normalizedTitle
        }.count
    }

    private func matchingAXSizeCandidateCount(
        for window: AlignerWindow,
        in axMetadata: [AXWindowMetadata]
    ) -> Int {
        guard let processIdentifier = window.app.processIdentifier,
              let cgFingerprint = cgWindowFingerprint(for: window)
        else {
            return 0
        }

        return axMetadata.filter { metadata in
            metadata.processIdentifier == processIdentifier
                && Int(metadata.size.width.rounded()) == cgFingerprint.width
                && Int(metadata.size.height.rounded()) == cgFingerprint.height
        }.count
    }

    func close(app: AlignerApp) throws -> WindowCloseResult {
        DevelopmentDiagnostics.log("windowClose.app.start", [
            "appName": app.name,
            "bundleIdentifier": app.bundleIdentifier,
            "pid": app.processIdentifier
        ])

        guard let processIdentifier = app.processIdentifier else {
            DevelopmentDiagnostics.log("windowClose.app.missingPID", [
                "appName": app.name,
                "bundleIdentifier": app.bundleIdentifier
            ])
            return .appNotFound
        }
        guard let runningApplication = NSRunningApplication(processIdentifier: processIdentifier) else {
            DevelopmentDiagnostics.log("windowClose.app.missingApplication", [
                "appName": app.name,
                "pid": processIdentifier
            ])
            return .appNotFound
        }

        let requested = runningApplication.terminate()
        DevelopmentDiagnostics.log("windowClose.app.result", [
            "appName": app.name,
            "pid": processIdentifier,
            "requested": requested
        ])
        return requested ? .requested : .failed("terminateFailed")
    }

    private func activateViaPrivateWindowServerAPI(_ window: AlignerWindow) -> PrivateWindowActivationOutcome? {
        guard window.identifierSource == .cgWindow,
              let processIdentifier = window.app.processIdentifier,
              let privateActivationBridge
        else {
            DevelopmentDiagnostics.log("windowActivation.privateActivation.skipped", [
                "windowID": window.id,
                "identifierSource": String(describing: window.identifierSource),
                "hasPID": window.app.processIdentifier != nil,
                "bridgeAvailable": privateActivationBridge != nil
            ])
            return nil
        }

        let outcome = privateActivationBridge.activate(
            processIdentifier: processIdentifier,
            windowID: window.id
        )
        DevelopmentDiagnostics.log("windowActivation.privateActivation.result", [
            "windowID": window.id,
            "pid": processIdentifier,
            "getProcessStatus": outcome.getProcessStatus,
            "setFrontError": outcome.setFrontError.map(String.init(describing:)),
            "makeKeyFirstError": outcome.makeKeyFirstError.map(String.init(describing:)),
            "makeKeySecondError": outcome.makeKeySecondError.map(String.init(describing:)),
            "succeeded": outcome.succeeded
        ])
        return outcome
    }

    private func focusTargetSpaceIfNeeded(for window: AlignerWindow) -> PrivateSpaceFocusOutcome? {
        guard window.identifierSource == .cgWindow,
              !window.spaceIDs.isEmpty,
              let privateSpaceActivationBridge
        else {
            DevelopmentDiagnostics.log("windowActivation.spaceFocus.skipped", [
                "windowID": window.id,
                "identifierSource": String(describing: window.identifierSource),
                "spaceIDCount": window.spaceIDs.count,
                "bridgeAvailable": privateSpaceActivationBridge != nil
            ])
            return nil
        }

        let outcome = privateSpaceActivationBridge.focus(spaceIDs: window.spaceIDs)
        DevelopmentDiagnostics.log("windowActivation.spaceFocus.result", [
            "windowID": window.id,
            "targetSpaceID": outcome?.targetSpaceID,
            "displayIdentifier": outcome?.displayIdentifier,
            "previousCurrentSpaceID": outcome?.previousCurrentSpaceID,
            "didRequestFocus": outcome?.didRequestFocus,
            "error": outcome?.error
        ])
        return outcome
    }

    private func windowRecords() throws -> [WindowEnumerationRecord] {
        guard let rawWindows = CGWindowListCopyWindowInfo(
            [.optionAll, .excludeDesktopElements],
            kCGNullWindowID
        ) as? [[String: Any]] else {
            return []
        }

        let axWindows = AXWindowMetadataReader.metadata(appCategorizer: appCategorizer)
        var axMetadata: [UInt32: AXWindowMetadata] = [:]
        for metadata in axWindows {
            if let windowID = metadata.windowID {
                axMetadata[windowID] = metadata
            }
        }
        let axBackedTitleKeys = Set(axMetadata.values.compactMap(AXWindowTitleKey.init))
        let cgWindowIDs = Set(rawWindows.compactMap { uint32Value($0[kCGWindowNumber as String]) })
        var fallbackAXMetadataByFingerprint: [AXWindowFingerprint: [AXWindowMetadata]] = [:]
        for metadata in axWindows {
            if let windowID = metadata.windowID, cgWindowIDs.contains(windowID) {
                continue
            }

            fallbackAXMetadataByFingerprint[AXWindowFingerprint(metadata), default: []].append(metadata)
        }
        let windowIDs = Array(cgWindowIDs.union(axMetadata.keys))
        let spaceIDsByWindowID = spaceIDsByWindowIDProvider(windowIDs)
        let cgWindowFingerprints = Set(rawWindows.compactMap { rawWindow -> AXWindowFingerprint? in
            guard let ownerPID = int32Value(rawWindow[kCGWindowOwnerPID as String]) else {
                return nil
            }

            let windowID = uint32Value(rawWindow[kCGWindowNumber as String])
            let axWindow = windowID.flatMap { axMetadata[$0] }
            return AXWindowFingerprint(
                processIdentifier: ownerPID,
                title: title(rawWindow: rawWindow, axWindow: axWindow),
                size: bounds(rawWindow[kCGWindowBounds as String]).size
            )
        })
        var occupiedWindowIDs = Set(windowIDs)
        var nextRestorableAXWindowsByID: [UInt32: RestorableAXWindow] = [:]
        var consumedAXMetadata = Set<AXWindowIdentity>()

        let cgRecords: [WindowEnumerationRecord] = rawWindows.compactMap { rawWindow in
            guard let windowID = uint32Value(rawWindow[kCGWindowNumber as String]) else {
                return nil
            }

            let rawBounds = bounds(rawWindow[kCGWindowBounds as String])
            let ownerPID = int32Value(rawWindow[kCGWindowOwnerPID as String])
            let runningApplication = ownerPID.flatMap(NSRunningApplication.init(processIdentifier:))
            let rawFingerprint = ownerPID.map {
                AXWindowFingerprint(
                    processIdentifier: $0,
                    title: title(rawWindow: rawWindow, axWindow: nil),
                    size: rawBounds.size
                )
            }
            let directAXWindow = axMetadata[windowID]
            let fallbackAXWindow = rawFingerprint.flatMap { fingerprint in
                fallbackAXMetadataByFingerprint[fingerprint]?.first { metadata in
                    !consumedAXMetadata.contains(AXWindowIdentity(metadata))
                }
            }
            let axWindow = directAXWindow ?? fallbackAXWindow
            let spaceIDs = spaceIDsByWindowID[windowID] ?? []
            let hasAXBackedTitleDuplicate = axWindow == nil
                && ownerPID.flatMap { AXWindowTitleKey(processIdentifier: $0, title: title(rawWindow: rawWindow, axWindow: nil)) }
                    .map { axBackedTitleKeys.contains($0) } == true
            let app = app(from: runningApplication, rawWindow: rawWindow, ownerPID: ownerPID)
            let record = WindowEnumerationRecord(
                id: windowID,
                app: app,
                activationPolicy: activationPolicy(from: runningApplication),
                title: title(rawWindow: rawWindow, axWindow: axWindow),
                size: rawBounds.size,
                frame: rawBounds,
                subrole: axWindow?.subrole ?? .standard,
                isMinimized: axWindow?.isMinimized ?? false,
                isFullscreen: !Set(spaceIDs).isDisjoint(with: fullscreenSpaceIDs),
                isGhost: isGhost(
                    rawWindow: rawWindow,
                    axWindow: axWindow,
                    app: app,
                    spaceIDs: spaceIDs,
                    hasAXBackedTitleDuplicate: hasAXBackedTitleDuplicate
                ),
                isDesktopElement: isDesktopElement(rawWindow: rawWindow, app: app),
                isSystemCritical: isSystemCritical(rawWindow: rawWindow, app: app),
                isInteractable: axWindow?.isInteractable ?? true,
                hasAXBacking: axWindow != nil,
                isOnscreen: boolValue(rawWindow[kCGWindowIsOnscreen as String]),
                spaceIDs: spaceIDs
            )

            if axWindow?.isMinimized == true, let axWindow {
                nextRestorableAXWindowsByID[windowID] = RestorableAXWindow(
                    processIdentifier: axWindow.processIdentifier,
                    element: axWindow.element
                )
            }
            if let axWindow, !record.isGhost {
                consumedAXMetadata.insert(AXWindowIdentity(axWindow))
            }

            return record
        }

        var axOnlyRecords: [WindowEnumerationRecord] = []
        for axWindow in axMetadata.values where axWindow.isMinimized {
            guard let windowID = axWindow.windowID else { continue }
            nextRestorableAXWindowsByID[windowID] = RestorableAXWindow(
                processIdentifier: axWindow.processIdentifier,
                element: axWindow.element
            )
        }

        for axWindow in axWindows {
            guard !consumedAXMetadata.contains(AXWindowIdentity(axWindow)) else { continue }
            guard axWindow.subrole.isExplicitlySupported else { continue }
            guard axWindow.hasExplicitSubrole else { continue }

            let resolvedWindowID: UInt32
            let identifierSource: AlignerWindow.IdentifierSource
            if let windowID = axWindow.windowID {
                guard !cgWindowIDs.contains(windowID) else { continue }
                resolvedWindowID = windowID
                identifierSource = .cgWindow
            } else if shouldCreateSyntheticAXFallback(for: axWindow) {
                guard !cgWindowFingerprints.contains(AXWindowFingerprint(axWindow)) else { continue }

                resolvedWindowID = MinimizedWindowFallbackPolicy.syntheticWindowID(
                    processIdentifier: axWindow.processIdentifier,
                    windowIndex: axWindow.windowIndex,
                    title: axWindow.title ?? "",
                    subroleDescription: axWindow.subrole.fallbackDescription,
                    occupiedWindowIDs: occupiedWindowIDs
                )
                occupiedWindowIDs.insert(resolvedWindowID)
                identifierSource = .syntheticAX
            } else {
                continue
            }

            let spaceIDs = spaceIDsByWindowID[resolvedWindowID] ?? []
            nextRestorableAXWindowsByID[resolvedWindowID] = RestorableAXWindow(
                processIdentifier: axWindow.processIdentifier,
                element: axWindow.element
            )
            axOnlyRecords.append(WindowEnumerationRecord(
                id: resolvedWindowID,
                app: axWindow.app,
                activationPolicy: axWindow.activationPolicy,
                title: axWindow.title ?? "",
                identifierSource: identifierSource,
                size: axWindow.size,
                frame: axWindow.frame,
                subrole: axWindow.subrole,
                isMinimized: axWindow.isMinimized,
                isFullscreen: !Set(spaceIDs).isDisjoint(with: fullscreenSpaceIDs),
                isGhost: false,
                isDesktopElement: false,
                isSystemCritical: isSystemCritical(app: axWindow.app),
                isInteractable: axWindow.isInteractable,
                hasAXBacking: true,
                isOnscreen: false,
                spaceIDs: spaceIDs
            ))
        }

        restorableAXWindowsByID = nextRestorableAXWindowsByID
        return cgRecords + axOnlyRecords
    }

    private func app(
        from runningApplication: NSRunningApplication?,
        rawWindow: [String: Any],
        ownerPID: Int32?
    ) -> AlignerApp {
        let bundleIdentifier = runningApplication?.bundleIdentifier ?? ""
        let name = runningApplication?.localizedName
            ?? stringValue(rawWindow[kCGWindowOwnerName as String])
            ?? "Unknown"
        let provisionalApp = AlignerApp(
            bundleIdentifier: bundleIdentifier,
            name: name,
            category: .generic,
            isHidden: runningApplication?.isHidden ?? false,
            executablePath: runningApplication?.bundleURL?.path,
            processIdentifier: ownerPID
        )

        return AlignerApp(
            bundleIdentifier: provisionalApp.bundleIdentifier,
            name: provisionalApp.name,
            category: appCategorizer.category(for: provisionalApp),
            isHidden: provisionalApp.isHidden,
            executablePath: provisionalApp.executablePath,
            processIdentifier: provisionalApp.processIdentifier
        )
    }

    private func activateApplication(for window: AlignerWindow) -> Bool {
        guard
            let processIdentifier = window.app.processIdentifier
        else {
            return false
        }

        return activateApplication(processIdentifier: processIdentifier)
    }

    private func activateApplication(processIdentifier: Int32) -> Bool {
        guard let application = NSRunningApplication(processIdentifier: processIdentifier) else {
            DevelopmentDiagnostics.log("windowActivation.activateApplication.missingApplication", [
                "pid": processIdentifier
            ])
            return false
        }

        let activated = application.activate(options: [.activateAllWindows])
        DevelopmentDiagnostics.log("windowActivation.activateApplication", [
            "pid": processIdentifier,
            "localizedName": application.localizedName,
            "bundleIdentifier": application.bundleIdentifier,
            "activationPolicy": application.activationPolicy.rawValue,
            "activateOptions": "activateAllWindows",
            "isActive": application.isActive,
            "result": activated
        ])
        return activated
    }

    private func focusWindowResult(_ window: AXUIElement, processIdentifier: Int32) -> AXActionResult {
        let appElement = AXUIElementCreateApplication(processIdentifier)
        let error = AXUIElementSetAttributeValue(
            appElement,
            kAXFocusedWindowAttribute as CFString,
            window
        )
        return AXActionResult(error: error)
    }

    private func raiseWindowResult(_ window: AXUIElement) -> AXActionResult {
        AXActionResult(error: AXUIElementPerformAction(window, kAXRaiseAction as CFString))
    }

    private func activationPolicy(from runningApplication: NSRunningApplication?) -> AlignerActivationPolicy {
        guard let runningApplication else { return .unknown }

        switch runningApplication.activationPolicy {
        case .regular:
            return .regular
        case .accessory:
            return .accessory
        case .prohibited:
            return .prohibited
        @unknown default:
            return .unknown
        }
    }

    private func title(rawWindow: [String: Any], axWindow: AXWindowMetadata?) -> String {
        if let axTitle = axWindow?.title, !axTitle.isEmpty {
            return axTitle
        }

        return stringValue(rawWindow[kCGWindowName as String]) ?? ""
    }

    private func isGhost(
        rawWindow: [String: Any],
        axWindow: AXWindowMetadata?,
        app: AlignerApp,
        spaceIDs: [UInt64],
        hasAXBackedTitleDuplicate: Bool = false
    ) -> Bool {
        let layer = intValue(rawWindow[kCGWindowLayer as String]) ?? 0
        let alpha = doubleValue(rawWindow[kCGWindowAlpha as String]) ?? 1
        let isOnscreen = boolValue(rawWindow[kCGWindowIsOnscreen as String])
        let rawTitle = stringValue(rawWindow[kCGWindowName as String]) ?? ""
        let rawBounds = bounds(rawWindow[kCGWindowBounds as String])

        if axWindow?.isMinimized == true {
            return false
        }
        if axWindow != nil {
            if alpha <= 0 {
                return true
            }
            if layer == 0 {
                return false
            }

            return !isOnscreen
        }
        if hasAXBackedTitleDuplicate {
            return true
        }
        if isKnownCGOnlyMainWindow(rawWindow: rawWindow, app: app) {
            return false
        }
        if !spaceIDs.isEmpty, isLikelyFullscreenAuxiliaryCGWindow(bounds: rawBounds) {
            return true
        }
        if rawTitle.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty, alpha < 0.99 {
            return true
        }
        if !spaceIDs.isEmpty {
            return layer != 0 || alpha <= 0
        }

        return layer != 0 || alpha <= 0 || !isOnscreen
    }

    private func isLikelyFullscreenAuxiliaryCGWindow(bounds: CGRect) -> Bool {
        bounds.width < 500 || bounds.height < 160
    }

    private func isKnownCGOnlyMainWindow(rawWindow: [String: Any], app: AlignerApp) -> Bool {
        let layer = intValue(rawWindow[kCGWindowLayer as String]) ?? 0
        let alpha = doubleValue(rawWindow[kCGWindowAlpha as String]) ?? 1
        let isOnscreen = boolValue(rawWindow[kCGWindowIsOnscreen as String])
        let title = stringValue(rawWindow[kCGWindowName as String]) ?? ""
        let rawBounds = bounds(rawWindow[kCGWindowBounds as String])
        let trimmedTitle = title.trimmingCharacters(in: .whitespacesAndNewlines)

        if app.bundleIdentifier == "cc.ffitch.shottr" {
            return isOnscreen
                && alpha > 0
                && trimmedTitle == "Shottr"
                && rawBounds.width > WindowEnumerationPolicy.minimumVisibleWidth
                && rawBounds.height > WindowEnumerationPolicy.minimumVisibleHeight
        }

        if app.bundleIdentifier == "com.apple.finder" {
            return layer == 0
                && alpha > 0
                && !trimmedTitle.isEmpty
                && rawBounds.width > WindowEnumerationPolicy.minimumVisibleWidth
                && rawBounds.height > WindowEnumerationPolicy.minimumVisibleHeight
        }

        guard app.bundleIdentifier == "io.dcloud.HBuilderX" else { return false }

        return layer == 0
            && alpha > 0
            && !isOnscreen
            && !trimmedTitle.isEmpty
            && rawBounds.width > WindowEnumerationPolicy.minimumVisibleWidth
            && rawBounds.height > WindowEnumerationPolicy.minimumVisibleHeight
    }

    private func isDesktopElement(rawWindow: [String: Any], app: AlignerApp) -> Bool {
        guard app.bundleIdentifier == "com.apple.finder" else { return false }
        let title = stringValue(rawWindow[kCGWindowName as String]) ?? ""
        let ownerName = stringValue(rawWindow[kCGWindowOwnerName as String]) ?? ""
        return title == "Desktop" || ownerName == "Dock"
    }

    private func isSystemCritical(rawWindow: [String: Any], app: AlignerApp) -> Bool {
        let title = stringValue(rawWindow[kCGWindowName as String]) ?? ""
        return SystemCriticalWindowClassifier.isSystemCritical(app: app)
            || SystemCriticalWindowClassifier.isSystemCriticalTitle(title)
    }

    private func isSystemCritical(app: AlignerApp) -> Bool {
        SystemCriticalWindowClassifier.isSystemCritical(app: app)
    }

    private func shouldCreateSyntheticAXFallback(for axWindow: AXWindowMetadata) -> Bool {
        MinimizedWindowFallbackPolicy.shouldCreateAXOnlyFallback(
            hasCGWindowID: axWindow.windowID != nil,
            isMinimized: axWindow.isMinimized
        )
    }

    private static func restoreResultString(_ result: WindowRestoreResult) -> String {
        switch result {
        case .restored:
            return "restored"
        case .windowNotFound:
            return "windowNotFound"
        case .unsupported:
            return "unsupported"
        case .activationFailed:
            return "activationFailed"
        }
    }

}

private struct AXWindowMetadata {
    let windowID: UInt32?
    let app: AlignerApp
    let activationPolicy: AlignerActivationPolicy
    let title: String?
    let isMinimized: Bool
    let size: CGSize
    let frame: CGRect?
    let subrole: AlignerWindowSubrole
    let hasExplicitSubrole: Bool
    let isInteractable: Bool
    let processIdentifier: Int32
    let windowIndex: Int
    let element: AXUIElement
}

private struct AXWindowIdentity: Hashable {
    let processIdentifier: Int32
    let windowID: UInt32?
    let windowIndex: Int

    init(_ metadata: AXWindowMetadata) {
        processIdentifier = metadata.processIdentifier
        windowID = metadata.windowID
        windowIndex = metadata.windowIndex
    }
}

private struct AXWindowTitleKey: Hashable {
    let processIdentifier: Int32
    let title: String

    init?(processIdentifier: Int32, title: String?) {
        let normalizedTitle = title?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        guard !normalizedTitle.isEmpty else { return nil }

        self.processIdentifier = processIdentifier
        self.title = normalizedTitle
    }

    init?(_ metadata: AXWindowMetadata) {
        self.init(processIdentifier: metadata.processIdentifier, title: metadata.title)
    }
}

private struct AXWindowFingerprint: Hashable {
    let processIdentifier: Int32
    let title: String
    let width: Int
    let height: Int

    init(processIdentifier: Int32, title: String, size: CGSize) {
        self.processIdentifier = processIdentifier
        self.title = title
        self.width = Int(size.width.rounded())
        self.height = Int(size.height.rounded())
    }

    init(_ metadata: AXWindowMetadata) {
        self.init(
            processIdentifier: metadata.processIdentifier,
            title: metadata.title ?? "",
            size: metadata.size
        )
    }
}

private struct RestorableAXWindow {
    let processIdentifier: Int32
    let element: AXUIElement
}

private struct AXActionResult {
    let error: AXError

    var success: Bool {
        error == .success
    }
}

private enum AXWindowRestoreError: Error {
    case setMinimizedFailed(AXError)
    case raiseFailed(AXError)
}

private enum AXWindowMetadataReader {
    static func metadata(appCategorizer: any AppCategorizer) -> [AXWindowMetadata] {
        var result: [AXWindowMetadata] = []

        for application in NSWorkspace.shared.runningApplications {
            guard application.activationPolicy == .regular else { continue }
            let app = app(from: application, appCategorizer: appCategorizer)

            let appElement = AXUIElementCreateApplication(application.processIdentifier)
            let windows = windows(for: appElement)
            guard !windows.isEmpty else { continue }

            for (windowIndex, window) in windows.enumerated() {
                let subrole = subrole(for: window)
                let size = size(for: window)
                let position = position(for: window)
                result.append(AXWindowMetadata(
                    windowID: windowID(for: window),
                    app: app,
                    activationPolicy: activationPolicy(from: application),
                    title: title(for: window),
                    isMinimized: boolAttribute(kAXMinimizedAttribute as String, for: window) ?? false,
                    size: size,
                    frame: position.map { CGRect(origin: $0, size: size) },
                    subrole: subrole.value,
                    hasExplicitSubrole: subrole.isExplicit,
                    isInteractable: boolAttribute(kAXEnabledAttribute as String, for: window) ?? true,
                    processIdentifier: application.processIdentifier,
                    windowIndex: windowIndex,
                    element: window
                ))
            }
        }

        return result
    }

    private static func windows(for appElement: AXUIElement) -> [AXUIElement] {
        var result: [AXUIElement] = []
        var seen = Set<AXWindowElementKey>()

        func append(_ window: AXUIElement) {
            let key = AXWindowElementKey(window)
            guard !seen.contains(key) else { return }
            seen.insert(key)
            result.append(window)
        }

        var windowsValue: CFTypeRef?
        if AXUIElementCopyAttributeValue(appElement, kAXWindowsAttribute as CFString, &windowsValue) == .success,
           let windows = windowsValue as? [AXUIElement] {
            windows.forEach(append)
        }

        for attribute in [kAXFocusedWindowAttribute, kAXMainWindowAttribute] {
            var windowValue: CFTypeRef?
            guard AXUIElementCopyAttributeValue(appElement, attribute as CFString, &windowValue) == .success,
                  let window = windowValue,
                  CFGetTypeID(window) == AXUIElementGetTypeID()
            else {
                continue
            }

            append(window as! AXUIElement)
        }

        return result
    }

    private static func app(
        from application: NSRunningApplication,
        appCategorizer: any AppCategorizer
    ) -> AlignerApp {
        let provisionalApp = AlignerApp(
            bundleIdentifier: application.bundleIdentifier ?? "",
            name: application.localizedName ?? "Unknown",
            category: .generic,
            isHidden: application.isHidden,
            executablePath: application.bundleURL?.path,
            processIdentifier: application.processIdentifier
        )

        return AlignerApp(
            bundleIdentifier: provisionalApp.bundleIdentifier,
            name: provisionalApp.name,
            category: appCategorizer.category(for: provisionalApp),
            isHidden: provisionalApp.isHidden,
            executablePath: provisionalApp.executablePath,
            processIdentifier: provisionalApp.processIdentifier
        )
    }

    private static func activationPolicy(from application: NSRunningApplication) -> AlignerActivationPolicy {
        switch application.activationPolicy {
        case .regular:
            return .regular
        case .accessory:
            return .accessory
        case .prohibited:
            return .prohibited
        @unknown default:
            return .unknown
        }
    }

    private static func windowID(for window: AXUIElement) -> UInt32? {
        var value: CFTypeRef?
        if AXUIElementCopyAttributeValue(window, "AXWindowNumber" as CFString, &value) == .success,
           let windowID = uint32Value(value) {
            return windowID
        }

        return PrivateAXWindowIDReader.windowID(for: window)
    }

    private static func title(for window: AXUIElement) -> String? {
        var value: CFTypeRef?
        guard AXUIElementCopyAttributeValue(window, kAXTitleAttribute as CFString, &value) == .success else {
            return nil
        }

        return value as? String
    }

    private static func boolAttribute(_ attribute: String, for window: AXUIElement) -> Bool? {
        var value: CFTypeRef?
        guard AXUIElementCopyAttributeValue(window, attribute as CFString, &value) == .success else {
            return nil
        }

        return boolValue(value)
    }

    private static func size(for window: AXUIElement) -> CGSize {
        var value: CFTypeRef?
        guard AXUIElementCopyAttributeValue(window, kAXSizeAttribute as CFString, &value) == .success,
              let axValue = value,
              CFGetTypeID(axValue) == AXValueGetTypeID()
        else {
            return .zero
        }

        var size = CGSize.zero
        guard AXValueGetValue(axValue as! AXValue, .cgSize, &size) else {
            return .zero
        }

        return size
    }

    private static func position(for window: AXUIElement) -> CGPoint? {
        var value: CFTypeRef?
        guard AXUIElementCopyAttributeValue(window, kAXPositionAttribute as CFString, &value) == .success,
              let axValue = value,
              CFGetTypeID(axValue) == AXValueGetTypeID()
        else {
            return nil
        }

        var position = CGPoint.zero
        guard AXValueGetValue(axValue as! AXValue, .cgPoint, &position) else {
            return nil
        }

        return position
    }

    private static func subrole(for window: AXUIElement) -> (value: AlignerWindowSubrole, isExplicit: Bool) {
        var value: CFTypeRef?
        guard AXUIElementCopyAttributeValue(window, kAXSubroleAttribute as CFString, &value) == .success,
              let subrole = value as? String
        else {
            return (.standard, false)
        }

        switch subrole {
        case "AXStandardWindow":
            return (.standard, true)
        case "AXDialog", "AXModalDialog":
            return (.dialog, true)
        case "AXSheet":
            return (.sheet, true)
        default:
            return (.unknown(subrole), true)
        }
    }
}

private struct AXWindowElementKey: Hashable {
    private let typeID: CFTypeID
    private let pointer: UInt
    private let windowID: UInt32?

    init(_ element: AXUIElement) {
        self.typeID = CFGetTypeID(element)
        self.pointer = UInt(bitPattern: Unmanaged.passUnretained(element).toOpaque())
        self.windowID = PrivateAXWindowIDReader.windowID(for: element)
    }

    static func == (lhs: AXWindowElementKey, rhs: AXWindowElementKey) -> Bool {
        if let lhsWindowID = lhs.windowID,
           let rhsWindowID = rhs.windowID {
            return lhsWindowID == rhsWindowID
        }

        return lhs.typeID == rhs.typeID && lhs.pointer == rhs.pointer
    }

    func hash(into hasher: inout Hasher) {
        if let windowID {
            hasher.combine("windowID")
            hasher.combine(windowID)
            return
        }

        hasher.combine("pointer")
        hasher.combine(typeID)
        hasher.combine(pointer)
    }
}

private extension AlignerWindowSubrole {
    var isExplicitlySupported: Bool {
        switch self {
        case .standard, .dialog, .sheet:
            return true
        case .unknown:
            return false
        }
    }

    var fallbackDescription: String {
        switch self {
        case .standard:
            return "standard"
        case .dialog:
            return "dialog"
        case .sheet:
            return "sheet"
        case .unknown(let rawValue):
            return rawValue
        }
    }
}

private func bounds(_ value: Any?) -> CGRect {
    guard let dictionary = value as? NSDictionary else {
        return .zero
    }

    var rect = CGRect.zero
    CGRectMakeWithDictionaryRepresentation(dictionary as CFDictionary, &rect)
    return rect
}

private func stringValue(_ value: Any?) -> String? {
    value as? String
}

private func normalizedWindowTitle(_ title: String) -> String {
    title.trimmingCharacters(in: .whitespacesAndNewlines)
}

private func boolValue(_ value: Any?) -> Bool {
    switch value {
    case let bool as Bool:
        return bool
    case let number as NSNumber:
        return number.boolValue
    default:
        return false
    }
}

private func intValue(_ value: Any?) -> Int? {
    switch value {
    case let number as NSNumber:
        return number.intValue
    case let int as Int:
        return int
    default:
        return nil
    }
}

private func int32Value(_ value: Any?) -> Int32? {
    switch value {
    case let number as NSNumber:
        return number.int32Value
    case let int32 as Int32:
        return int32
    case let int as Int:
        return Int32(int)
    default:
        return nil
    }
}

private func uint32Value(_ value: Any?) -> UInt32? {
    switch value {
    case let number as NSNumber:
        return number.uint32Value
    case let uint32 as UInt32:
        return uint32
    case let int as Int where int >= 0:
        return UInt32(int)
    default:
        return nil
    }
}

private func doubleValue(_ value: Any?) -> Double? {
    switch value {
    case let number as NSNumber:
        return number.doubleValue
    case let double as Double:
        return double
    default:
        return nil
    }
}
