import AppKit
import SwiftUI

/// Borderless, floating NSPanel that hosts the notch overlay.
/// When the notch is open the window accepts key status so the
/// terminal can receive keyboard input. On resignKey the
/// `onResignKey` closure fires to close the notch.
class NotchWindow: NSPanel {

    var isNotchOpen: Bool = false

    /// Called when the window loses key status while the notch is open.
    var onResignKey: (() -> Void)?

    override init(
        contentRect: NSRect,
        styleMask style: NSWindow.StyleMask,
        backing backingStoreType: NSWindow.BackingStoreType,
        defer flag: Bool
    ) {
        // Start as a plain borderless utility panel.
        // .nonactivatingPanel is NOT included so the window can
        // properly accept key status when the notch opens.
        super.init(
            contentRect: contentRect,
            styleMask: [.borderless, .utilityWindow, .nonactivatingPanel],
            backing: .buffered,
            defer: flag
        )
        configureWindow()
    }

    private func configureWindow() {
        isOpaque = false
        backgroundColor = .clear

        isFloatingPanel = true
        level = .mainMenu + 3

        titleVisibility = .hidden
        titlebarAppearsTransparent = true
        hasShadow = false

        isMovable = false
        isMovableByWindowBackground = false

        collectionBehavior = [
            .canJoinAllSpaces,
            .stationary,
            .fullScreenAuxiliary,
            .ignoresCycle
        ]

        appearance = NSAppearance(named: .darkAqua)

        // Accepts mouse events when the app is NOT active so the
        // user can click the closed notch to open it.
        acceptsMouseMovedEvents = true
    }

    // MARK: - Key window management

    override var canBecomeKey: Bool { isNotchOpen }
    override var canBecomeMain: Bool { false }

    override func resignKey() {
        super.resignKey()
        if isNotchOpen {
            // Brief async dispatch so the new key window settles first —
            // avoids closing when we're just transferring focus between
            // our own windows (e.g. opening settings).
            DispatchQueue.main.async { [weak self] in
                guard let self, self.isNotchOpen else { return }
                self.onResignKey?()
            }
        }
    }
}
