"""
Shared onboarding UI helpers for guided help text and tutorial links.
"""

from __future__ import annotations

from html import escape
import os
from pathlib import Path
from typing import Iterable, Optional

from .qt_compat import QFrame, QLabel, QVBoxLayout, Qt
from .theme import info_panel_colors
from .translator import tr


_DEMO_DIR = Path(__file__).resolve().parent / "tutorial_demos"
_TUTORIALS_ENABLED = os.environ.get("EMDS_ENABLE_TUTORIAL_LINKS", "").strip().lower() in {
    "1",
    "true",
    "yes",
    "on",
}


def _demo_url(filename: str) -> str:
    """Return a file:// URL for a bundled tutorial demo HTML file."""
    return (_DEMO_DIR / filename).as_uri()


# Map of tutorial slug -> on-disk demo filename. Labels are resolved through
# tr("tutorials.<slug>") at call time so they reflect the active language.
_TUTORIAL_URLS = {
    "getting_started": _demo_url("getting-started.html"),
    "create_workspace": _demo_url("create-workspace.html"),
    "first_task": _demo_url("first-task.html"),
    "create_study_area": _demo_url("create-study-area.html"),
    "review_results": _demo_url("review-results.html"),
}


def _tutorial_label(link_key: str) -> str:
    """Return the translated display label for a tutorial slug."""
    return tr(f"tutorials.{link_key}")


def tutorials_available() -> bool:
    """Return whether unfinished tutorial links should be shown in the app."""
    return _TUTORIALS_ENABLED


def tutorial_url(link_key: str) -> str:
    """Return the configured URL for a tutorial link key."""
    if not tutorials_available():
        return ""
    return _TUTORIAL_URLS.get(link_key, "")


# Backwards-compatible accessor for callers that still import TUTORIAL_LINKS.
# Each value is (translated_label, url); the label reflects the language at the
# time of access via __getitem__/.get().
class _TutorialLinksMap:
    def __getitem__(self, key):
        if not tutorials_available() or key not in _TUTORIAL_URLS:
            raise KeyError(key)
        return (_tutorial_label(key), _TUTORIAL_URLS[key])

    def get(self, key, default=("", "")):
        if not tutorials_available():
            return default
        url = _TUTORIAL_URLS.get(key)
        if url is None:
            return default
        return (_tutorial_label(key), url)

    def __iter__(self):
        return iter(_TUTORIAL_URLS)

    def items(self):
        for key in _TUTORIAL_URLS:
            yield key, (_tutorial_label(key), _TUTORIAL_URLS[key])


TUTORIAL_LINKS = _TutorialLinksMap()


def create_external_links_label(
    link_keys: Iterable[str],
    prefix: Optional[str] = None,
    parent=None,
) -> QLabel:
    """Build a rich-text label with clickable external tutorial links.

    The label remembers its inputs and exposes a ``retranslate()`` method so
    callers can refresh its rendered HTML when the active language changes.
    """
    link_keys = list(link_keys)

    def _build_text() -> str:
        # Resolve prefix: callers may pass a translation key (e.g. "tutorials.open_prefix")
        # or a literal string. If it looks like a dotted key, run it through tr().
        if prefix:
            resolved_prefix = tr(prefix) if "." in prefix and " " not in prefix else prefix
        else:
            resolved_prefix = ""

        links = []
        for link_key in link_keys:
            label, url = TUTORIAL_LINKS.get(link_key, ("", ""))
            if label and url:
                links.append(f'<a href="{escape(url, quote=True)}">{escape(label)}</a>')

        if not links:
            return escape(resolved_prefix or "")
        if resolved_prefix:
            return f"{escape(resolved_prefix)} {' | '.join(links)}"
        return " | ".join(links)

    label_widget = QLabel(_build_text(), parent)
    label_widget.setWordWrap(True)
    label_widget.setOpenExternalLinks(True)
    label_widget.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction)
    label_widget.retranslate = lambda: label_widget.setText(_build_text())
    return label_widget


def create_hint_panel(
    title: str,
    body: str,
    link_key: Optional[str] = None,
    link_text: Optional[str] = None,
    parent=None,
) -> QFrame:
    """Create a lightweight framed coaching panel used in Guided-adjacent UI."""
    colors = info_panel_colors()

    frame = QFrame(parent)
    frame.setFrameShape(QFrame.Shape.StyledPanel)
    # Scope the frame background to the QFrame itself (not descendants) so the
    # explicit label colors below win, and always pair the background with an
    # explicit text color so it is readable in both light and dark themes.
    frame.setStyleSheet(
        "QFrame {"
        f"background-color: {colors['background']};"
        f"border: 1px solid {colors['border']};"
        "border-radius: 6px;"
        "}"
    )

    layout = QVBoxLayout(frame)
    layout.setContentsMargins(8, 8, 8, 8)
    layout.setSpacing(4)

    title_label = QLabel(title, frame)
    title_label.setWordWrap(True)
    title_label.setStyleSheet(
        f"font-weight: bold; color: {colors['text']}; background: transparent; border: none;"
    )
    layout.addWidget(title_label)
    frame.title_label = title_label

    body_label = QLabel(body, frame)
    body_label.setWordWrap(True)
    body_label.setStyleSheet(
        f"color: {colors['text']}; background: transparent; border: none;"
    )
    layout.addWidget(body_label)
    frame.body_label = body_label

    if link_key:
        url = tutorial_url(link_key)
        if url:
            def _link_html() -> str:
                text = link_text if link_text is not None else tr("tutorials.watch_this_step")
                # Inline the anchor color: a QLabel stylesheet `color` does not
                # reliably recolor <a> text, so theme the link here instead.
                return (
                    f'<a href="{escape(url, quote=True)}" '
                    f'style="color: {colors["link"]};">{escape(text)}</a>'
                )

            link_label = QLabel(_link_html(), frame)
            link_label.setStyleSheet("background: transparent; border: none;")
            link_label.setWordWrap(True)
            link_label.setOpenExternalLinks(True)
            link_label.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction)
            link_label.retranslate = lambda: link_label.setText(_link_html())
            layout.addWidget(link_label)
            frame.link_label = link_label

    return frame
