import AppKit
import AlignerCore

@MainActor
final class Round0DebugOverlayController {
    static let overlayTitle = "Aligner Round0 Debug Overlay"
    static let settingsTitle = "Aligner Round0 Debug Settings"

    private let overlayHost: QuickSwitchOverlayHost
    private var settingsWindow: NSWindow?

    init() {
        overlayHost = QuickSwitchOverlayHost(
            title: Self.overlayTitle,
            contentView: Self.makeOverlayView()
        )
    }

    func show(includeSettingsChild: Bool) {
        overlayHost.show(context: OverlayContext(entryPoint: .quickSwitch))

        if includeSettingsChild {
            attachSettingsChild()
        }
    }

    func hide() {
        if let settingsWindow {
            overlayHost.detachChild(settingsWindow)
            settingsWindow.orderOut(nil)
        }
        settingsWindow = nil
        overlayHost.hide(reason: .userClosed)
    }

    private func attachSettingsChild() {
        if settingsWindow == nil {
            settingsWindow = Self.makeSettingsWindow()
        }

        guard let settingsWindow else { return }
        settingsWindow.center()
        overlayHost.attachChild(settingsWindow)
        settingsWindow.orderFrontRegardless()
    }

    private static func makeOverlayView() -> NSView {
        let root = NSVisualEffectView()
        root.material = .hudWindow
        root.blendingMode = .behindWindow
        root.state = .active
        root.translatesAutoresizingMaskIntoConstraints = false

        let label = NSTextField(labelWithString: "Round0 Debug Overlay")
        label.font = .systemFont(ofSize: 24, weight: .semibold)
        label.textColor = .white
        label.alignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false

        root.addSubview(label)
        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: root.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: root.centerYAnchor)
        ])

        return root
    }

    private static func makeSettingsWindow() -> NSWindow {
        let window = NSWindow(
            contentRect: NSRect(x: 0, y: 0, width: 360, height: 180),
            styleMask: [.titled, .closable],
            backing: .buffered,
            defer: false
        )
        window.title = settingsTitle
        window.isReleasedWhenClosed = false

        let label = NSTextField(wrappingLabelWithString: "Round0 Settings Child Window")
        label.font = .systemFont(ofSize: 17, weight: .semibold)
        label.alignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false

        let content = NSView()
        content.addSubview(label)
        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: content.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: content.centerYAnchor),
            label.leadingAnchor.constraint(greaterThanOrEqualTo: content.leadingAnchor, constant: 24),
            label.trailingAnchor.constraint(lessThanOrEqualTo: content.trailingAnchor, constant: -24)
        ])
        window.contentView = content
        return window
    }
}

struct Round0DebugLaunchOptions {
    let skipPermissions: Bool
    let showOverlay: Bool
    let showSettingsChild: Bool
    let autoHideAfter: TimeInterval?
    let quitAfter: TimeInterval?

    static func parse(arguments: [String]) -> Round0DebugLaunchOptions {
        Round0DebugLaunchOptions(
            skipPermissions: arguments.contains("--round0-skip-permissions"),
            showOverlay: arguments.contains("--round0-debug-overlay"),
            showSettingsChild: arguments.contains("--round0-debug-settings-child"),
            autoHideAfter: timeInterval(for: "--round0-debug-auto-hide-after", in: arguments),
            quitAfter: timeInterval(for: "--round0-debug-quit-after", in: arguments)
        )
    }

    private static func timeInterval(for key: String, in arguments: [String]) -> TimeInterval? {
        let prefix = "\(key)="
        guard let argument = arguments.first(where: { $0.hasPrefix(prefix) }) else {
            return nil
        }

        return TimeInterval(argument.dropFirst(prefix.count))
    }
}
