# -*- coding: utf-8 -*-
# (C) 2016 Minoru Akagi
# SPDX-License-Identifier: GPL-2.0-or-later
# begin: 2016-02-10

import json
import logging

from qgis.PyQt.QtCore import Qt, QUrl
from qgis.PyQt.QtGui import QDesktopServices
from qgis.PyQt.QtWidgets import QDialog, QVBoxLayout

from qgis.PyQt.QtWebKit import QWebSettings, QWebSecurityOrigin
from qgis.PyQt.QtWebKitWidgets import QWebInspector, QWebPage, QWebView

from .webviewcommon import Q3DWebPageCommon, Q3DWebViewCommon
from ..conf import DEBUG_MODE
from ..utils import js_bool, pluginDir
from ..utils.logging import logger, web_logger


class Q3DWebKitPage(Q3DWebPageCommon, QWebPage):

    def __init__(self, parent=None):
        QWebPage.__init__(self, parent)
        Q3DWebPageCommon.__init__(self)

        self.isWebEnginePage = False

        self.mainFrame().javaScriptWindowObjectCleared.connect(self.addJSObject)

        # security settings
        origin = self.mainFrame().securityOrigin()
        origin.addAccessWhitelistEntry("http:", "*", QWebSecurityOrigin.AllowSubdomains)
        origin.addAccessWhitelistEntry("https:", "*", QWebSecurityOrigin.AllowSubdomains)

        self.setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
        self.linkClicked.connect(QDesktopServices.openUrl)

    def addJSObject(self):
        self.mainFrame().addToJavaScriptWindowObject("pyObj", self.bridge)
        logger.debug("pyObj added")

    def url(self):
        return self.mainFrame().url()

    def setup(self):
        # if self.offScreen:
        #     # transparent background
        #     palette = self.palette()
        #     palette.setBrush(QPalette.Base, Qt.GlobalColor.transparent)
        #     self.setPalette(palette)
        #     #webview: self.setAttribute(Qt.WidgetAttribute.WA_OpaquePaintEvent, False)

        url = pluginDir("web/viewer/webkit.html").replace("\\", "/")
        self.myUrl = QUrl.fromLocalFile(url)
        self.reload()

    def reload(self):
        self.showStatusMessage("Initializing preview...")
        self.mainFrame().setUrl(self.myUrl)

    def runScript(self, string, message="", sourceID="webkitview.py", callback=None, wait=False):
        """
        Run a JavaScript script in the web view with optional data and callback.
        Args:
            string (str): The JavaScript code string to execute.
            message (str, optional): A descriptive message for logging purposes.
            sourceID (str, optional): Identifier for the source of the script.
            callback (optional): Callback function to be executed after script runs.
            wait (bool, optional): Whether to wait for script execution to complete.
        """
        self.logScriptExecution(string, message, sourceID)


        result = self.mainFrame().evaluateJavaScript(string)
        if callback:
            callback(result)

        return result

    def sendData(self, data, viaQueue=False):
        self.bridge.setData(data)
        self.runScript(f"loadData(pyData(), {js_bool(viaQueue)})", message=None)

    def javaScriptConsoleMessage(self, message, lineNumber, sourceID):
        if DEBUG_MODE:
            msg = message.lower()

            if "error" in msg:
                level = logging.ERROR
            elif "warning" in msg:
                level = logging.WARNING
            else:
                level = logging.INFO

            text = message
            if sourceID:
                text += f"\t({sourceID.split('/')[-1]}:{lineNumber})"

            web_logger.log(level, text)

    def logToConsole(self, message, level="debug"):
        if level not in ["debug", "info", "warn", "error"]:
            level = "log"

        self.mainFrame().evaluateJavaScript(f"console.{level}({json.dumps(message)});")


class Q3DWebKitView(Q3DWebViewCommon, QWebView):

    def __init__(self, parent):
        QWebView.__init__(self, parent)
        Q3DWebViewCommon.__init__(self)

        self._page = Q3DWebKitPage(self)
        self._page.setObjectName("webKitPage")
        self.setPage(self._page)

        # security setting for billboard, model file and point cloud layer
        self.settings().setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, True)

        # web inspector setting
        self.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)

    def showDevTools(self):
        dlg = QDialog(self)
        dlg.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
        dlg.resize(800, 500)
        dlg.setWindowTitle("Qgis2threejs Web Inspector")
        dlg.rejected.connect(self.devToolsClosed)

        wi = QWebInspector(dlg)
        wi.setPage(self._page)

        v = QVBoxLayout()
        v.setContentsMargins(0, 0, 0, 0)
        v.addWidget(wi)

        dlg.setLayout(v)
        dlg.show()
