import Foundation

public enum AlignerSpaceType: Equatable, Sendable {
    case user
    case fullscreen
    case system
    case unknown(Int)
}

public struct AlignerSpace: Equatable, Sendable {
    public let id: UInt64
    public let type: AlignerSpaceType
    public let displayUUID: String
    public let index: Int

    public init(id: UInt64, type: AlignerSpaceType, displayUUID: String, index: Int) {
        self.id = id
        self.type = type
        self.displayUUID = displayUUID
        self.index = index
    }
}

public struct AlignerDisplay: Equatable, Sendable {
    public let uuid: String
    public let physical: Bool
    public let spaces: [AlignerSpace]

    public init(uuid: String, physical: Bool, spaces: [AlignerSpace]) {
        self.uuid = uuid
        self.physical = physical
        self.spaces = spaces
    }
}

public enum AppCategory: String, CaseIterable, Equatable, Sendable {
    case finder
    case browser
    case terminal
    case editorIDE
    case chat
    case documentNotes
    case generic
}

public struct AlignerApp: Equatable, Sendable {
    public let bundleIdentifier: String
    public let name: String
    public let category: AppCategory
    public let isHidden: Bool
    public let executablePath: String?
    public let processIdentifier: Int32?

    public init(
        bundleIdentifier: String,
        name: String,
        category: AppCategory,
        isHidden: Bool = false,
        executablePath: String? = nil,
        processIdentifier: Int32? = nil
    ) {
        self.bundleIdentifier = bundleIdentifier
        self.name = name
        self.category = category
        self.isHidden = isHidden
        self.executablePath = executablePath
        self.processIdentifier = processIdentifier
    }
}

public struct AlignerWindow: Equatable, Sendable {
    public enum IdentifierSource: Equatable, Sendable {
        case cgWindow
        case syntheticAX
    }

    public let id: UInt32
    public let identifierSource: IdentifierSource
    public let app: AlignerApp
    public let title: String
    public let isMinimized: Bool
    public let isFullscreen: Bool
    public let isGhost: Bool
    public let spaceIDs: [UInt64]

    public init(
        id: UInt32,
        app: AlignerApp,
        title: String,
        identifierSource: IdentifierSource = .cgWindow,
        isMinimized: Bool = false,
        isFullscreen: Bool = false,
        isGhost: Bool = false,
        spaceIDs: [UInt64] = []
    ) {
        self.id = id
        self.identifierSource = identifierSource
        self.app = app
        self.title = title
        self.isMinimized = isMinimized
        self.isFullscreen = isFullscreen
        self.isGhost = isGhost
        self.spaceIDs = spaceIDs
    }
}

public enum WindowDisplayPolicy {
    public static func shouldDisplay(_ window: AlignerWindow) -> Bool {
        (!window.app.isHidden || window.isFullscreen) && !window.isGhost
    }
}
