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

import math
from dataclasses import dataclass, field
from urllib.parse import urlparse

from devplacepy.services.jobs.isslop.analysis.domsignals.base import DomPageContext, DomSiteContext
from devplacepy.services.jobs.isslop.analysis.domsignals.builders import detected_builder
from devplacepy.services.jobs.isslop.analysis.domsignals.registry import run_dom_checks, run_dom_site_checks
from devplacepy.services.jobs.isslop.analysis.signals import SEVERITY_FACTORS, Signal

DOM_SATURATION: float = 16.0
DOM_FINDINGS_CAP: int = 14

BUCKET_NONE: str = "none"
BUCKET_LIGHT: str = "light"
BUCKET_MODERATE: str = "moderate"
BUCKET_HEAVY: str = "heavy"


@dataclass(frozen=True)
class DomEvidence:
    score: float
    bucket: str
    signals: list[Signal] = field(default_factory=list)
    detected_builder: str | None = None
    builder_confidence: float = 0.0


def _bucket_for(score: float) -> str:
    if score < 10.0:
        return BUCKET_NONE
    if score < 35.0:
        return BUCKET_LIGHT
    if score < 65.0:
        return BUCKET_MODERATE
    return BUCKET_HEAVY


def aggregate_dom_evidence(pages: list[DomPageContext]) -> DomEvidence:
    if not pages:
        return DomEvidence(score=0.0, bucket=BUCKET_NONE, signals=[], detected_builder=None, builder_confidence=0.0)
    signals: list[Signal] = []
    for page in pages:
        signals.extend(run_dom_checks(page)[:DOM_FINDINGS_CAP])
    site = DomSiteContext(pages=pages, root_host=urlparse(pages[0].url).hostname or "")
    signals.extend(run_dom_site_checks(site))
    weighted = sum(signal.weight * SEVERITY_FACTORS.get(signal.severity, 0.3) for signal in signals)
    score = round(100.0 * (1.0 - math.exp(-weighted / DOM_SATURATION)), 1)
    builder_name, builder_confidence = detected_builder(pages)
    return DomEvidence(
        score=score,
        bucket=_bucket_for(score),
        signals=signals,
        detected_builder=builder_name,
        builder_confidence=builder_confidence,
    )
