# retoor <retoor@molodetz.nl>
from __future__ import annotations

import re

from devplacepy.services.jobs.isslop.analysis.domsignals.base import DomPageContext, dom_check
from devplacepy.services.jobs.isslop.analysis.signals import (
    AXIS_ORIGIN,
    AXIS_QUALITY,
    SEVERITY_MEDIUM,
    SEVERITY_STRONG,
    SEVERITY_WEAK,
    Signal,
)

HASHED_SEGMENT_PATTERN = re.compile(r"[.-][0-9a-f]{6,}\.js", re.IGNORECASE)
UNHASHED_BUNDLE_PATTERN = re.compile(r"/(main|bundle|index)\.js(\?|$)", re.IGNORECASE)
PLACEHOLDER_TEXT_PATTERN = re.compile(
    r"lorem ipsum|coming soon|your headline here|add your description|placeholder", re.IGNORECASE
)
PLACEHOLDER_IMAGE_HOSTS: tuple[str, ...] = ("via.placeholder.com", "placehold.co", "picsum.photos")
TAILWIND_PRODUCTION_WARNING: str = "cdn.tailwindcss.com should not be used in production"
REACT_DEV_WARNING_MARKERS: tuple[str, ...] = ("development build of React", "Each child in a list should have a unique")


def _text_blob(page: DomPageContext) -> str:
    parts = [
        str(heading.get("text", ""))
        for heading in (page.dom.get("headings") or [])
        if isinstance(heading, dict) and heading.get("text")
    ]
    meta = page.dom.get("meta", {}) or {}
    description = meta.get("description") if isinstance(meta, dict) else ""
    if description:
        parts.append(str(description))
    return "\n".join(parts)


def _looks_unhashed(src: str) -> bool:
    if not src:
        return False
    if HASHED_SEGMENT_PATTERN.search(src):
        return False
    return bool(UNHASHED_BUNDLE_PATTERN.search(src))


def _detect_tailwind_cdn(page: DomPageContext) -> Signal | None:
    scripts = page.dom.get("scripts", []) or []
    if not any("cdn.tailwindcss.com" in str(src) for src in scripts):
        return None
    console_text = " ".join(page.console_warnings + page.console_errors)
    if TAILWIND_PRODUCTION_WARNING in console_text:
        return Signal(
            "TAILWIND_CDN_DOM",
            "Tailwind CDN build flagged unsuitable for production by the browser console",
            SEVERITY_STRONG,
            AXIS_ORIGIN,
            3.5,
            0,
            "cdn.tailwindcss.com + production warning",
        )
    return Signal(
        "TAILWIND_CDN_DOM",
        "Tailwind loaded from the CDN build in the rendered page",
        SEVERITY_MEDIUM,
        AXIS_ORIGIN,
        2.0,
        0,
        "cdn.tailwindcss.com",
    )


def _detect_cdn_react(page: DomPageContext) -> Signal | None:
    scripts = page.dom.get("scripts", []) or []
    for src in scripts:
        text = str(src)
        if "unpkg.com/react" in text or "esm.sh/react" in text or "esm.sh/tsx" in text:
            return Signal(
                "CDN_REACT_UNBUNDLED",
                "React loaded unbundled directly from a CDN",
                SEVERITY_MEDIUM,
                AXIS_ORIGIN,
                2.0,
                0,
                text[:150],
            )
    return None


def _detect_react_dev_warning(page: DomPageContext) -> Signal | None:
    console_text = " ".join(page.console_warnings + page.console_errors)
    if not any(marker in console_text for marker in REACT_DEV_WARNING_MARKERS):
        return None
    return Signal(
        "REACT_DEV_BUILD_WARNING",
        "React development-build or missing-key warnings present in the console",
        SEVERITY_MEDIUM,
        AXIS_QUALITY,
        1.5,
        0,
        console_text[:150],
    )


def _detect_unhashed_bundle(page: DomPageContext) -> Signal | None:
    scripts = page.dom.get("scripts", []) or []
    for src in scripts:
        if _looks_unhashed(str(src)):
            return Signal(
                "UNHASHED_BUNDLE_FILENAME",
                "Script bundle filename with no content-hash segment",
                SEVERITY_WEAK,
                AXIS_QUALITY,
                0.5,
                0,
                str(src),
            )
    return None


def _detect_placeholder_content(page: DomPageContext) -> Signal | None:
    match = PLACEHOLDER_TEXT_PATTERN.search(_text_blob(page))
    if not match:
        return None
    return Signal(
        "PLACEHOLDER_CONTENT_DOM",
        "Placeholder or unedited template copy left in the rendered page",
        SEVERITY_MEDIUM,
        AXIS_QUALITY,
        2.0,
        0,
        match.group(0),
    )


def _detect_placeholder_image_host(page: DomPageContext) -> Signal | None:
    images = page.dom.get("images", []) or []
    for image in images:
        if not isinstance(image, dict):
            continue
        src = str(image.get("src", ""))
        if any(host in src for host in PLACEHOLDER_IMAGE_HOSTS):
            return Signal(
                "PLACEHOLDER_IMAGE_HOST",
                "Image served from a generic placeholder image host",
                SEVERITY_MEDIUM,
                AXIS_QUALITY,
                1.5,
                0,
                src,
            )
    return None


def _detect_default_framework_title(page: DomPageContext) -> Signal | None:
    meta = page.dom.get("meta", {}) or {}
    title = str(meta.get("title", ""))
    if title == "Vite + React" or "Create Next App" in title:
        return Signal(
            "DEFAULT_FRAMEWORK_TITLE",
            "Unedited default framework document title",
            SEVERITY_MEDIUM,
            AXIS_ORIGIN,
            1.5,
            0,
            title,
        )
    return None


@dom_check
def detect_build_signals(page: DomPageContext) -> list[Signal]:
    findings: list[Signal] = []
    for signal in (
        _detect_tailwind_cdn(page),
        _detect_cdn_react(page),
        _detect_react_dev_warning(page),
        _detect_unhashed_bundle(page),
        _detect_placeholder_content(page),
        _detect_placeholder_image_host(page),
        _detect_default_framework_title(page),
    ):
        if signal is not None:
            findings.append(signal)
    return findings
