//
//  DetailWebView.swift
//  NetNewsWire
//
//  Created by Brent Simmons on 2/10/18.
//  Copyright © 2018 Ranchero Software. All rights reserved.
//

import AppKit
import WebKit
import AppKitExtras

final class DetailWebView: WKWebView {

	weak var keyboardDelegate: KeyboardDelegate?
	
	override func accessibilityLabel() -> String? {
		return NSLocalizedString("Article", comment: "Article")
	}

	// MARK: - NSResponder
	
	override func keyDown(with event: NSEvent) {
		if keyboardDelegate?.keydown(event, in: self) ?? false {
			return
		}
		super.keyDown(with: event)
	}

	// MARK: NSView

	override func willOpenMenu(_ menu: NSMenu, with event: NSEvent) {
		// There’s no API for affecting a WKWebView’s contextual menu.
		// (WebView had API for this.)
		//
		// This a minor hack. It hides unwanted menu items.
		// The menu item identifiers are not documented anywhere;
		// they could change, and this code would need updating.
		for menuItem in menu.items {
			if shouldHideMenuItem(menuItem) {
				menuItem.isHidden = true
			}
		}

		super.willOpenMenu(menu, with: event)
	}

	override func viewWillStartLiveResize() {
		super.viewWillStartLiveResize()
		evaluateJavaScript("document.body.style.overflow = 'hidden';", completionHandler: nil)
	}

	override func viewDidEndLiveResize() {
		super.viewDidEndLiveResize()
		evaluateJavaScript("document.body.style.overflow = 'visible';", completionHandler: nil)
		bigSurOffsetFix()
	}
	
	override func setFrameSize(_ newSize: NSSize) {
		super.setFrameSize(newSize)
		if (!inLiveResize) {
			bigSurOffsetFix()
		}
	}
		
	private var inBigSurOffsetFix = false
	
	private func bigSurOffsetFix() {
		/*
		On macOS 11, when a user exits full screen
		or exits zoomed mode by disconnecting an external display
		the webview's `origin.y` is offset by a sizeable amount.
		
		This code adjusts the height of the window by -1pt/+1pt,
		which puts the webview back in the correct place.
		 */
		guard var frame = window?.frame else {
			return
		}

		guard !inBigSurOffsetFix else {
			return
		}

		inBigSurOffsetFix = true

		defer {
			inBigSurOffsetFix = false
		}

		frame.size = NSSize(width: window!.frame.width, height: window!.frame.height - 1)
		window!.setFrame(frame, display: false)
		frame.size = NSSize(width: window!.frame.width, height: window!.frame.height + 1)
		window!.setFrame(frame, display: false)
	}
}

// MARK: - Private

private extension NSUserInterfaceItemIdentifier {

	static let DetailMenuItemIdentifierReload = NSUserInterfaceItemIdentifier(rawValue: "WKMenuItemIdentifierReload")
	static let DetailMenuItemIdentifierOpenLink = NSUserInterfaceItemIdentifier(rawValue: "WKMenuItemIdentifierOpenLink")
}

private extension DetailWebView {

	static let menuItemIdentifiersToHide: [NSUserInterfaceItemIdentifier] = [.DetailMenuItemIdentifierReload, .DetailMenuItemIdentifierOpenLink]
	static let menuItemIdentifierMatchStrings = ["newwindow", "download"]

	func shouldHideMenuItem(_ menuItem: NSMenuItem) -> Bool {

		guard let identifier = menuItem.identifier else {
			return false
		}

		if DetailWebView.menuItemIdentifiersToHide.contains(identifier) {
			return true
		}

		let lowerIdentifier = identifier.rawValue.lowercased()
		for matchString in DetailWebView.menuItemIdentifierMatchStrings {
			if lowerIdentifier.contains(matchString) {
				return true
			}
		}

		return false
	}
}

