// LoopFollow
// NightScoutViewController.swift

import Combine
import UIKit
import WebKit

class NightscoutViewController: UIViewController {
    var webView: WKWebView!
    private var cancellables = Set<AnyCancellable>()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBackground
        overrideUserInterfaceStyle = Storage.shared.appearanceMode.value.userInterfaceStyle

        // Create WKWebView programmatically
        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.mediaTypesRequiringUserActionForPlayback = []
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(webView)

        let safeArea = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            webView.topAnchor.constraint(equalTo: safeArea.topAnchor),
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            webView.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor),
        ])

        // Listen for appearance setting changes
        Storage.shared.appearanceMode.$value
            .receive(on: DispatchQueue.main)
            .sink { [weak self] mode in
                self?.overrideUserInterfaceStyle = mode.userInterfaceStyle
            }
            .store(in: &cancellables)

        var url = Storage.shared.url.value
        let token = Storage.shared.token.value

        if token != "" {
            url = url + "?token=" + token
        }

        guard let myUrl = URL(string: url) else { return }

        let webpagePreferences = WKWebpagePreferences()
        webpagePreferences.allowsContentJavaScript = true
        webView.configuration.defaultWebpagePreferences = webpagePreferences

        webView.navigationDelegate = self
        webView.uiDelegate = self
        webView.load(URLRequest(url: myUrl))

        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(self, action: #selector(reloadWebView(_:)), for: .valueChanged)
        webView.scrollView.addSubview(refreshControl)
    }

    @objc func reloadWebView(_ sender: UIRefreshControl) {
        clearWebCache()
        webView.reload()
        sender.endRefreshing()
    }

    func clearWebCache() {
        let dataStore = WKWebsiteDataStore.default()
        let cacheTypes = Set([WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
        let date = Date(timeIntervalSince1970: 0)
        dataStore.removeData(ofTypes: cacheTypes, modifiedSince: date) {
            print("Web cache cleared.")
        }
    }

    // this handles target=_blank links by opening them in the same view
    func webView(webView: WKWebView!, createWebViewWithConfiguration _: WKWebViewConfiguration!, forNavigationAction navigationAction: WKNavigationAction!, windowFeatures _: WKWindowFeatures!) -> WKWebView! {
        if let frame = navigationAction.targetFrame,
           frame.isMainFrame
        {
            return nil
        }
        // for _blank target or non-mainFrame target
        webView.load(navigationAction.request)
        return nil
    }
}

// MARK: - WKUIDelegate implementation

extension NightscoutViewController: WKNavigationDelegate, WKUIDelegate {
    func webView(_: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame _: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        let alertCtrl = UIAlertController(title: nil, message: message, preferredStyle: .alert)

        alertCtrl.addAction(UIAlertAction(title: "OK", style: .default) { _ in
            completionHandler(true)
        })

        alertCtrl.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
            completionHandler(false)
        })

        present(alertCtrl, animated: true)
    }

    func webView(_: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        guard let _ = navigationAction.request.url else {
            decisionHandler(.cancel)
            return
        }

        decisionHandler(.allow)
    }

    func webView(_: WKWebView, shouldStartLoadWith request: URLRequest) -> Bool {
        guard let url = request.url else {
            return false
        }

        LogManager.shared.log(category: .nightscout, message: "Web shouldStart: \(LogRedactor.url(url.absoluteString))", isDebug: true)
        return true
    }

    func webView(_ webView: WKWebView, createWebViewWith _: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures _: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }

        return nil
    }

    func webView(_ webView: WKWebView, didFinish _: WKNavigation!) {
        let javascript = """
        var meta = document.querySelector('meta[name="viewport"]');
        if (meta) {
            meta.setAttribute('content', 'width=device-width, initial-scale=0.9, maximum-scale=5.0, user-scalable=yes');
        }
        """

        webView.evaluateJavaScript(javascript)
    }
}
