import CoreGraphics
import Foundation

public enum AlignerActivationPolicy: Equatable, Sendable {
    case regular
    case accessory
    case prohibited
    case unknown
}

public enum AlignerWindowSubrole: Equatable, Sendable {
    case standard
    case dialog
    case sheet
    case unknown(String)
}

public struct WindowEnumerationRecord: Equatable, Sendable {
    public let id: UInt32
    public let identifierSource: AlignerWindow.IdentifierSource
    public let app: AlignerApp
    public let activationPolicy: AlignerActivationPolicy
    public let title: String
    public let size: CGSize
    public let frame: CGRect?
    public let subrole: AlignerWindowSubrole
    public let isMinimized: Bool
    public let isFullscreen: Bool
    public let isGhost: Bool
    public let isDesktopElement: Bool
    public let isSystemCritical: Bool
    public let isInteractable: Bool
    public let hasAXBacking: Bool
    public let isOnscreen: Bool
    public let spaceIDs: [UInt64]

    public init(
        id: UInt32,
        app: AlignerApp,
        activationPolicy: AlignerActivationPolicy = .regular,
        title: String,
        identifierSource: AlignerWindow.IdentifierSource = .cgWindow,
        size: CGSize,
        frame: CGRect? = nil,
        subrole: AlignerWindowSubrole,
        isMinimized: Bool = false,
        isFullscreen: Bool = false,
        isGhost: Bool = false,
        isDesktopElement: Bool = false,
        isSystemCritical: Bool = false,
        isInteractable: Bool = true,
        hasAXBacking: Bool = false,
        isOnscreen: Bool = false,
        spaceIDs: [UInt64] = []
    ) {
        self.id = id
        self.identifierSource = identifierSource
        self.app = app
        self.activationPolicy = activationPolicy
        self.title = title
        self.size = size
        self.frame = frame
        self.subrole = subrole
        self.isMinimized = isMinimized
        self.isFullscreen = isFullscreen
        self.isGhost = isGhost
        self.isDesktopElement = isDesktopElement
        self.isSystemCritical = isSystemCritical
        self.isInteractable = isInteractable
        self.hasAXBacking = hasAXBacking
        self.isOnscreen = isOnscreen
        self.spaceIDs = spaceIDs
    }
}

public enum WindowEnumerationPolicy {
    public static let minimumVisibleWidth: CGFloat = 100
    public static let minimumVisibleHeight: CGFloat = 50

    public static func shouldInclude(_ record: WindowEnumerationRecord) -> Bool {
        guard record.id != 0 else { return false }
        guard hasSupportedActivationPolicy(record) else { return false }
        guard isSupportedSubrole(record.subrole) else { return false }
        guard !record.app.isHidden || record.isFullscreen else { return false }
        guard !record.isGhost else { return false }
        guard !record.isDesktopElement else { return false }
        guard !record.isSystemCritical else { return false }
        guard record.isInteractable else { return false }
        guard !isKnownClosedShottrCGPlaceholder(record) else { return false }
        guard !isCGOnlyOffscreenGhost(record) else { return false }
        guard !isKnownClosedDocumentPlaceholder(record) else { return false }

        return record.isMinimized || record.isFullscreen || isLargeEnough(record.size)
    }

    private static func hasSupportedActivationPolicy(_ record: WindowEnumerationRecord) -> Bool {
        record.activationPolicy == .regular
            || (record.activationPolicy == .accessory && isKnownAccessoryMainWindow(record))
    }

    public static func window(from record: WindowEnumerationRecord) -> AlignerWindow? {
        guard shouldInclude(record) else { return nil }

        return AlignerWindow(
            id: record.id,
            app: record.app,
            title: displayTitle(for: record),
            identifierSource: record.identifierSource,
            isMinimized: record.isMinimized,
            isFullscreen: record.isFullscreen,
            isGhost: record.isGhost,
            frame: record.frame,
            spaceIDs: record.spaceIDs
        )
    }

    private static func isSupportedSubrole(_ subrole: AlignerWindowSubrole) -> Bool {
        switch subrole {
        case .standard, .dialog, .sheet:
            return true
        case .unknown:
            return false
        }
    }

    private static func isLargeEnough(_ size: CGSize) -> Bool {
        size.width > minimumVisibleWidth && size.height > minimumVisibleHeight
    }

    private static func isCGOnlyOffscreenGhost(_ record: WindowEnumerationRecord) -> Bool {
        guard record.identifierSource == .cgWindow,
              !record.hasAXBacking,
              !record.isOnscreen,
              !record.isMinimized,
              !record.isFullscreen
        else {
            return false
        }

        if !record.spaceIDs.isEmpty {
            return false
        }

        return !isKnownCGOnlyOffscreenMainWindow(record)
    }

    private static func isKnownCGOnlyOffscreenMainWindow(_ record: WindowEnumerationRecord) -> Bool {
        let trimmedTitle = record.title.trimmingCharacters(in: .whitespacesAndNewlines)

        switch record.app.bundleIdentifier {
        case "com.apple.finder":
            return !trimmedTitle.isEmpty && isLargeEnough(record.size)
        case "io.dcloud.HBuilderX":
            return !trimmedTitle.isEmpty && isLargeEnough(record.size)
        default:
            return false
        }
    }

    private static func isKnownAccessoryMainWindow(_ record: WindowEnumerationRecord) -> Bool {
        let trimmedTitle = record.title.trimmingCharacters(in: .whitespacesAndNewlines)

        return record.app.bundleIdentifier == "cc.ffitch.shottr"
            && trimmedTitle == "Shottr"
            && record.isOnscreen
            && isLargeEnough(record.size)
    }

    private static func isKnownClosedShottrCGPlaceholder(_ record: WindowEnumerationRecord) -> Bool {
        let trimmedTitle = record.title.trimmingCharacters(in: .whitespacesAndNewlines)

        return record.app.bundleIdentifier == "cc.ffitch.shottr"
            && trimmedTitle == "Shottr"
            && record.identifierSource == .cgWindow
            && !record.hasAXBacking
            && !record.isOnscreen
            && !record.isMinimized
            && !record.isFullscreen
    }

    private static func isKnownClosedDocumentPlaceholder(_ record: WindowEnumerationRecord) -> Bool {
        let trimmedTitle = record.title.trimmingCharacters(in: .whitespacesAndNewlines)
        return record.identifierSource == .cgWindow
            && record.app.bundleIdentifier == "app.vmark"
            && trimmedTitle.isEmpty
            && !record.hasAXBacking
            && !record.isOnscreen
            && !record.isMinimized
            && !record.isFullscreen
    }

    private static func displayTitle(for record: WindowEnumerationRecord) -> String {
        let trimmedTitle = record.title.trimmingCharacters(in: .whitespacesAndNewlines)
        guard trimmedTitle.isEmpty else { return record.title }

        return "\(record.app.name) Untitled"
    }
}
