//
//  ViewController.swift
//  Tasks
//
//  Created by Chen-I Lim on 10/7/20.
//

import Cocoa
import WebKit

class ViewController:
	NSViewController,
	WKUIDelegate,
	WKNavigationDelegate {
	@IBOutlet var webView: WKWebView!
	
	override func viewDidLoad() {
		super.viewDidLoad()

		NSLog("viewDidLoad")

		webView.navigationDelegate = self
		webView.uiDelegate = self

		clearWebViewCache()
		loadHomepage()

		// Do any additional setup after loading the view.
		NotificationCenter.default.addObserver(self, selector: #selector(onServerStarted), name: AppDelegate.serverStartedNotification, object: nil)
	}

	override var representedObject: Any? {
		didSet {
			// Update the view, if already loaded.
		}
	}

	private func clearWebViewCache() {
		let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
		let date = Date(timeIntervalSince1970: 0)
		WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes as! Set<String>, modifiedSince: date, completionHandler:{ })
	}

	@objc func onServerStarted() {
		NSLog("onServerStarted")
		DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
			self.loadHomepage()
		}
	}

	private func loadHomepage() {
		let appDelegate = NSApplication.shared.delegate as! AppDelegate
		let port = appDelegate.serverPort
		let url = URL(string: "http://localhost:\(port)/")!
		let request = URLRequest(url: url)
		webView.load(request)
	}

	private func downloadJsonUrl(_ url: URL) {
		NSLog("downloadJsonUrl")
		let prefix = "data:text/json,"
		let urlString = url.absoluteString
		let encodedJson = String(urlString[urlString.index(urlString.startIndex, offsetBy: prefix.lengthOfBytes(using: .utf8))...])
		guard let json = encodedJson.removingPercentEncoding else {
			return
		}

		// Form file name
		let dateFormatter = DateFormatter()
		dateFormatter.dateFormat = "yyyy-M-d"
		let dateString = dateFormatter.string(from: Date())
		let filename = "archive-\(dateString).octo"

		// Save file
		let savePanel = NSSavePanel()
		savePanel.canCreateDirectories = true
		savePanel.nameFieldStringValue = filename
		// BUGBUG: Specifying the allowedFileTypes causes Catalina to hang / error out
		//savePanel.allowedFileTypes = [".octo"]
		savePanel.begin { (result) in
			if result.rawValue == NSApplication.ModalResponse.OK.rawValue,
			   let fileUrl = savePanel.url {
				try? json.write(to: fileUrl, atomically: true, encoding: .utf8)
			}
		}
	}

	func webView(_ webView: WKWebView, runOpenPanelWith parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping ([URL]?) -> Void) {
		NSLog("webView runOpenPanel")
		let openPanel = NSOpenPanel()
		openPanel.canChooseFiles = true
		openPanel.begin { (result) in
			if result == NSApplication.ModalResponse.OK {
				if let url = openPanel.url {
					completionHandler([url])
				}
			} else if result == NSApplication.ModalResponse.cancel {
				completionHandler(nil)
			}
		}
	}

	func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
		if let url = navigationAction.request.url {
			// Intercept archive downloads, and present native UI
			if (url.absoluteString.hasPrefix("data:text/json,")) {
				decisionHandler(.cancel)
				downloadJsonUrl(url)
				return
			}
			NSLog("decidePolicyFor navigationAction: \(url.absoluteString)")
		}
		decisionHandler(.allow)
	}

	func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
		NSLog("webView didFinish navigation: \(webView.url?.absoluteString ?? "")")
		// Disable right-click menu
		webView.evaluateJavaScript("document.body.setAttribute('oncontextmenu', 'event.preventDefault();');", completionHandler: nil)
	}

	@IBAction func navigateToHome(_ sender: NSObject) {
		loadHomepage()
	}
}

