from pathlib import Path

from PyQt5.QtCore import QByteArray, Qt, QUrl
from PyQt5.QtWidgets import (
    QFrame,
    QHBoxLayout,
    QLabel,
    QPushButton,
    QVBoxLayout,
    QWidget,
)
from PyQt5.QtWebEngineCore import (
    QWebEngineUrlRequestInterceptor,
)
from PyQt5.QtWebEngineWidgets import (
    QWebEnginePage,
    QWebEngineProfile,
    QWebEngineView,
)


EMBEDDED_WORKSPACE_VERSION = "0.1.1-armor-agent-shell"


class LocalRequestInterceptor(
    QWebEngineUrlRequestInterceptor
):
    def __init__(self, workspace_url, token, parent=None):
        super().__init__(parent)

        origin = QUrl(workspace_url)

        self.scheme = origin.scheme().lower()
        self.host = origin.host().lower()
        self.port = origin.port(80)
        self.token = token

    def interceptRequest(self, information):
        url = information.requestUrl()
        scheme = url.scheme().lower()

        if scheme in {"about", "blob", "data"}:
            return

        allowed = (
            scheme == self.scheme
            and url.host().lower() == self.host
            and url.port(80) == self.port
        )

        if not allowed:
            information.block(True)
            return

        if self.token:
            information.setHttpHeader(
                QByteArray(
                    b"X-SHiRE-Workspace-Token"
                ),
                QByteArray(
                    self.token.encode("utf-8")
                ),
            )


class LocalOnlyPage(QWebEnginePage):
    def __init__(self, profile, workspace_url, parent=None):
        super().__init__(profile, parent)

        origin = QUrl(workspace_url)

        self.scheme = origin.scheme().lower()
        self.host = origin.host().lower()
        self.port = origin.port(80)

    def acceptNavigationRequest(
        self,
        url,
        navigation_type,
        is_main_frame,
    ):
        scheme = url.scheme().lower()

        if scheme in {"about", "blob", "data"}:
            return True

        return (
            scheme == self.scheme
            and url.host().lower() == self.host
            and url.port(80) == self.port
        )

    def createWindow(self, window_type):
        return None


class EmbeddedAgentWorkspace(QWidget):
    def __init__(self, stack, agents_page, data):
        super().__init__()

        self.stack = stack
        self.agents_page = agents_page
        self.data = dict(data)

        self.agent_id = str(
            data.get("id")
            or "unknown"
        )

        self.workspace_url = str(
            data.get("workspaceUrl")
            or ""
        ).strip()

        self._validate_workspace_url()

        root = QVBoxLayout(self)
        root.setContentsMargins(0, 0, 0, 0)
        root.setSpacing(0)

        header = QFrame()
        header.setObjectName(
            "agentWorkspaceHeader"
        )
        header.setMinimumHeight(60)
        header.setStyleSheet(
            """
            QFrame#agentWorkspaceHeader {
                background:#060c12;
                border-bottom:1px solid #304657;
            }
            """
        )

        controls = QHBoxLayout(header)
        controls.setContentsMargins(14, 8, 14, 8)
        controls.setSpacing(9)

        self.home_button = QPushButton("HOME")
        self.home_button.setObjectName(
            "agentWorkspaceHome"
        )

        self.back_button = QPushButton(
            "BACK TO AGENTS"
        )
        self.back_button.setObjectName(
            "agentWorkspaceBack"
        )

        self.reload_button = QPushButton("RELOAD")
        self.reload_button.setObjectName(
            "agentWorkspaceReload"
        )

        normal_style = """
            QPushButton {
                color:#e8fff2;
                background:#152432;
                border:1px solid #385063;
                border-radius:10px;
                padding:8px 14px;
                font-size:10px;
                font-weight:900;
            }
            QPushButton:hover {
                background:#20384a;
                border-color:#00ff66;
            }
        """

        for button in (
            self.back_button,
            self.reload_button,
        ):
            button.setMinimumHeight(40)
            button.setStyleSheet(normal_style)

        self.home_button.setMinimumHeight(40)
        self.home_button.setStyleSheet(
            """
            QPushButton {
                color:#02040a;
                background:#00ff66;
                border:none;
                border-radius:10px;
                padding:8px 16px;
                font-size:10px;
                font-weight:900;
            }
            QPushButton:hover {
                background:#78ffaa;
            }
            """
        )

        self.home_button.clicked.connect(
            self.go_home
        )
        self.back_button.clicked.connect(
            self.back_to_agents
        )
        self.reload_button.clicked.connect(
            self.reload_workspace
        )

        title_box = QVBoxLayout()
        title_box.setSpacing(0)

        title = QLabel(
            str(
                data.get("name")
                or self.agent_id
            )
        )
        title.setStyleSheet(
            "color:#e8fff2;"
            "font-size:15px;"
            "font-weight:900;"
            "background:transparent;"
            "border:none;"
        )

        subtitle = QLabel(
            "DEDICATED AGENT WORKSPACE · "
            "PRIVATE LOCAL SESSION"
        )
        subtitle.setStyleSheet(
            "color:#91a0aa;"
            "font-size:8px;"
            "font-weight:800;"
            "background:transparent;"
            "border:none;"
        )

        title_box.addWidget(title)
        title_box.addWidget(subtitle)

        self.status = QLabel("LOADING")
        self.status.setObjectName(
            "agentWorkspaceStatus"
        )
        self.status.setAlignment(Qt.AlignCenter)
        self.status.setMinimumWidth(140)

        self._set_status(
            "LOADING",
            "#f2b84b",
        )

        controls.addWidget(self.home_button)
        controls.addWidget(self.back_button)
        controls.addWidget(self.reload_button)
        controls.addSpacing(8)
        controls.addLayout(title_box, 1)
        controls.addWidget(self.status)

        root.addWidget(header)

        self.view = QWebEngineView(self)
        self.view.setObjectName(
            "agentWorkspaceWebView"
        )
        self.view.setContextMenuPolicy(
            Qt.NoContextMenu
        )

        token = self._workspace_token()

        self.profile = QWebEngineProfile(self)
        self.profile.setHttpCacheType(
            QWebEngineProfile.MemoryHttpCache
        )
        self.profile.setPersistentCookiesPolicy(
            QWebEngineProfile.NoPersistentCookies
        )

        self.interceptor = LocalRequestInterceptor(
            self.workspace_url,
            token,
            self.profile,
        )

        self.profile.setUrlRequestInterceptor(
            self.interceptor
        )

        self.page = LocalOnlyPage(
            self.profile,
            self.workspace_url,
            self.view,
        )

        self.view.setPage(self.page)
        self.view.loadFinished.connect(
            self._load_finished
        )

        root.addWidget(self.view, 1)

        self.view.load(
            QUrl(self.workspace_url)
        )

    def _validate_workspace_url(self):
        url = QUrl(self.workspace_url)

        valid = (
            url.isValid()
            and url.scheme().lower() == "http"
            and url.host().lower() == "127.0.0.1"
            and url.port() > 0
        )

        if not valid:
            raise ValueError(
                "Agent workspace must use an explicit "
                "localhost HTTP address and port."
            )

    def _workspace_token(self):
        path = (
            Path("/etc/shire-agents")
            / f"{self.agent_id}-workspace.env"
        )

        try:
            lines = path.read_text(
                encoding="utf-8"
            ).splitlines()
        except Exception:
            return ""

        for line in lines:
            if line.startswith(
                "SHIRE_WORKSPACE_TOKEN="
            ):
                return line.split(
                    "=",
                    1,
                )[1].strip()

        return ""

    def _set_status(self, text, colour):
        self.status.setText(text)
        self.status.setStyleSheet(
            f"""
            color:{colour};
            background:rgba(0,0,0,100);
            border:1px solid {colour};
            border-radius:10px;
            padding:8px;
            font-size:9px;
            font-weight:900;
            """
        )

    def _load_finished(self, successful):
        if successful:
            self._set_status(
                "WORKSPACE LIVE",
                "#20e887",
            )
        else:
            self._set_status(
                "LOAD FAILED",
                "#ff4d5f",
            )

    def reload_workspace(self):
        self._set_status(
            "RELOADING",
            "#f2b84b",
        )
        self.view.reload()

    def go_home(self):
        self._leave(
            self.stack.widget(0)
        )

    def back_to_agents(self):
        self._leave(
            self.agents_page
        )

    def _leave(self, destination):
        self.view.stop()
        self.stack.setCurrentWidget(destination)
        self.stack.removeWidget(self)
        self.deleteLater()
