from __future__ import annotations
from typing import Any

DPI_LOW = 200
DPI_BORDERLINE = 300

SC_MODERATE = 0.5
SC_HIGH = 5.0

HC_MODERATE = 0.5
HC_HIGH = 5.0

CONTRAST_LOW = 5.0
CONTRAST_BORDERLINE = 10.0

CR_LOW = 20.0
CR_LIMITED = 33.3

CF_LOW = 15.0
CF_LIMITED = 33.0

DEFAULT_MESSAGE = "All Good"


def _is_num(x: Any) -> bool:
    return isinstance(x, (int, float))


def _fmt_limit(value: float) -> str:
    return str(int(value)) if float(value).is_integer() else f"{value:.1f}"


def recommendation_tags_for_record(rec: dict[str, Any]) -> str:
    tags: list[str] = []

    # 1) DPI
    dpi_pair = rec.get("dpi_pair")
    mdpi: float | None = None
    if isinstance(dpi_pair, tuple) and len(dpi_pair) == 2:
        nums = [v for v in dpi_pair if _is_num(v)]
        if nums:
            mdpi = float(min(nums))
    if mdpi is not None:
        if mdpi < DPI_LOW:
            tags.append("Low DPI")
        elif mdpi < DPI_BORDERLINE:
            tags.append("Borderline DPI")

    # 2) Shadow clip [%]
    sc = rec.get("shadow_clip_pct")
    if _is_num(sc):
        if sc > SC_HIGH:
            tags.append("High Shadow Clip")
        elif sc >= SC_MODERATE:
            tags.append("Moderate Shadow Clip")

    # 3) Highlight clip [%]
    hc = rec.get("highlight_clip_pct")
    if _is_num(hc):
        if hc > HC_HIGH:
            tags.append("High Highlight Clip")
        elif hc >= HC_MODERATE:
            tags.append("Moderate Highlight Clip")

    # 4) Contrast [%] (P1–P99)
    co = rec.get("contrast_p1p99_pct")
    if _is_num(co):
        if co < CONTRAST_LOW:
            tags.append("Low Contrast")
        elif co < CONTRAST_BORDERLINE:
            tags.append("Borderline Contrast")

    # 5) Colorfulness (HS)
    cf = rec.get("colorfulness_hs")
    if _is_num(cf):
        if cf < CF_LOW:
            tags.append("Low Colorfulness")
        elif cf < CF_LIMITED:
            tags.append("Limited Colorfulness")

    # 6) Color richness [%]
    cr = rec.get("color_richness_pct")
    if _is_num(cr):
        if cr < CR_LOW:
            tags.append("Low Color Richness")
        elif cr < CR_LIMITED:
            tags.append("Limited Color Richness")

    if not tags:
        return DEFAULT_MESSAGE
    return ", ".join(tags)


def recommendation_bullets_for_record(tags_str: str) -> list[tuple[str, str]]:
    if tags_str == DEFAULT_MESSAGE or not tags_str.strip():
        return [(DEFAULT_MESSAGE, "No notable issues detected.")]

    parts: list[tuple[str, str]] = []
    for tag in (t.strip() for t in tags_str.split(",") if t.strip()):
        if tag == "Low DPI":
            exp = f"Effective resolution is below {DPI_LOW} DPI, print may look soft. For printed theses aim for at least {DPI_BORDERLINE} DPI."
        elif tag == "Borderline DPI":
            exp = f"Effective resolution is {DPI_LOW}–{DPI_BORDERLINE - 1} DPI, usually OK on-screen but borderline for print. For high-quality print aim for {DPI_BORDERLINE} DPI or higher."
        elif tag == "Moderate Shadow Clip":
            exp = f"{_fmt_limit(SC_MODERATE)}–{_fmt_limit(SC_HIGH)}% of pixels are pure black (value 0), so some shadow detail may be lost. Ideally shadow clip should stay below about {_fmt_limit(SC_MODERATE)}%."
        elif tag == "High Shadow Clip":
            exp = f">{_fmt_limit(SC_HIGH)}% of pixels are pure black (value 0), so dark areas lose detail. For important figures try to keep shadow clip below {_fmt_limit(SC_HIGH)}% and ideally near {_fmt_limit(SC_MODERATE)}%."
        elif tag == "Moderate Highlight Clip":
            exp = f"{_fmt_limit(HC_MODERATE)}–{_fmt_limit(HC_HIGH)}% of pixels are pure white (value 255), so some highlight detail may be lost. Ideally highlight clip should stay below about {_fmt_limit(HC_MODERATE)}%."
        elif tag == "High Highlight Clip":
            exp = f">{_fmt_limit(HC_HIGH)}% of pixels are pure white (value 255), so bright areas lose detail. For important figures try to keep highlight clip below {_fmt_limit(HC_HIGH)}% and ideally near {_fmt_limit(HC_MODERATE)}%."
        elif tag == "Low Contrast":
            exp = f"The 1st–99th percentile brightness spread is <{int(CONTRAST_LOW)}%, indicating very low tonal range (low-contrast) and a likely flat-looking image."
        elif tag == "Borderline Contrast":
            exp = f"The 1st–99th percentile brightness spread is {int(CONTRAST_LOW)}–{int(CONTRAST_BORDERLINE)}%, which is close to the low-contrast threshold and may still look somewhat flat."
        elif tag == "Low Colorfulness":
            exp = f"Perceived colorfulness (Hasler–Süsstrunk) is <{int(CF_LOW)}, which corresponds to the 'not/slightly colourful' range on the reference scale (very muted colours, often near-grayscale)."
        elif tag == "Limited Colorfulness":
            exp = f"Perceived colorfulness (Hasler–Süsstrunk) is {int(CF_LOW)}–{int(CF_LIMITED)}, which corresponds to the 'slightly to moderately colourful' range on the reference scale (colours are present but not very vivid)."
        elif tag == "Low Color Richness":
            exp = f"Color richness (normalized Shannon entropy of a 5-bit RGB histogram) is <{int(CR_LOW)}% (≈<8 effective colors), indicating a very limited palette."
        elif tag == "Limited Color Richness":
            exp = f"Color richness is {int(CR_LOW)}–{CR_LIMITED:.1f}% (≈8–32 effective colors), indicating a limited palette."
        else:
            exp = tag

        def ensure_period(s: str) -> str:
            s = s.strip()
            return s if s.endswith('.') else (s + '.')

        parts.append((tag, ensure_period(exp)))

    return parts


def recommendation_long_for_record(tags_str: str) -> str:
    bullets = recommendation_bullets_for_record(tags_str)
    return " ".join(f"{t}: {e}" for t, e in bullets)
