# retoor <retoor@molodetz.nl>

import re

from devplacepy.utils import strip_html

from .constants import (
    JUNK_PATTERNS,
    MAX_TITLE_CAPS_RATIO,
    MIN_BODY_CHARS,
    MIN_TITLE_CHARS,
    THIN_CONTENT_PENALTY,
    UNIQUE_IMAGE_BONUS,
    WHITESPACE_PATTERN,
)


def _extract_grade(text: str) -> int | None:
    match = re.search(r"\d+", text.strip())
    if match:
        val = int(match.group())
        if 1 <= val <= 10:
            return val
    return None


def _strip_md_fence(text: str) -> str:
    stripped = text.strip()
    if not stripped.startswith("```"):
        return stripped
    lines = stripped.splitlines()
    if len(lines) < 2 or not lines[-1].strip().startswith("```"):
        return stripped
    return "\n".join(lines[1:-1]).strip()


def clean_news_text(text: str) -> str:
    if not text:
        return ""
    cleaned = strip_html(text)
    for pattern in JUNK_PATTERNS:
        cleaned = pattern.sub(" ", cleaned)
    cleaned = WHITESPACE_PATTERN.sub(" ", cleaned)
    return cleaned.strip()


def _caps_ratio(title: str) -> float:
    letters = [c for c in title if c.isalpha()]
    if not letters:
        return 0.0
    uppers = sum(1 for c in letters if c.isupper())
    return uppers / len(letters)


def _is_valid_url(url: str) -> bool:
    return url.startswith("http://") or url.startswith("https://")


def reliability_reason(title: str, body: str, url: str) -> str:
    if not url or not _is_valid_url(url):
        return "invalid_url"
    if len(title) < MIN_TITLE_CHARS:
        return "short_title"
    if len(body) < MIN_BODY_CHARS:
        return "thin_body"
    if _caps_ratio(title) > MAX_TITLE_CAPS_RATIO:
        return "shouting_title"
    return ""


def effective_score(
    ai_grade: int, has_unique_image: bool, body_marginal: bool
) -> int:
    score = ai_grade
    if has_unique_image:
        score += UNIQUE_IMAGE_BONUS
    if body_marginal:
        score -= THIN_CONTENT_PENALTY
    return max(1, min(10, score))
