//
//  KMScreenShotMaskWindowController.swift
//  PDF Reader Pro
//
//  Created by liujiajie on 2024/1/24.
//

import Cocoa

let ktimeLabelWidthAndHeight: CGFloat = 100
let kdefauletDelaytime: CGFloat = 5

class KMScreenShotMaskWindowController: NSWindowController{
    var maskViewController: KMScreenShotMaskViewController!
    @IBOutlet var timeLabel: NSTextField!
    var fullScreenCallBack: captureScreenCallBack?
    var countDownTimer: Timer?
    
    var countDownSurplusTime: Int = 0
    var localMonitor: Any?
    var globalMonitor: Any?
    
    deinit {
        NotificationCenter.default.removeObserver(self)
        if (countDownTimer != nil){
            countDownTimer?.invalidate()
            countDownTimer = nil
        }
    }
    convenience init( handler: @escaping captureScreenCallBack) {
        self.init(windowNibName: "KMScreenShotMaskWindowController")
        self.window?.backgroundColor = .clear
        self.window?.isOpaque = false
        let screen = NSScreen.screens.first
        self.window?.setFrame(screen?.frame ?? .zero, display: false)
        self.window?.level =  NSWindow.Level(Int(kCGOverlayWindowLevel)) //NSWindow.Level(rawValue: Int(kCGOverlayWindowLevel))
        self.maskViewController = KMScreenShotMaskViewController(callB: handler)
        self.maskViewController.view.frame = self.window?.frame ?? .zero
        self.window?.contentView!.addSubview(self.maskViewController.view)
        self.timeLabel.isHidden = true
    }
    
    convenience init(fullScreenShot delayTime: Int, completeHandler:  @escaping captureScreenCallBack) {
        self.init(windowNibName: "KMScreenShotMaskWindowController")
        self.countDownSurplusTime = delayTime
        self.window?.backgroundColor = NSColor.black
        if let screen = NSScreen.screens.first {
            self.window?.setFrame(NSRect(x: screen.frame.size.width/2 - ktimeLabelWidthAndHeight/2, y: screen.frame.size.height/2 - ktimeLabelWidthAndHeight/2, width: ktimeLabelWidthAndHeight, height: ktimeLabelWidthAndHeight), display: false)
        }
        self.window?.level = NSWindow.Level(Int(kCGOverlayWindowLevel))
        self.timeLabel.font = NSFont.systemFont(ofSize: 100)
        self.timeLabel.textColor = NSColor.white
        self.window?.alphaValue = 0.3
        self.timeLabel.integerValue = self.countDownSurplusTime
        self.timeLabel.sizeToFit()
        self.timeLabel.frame = NSRect(x: (ktimeLabelWidthAndHeight - self.timeLabel.frame.size.width)/2, y: (ktimeLabelWidthAndHeight - self.timeLabel.frame.size.height)/2, width: self.timeLabel.frame.size.width, height: self.timeLabel.frame.size.height)
        if delayTime == 0 {
            self.window?.setIsVisible(false)
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                let ima = KMScreenShotHandler.fullScreenShot()
                completeHandler(ima)
            }
        } else {
            self.timeLabel.isHidden = false
            let sel = NSSelectorFromString("countTimer_Method:")
            self.countDownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: sel, userInfo: nil, repeats: true)
            
            RunLoop.current.add(self.countDownTimer!, forMode: .common)
            self.fullScreenCallBack = completeHandler
            if self.localMonitor == nil {
                let mask: NSEvent.EventTypeMask = [.leftMouseDown, .keyDown]
                self.localMonitor = NSEvent.addLocalMonitorForEvents(matching: mask, handler: { (event) -> NSEvent? in
                    if event.type == .keyDown {
                        if event.keyCode == 53 {
                            self.endFullScreenShot()
                            self.fullScreenCallBack?(nil)
                        }
                    }
                    return nil
                })
            }
            if self.globalMonitor == nil {
                self.globalMonitor = NSEvent.addGlobalMonitorForEvents(matching: .keyDown, handler: { (event) in
                    if event.type == .keyDown {
                        if event.keyCode == 53 {
                            self.endFullScreenShot()
                            self.fullScreenCallBack?(nil)
                        }
                    }
                })
            }
        }
        NotificationCenter.default.addObserver(self, selector: #selector(cancelCurrentCapturingAction(notification:)), name: NSNotification.Name(KMCancelCurrentCapturingActionNotification), object: nil)
    }
    @objc func cancelCurrentCapturingAction(notification: Notification) {
        DispatchQueue.main.async {
            self.endFullScreenShot()
        }
    }
    func endFullScreenShot() {
        self.countDownTimer?.invalidate()
        self.window?.setIsVisible(false)
        NSEvent.removeMonitor(self.localMonitor as Any)
        self.localMonitor = nil
        NSEvent.removeMonitor(self.globalMonitor as Any)
        self.globalMonitor = nil
    }
    @objc func countTimer_Method(_ sender: Any) {
        self.countDownSurplusTime -= 1
        self.timeLabel.integerValue = self.countDownSurplusTime
        if self.countDownSurplusTime == 0 {
            self.endFullScreenShot()
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                let ima = KMScreenShotHandler.fullScreenShot()
                self.fullScreenCallBack?(ima)
            }
        }
    }
    override func windowDidLoad() {
        super.windowDidLoad()
    }
    
    func beginImageCapture(_ isCaptureWindow: Bool) { self.maskViewController.beginImageCapture(isCaptureWindow)
        if isCaptureWindow {
            let cursor = NSCursor(image: NSImage(named: "cameraCursor") ?? NSImage(), hotSpot: NSPoint(x: 0, y: 0))
            cursor.set()
            self.showScreenShotHint(NSLocalizedString("Move the camera over the window you want to capture.", comment: ""))
        } else {
            NSCursor.crosshair.set()
            self.showScreenShotHint(NSLocalizedString("Drag the crosshair over the area you want to capture.", comment: ""))
        }
    }
    
    func showScreenShotHint(_ hintMsg: String) {
        let topBottomGap: CGFloat = 10
        let texfield = NSTextField()
        texfield.isBordered = false
        texfield.font = NSFont.systemFont(ofSize: 20)
        texfield.textColor = NSColor.white
        texfield.backgroundColor = NSColor.clear
        texfield.stringValue = hintMsg
        texfield.sizeToFit()
        let hintContainer = NSView()
        hintContainer.wantsLayer = true
        hintContainer.layer?.backgroundColor = NSColor.black.cgColor
        hintContainer.addSubview(texfield)
        
        var containerFrame = hintContainer.frame
        containerFrame.size.height = texfield.frame.size.height + topBottomGap * 2
        containerFrame.size.width = texfield.frame.size.width + containerFrame.size.height
        containerFrame.origin.x = ((self.window?.contentView?.frame.size.width ?? 0) - containerFrame.size.width) / 2
        containerFrame.origin.y = ((self.window?.contentView?.frame.size.height ?? 0) - containerFrame.size.height) / 2
        hintContainer.frame = containerFrame
        
        var textfieldFrame = texfield.frame
        textfieldFrame.origin.x = (containerFrame.size.width - texfield.frame.size.width) / 2
        textfieldFrame.origin.y = topBottomGap
        texfield.frame = textfieldFrame
        
        hintContainer.layer?.cornerRadius = containerFrame.size.height / 2
        self.window?.contentView?.addSubview(hintContainer)
        
        NSAnimationContext.runAnimationGroup({ (context) in
            context.duration = 3
            hintContainer.animator().alphaValue = 0.0
        }, completionHandler: {
            
        })
    }
}