from __future__ import annotations

import re
from typing import Any

try:
    from .krea_cast import natural_label_text
except ImportError:  # Allows local smoke tests with `python -c`.
    from krea_cast import natural_label_text


def _clean(value: Any) -> str:
    text = "" if value is None else str(value)
    text = text.replace("\n", " ")
    text = re.sub(r"\s+", " ", text).strip()
    text = re.sub(r"\s+([,.;:])", r"\1", text)
    return text


def clothing_access_phrase(action_text: Any) -> str:
    text = _clean(action_text).lower()
    if any(term in text for term in ("cumshot", "ejaculat", "semen", "cum on", "cum across", "post-orgasm", "aftermath")):
        return "leaving the body exposed for visible semen and aftermath"
    if any(term in text for term in ("boobjob", "titjob", "breast sex", "handjob", "hand job", "footjob", "testicle", "balls", "penis licking", "non-penetrative")):
        return "leaving the contact point unobstructed"
    if any(term in text for term in ("oral", "blowjob", "fellatio", "mouth", "tongue")):
        return "leaving the oral contact unobstructed"
    if any(term in text for term in ("penetrat", "thrust", "penis entering", "vaginal", "anal")):
        return "leaving the penetration point unobstructed"
    return "leaving skin and body contact readable"


def natural_clothing_state(text: Any, action_text: Any = "") -> str:
    text = _clean(text)
    if not text:
        return ""
    text = re.sub(r"^Clothing state:\s*", "", text, flags=re.IGNORECASE)
    if re.search(r";\s*(?=(?:Woman|Man) [A-Z]\b)", text):
        parts = [
            natural_clothing_state(part, action_text).rstrip(".")
            for part in re.split(r";\s*(?=(?:Woman|Man) [A-Z]\b)", text)
            if _clean(part)
        ]
        return ". ".join(part for part in parts if part)
    body_exposure = re.match(r"^Body exposure:\s*(.*?)\.?$", text, flags=re.IGNORECASE)
    if body_exposure:
        return _clean(body_exposure.group(1)).rstrip(".")
    if re.search(r"\bfully nude\b|\bbody is fully exposed\b|\bno clothing covering\b", text, flags=re.IGNORECASE):
        owner = "the woman"
        owner_match = re.match(r"^\s*((?:Woman|Man) [A-Z])\b", text)
        if owner_match:
            owner = natural_label_text(owner_match.group(1), ["Woman A", "Man A"]) or owner
        return f"{owner.capitalize()}'s body is fully exposed, bare skin unobstructed"
    match = re.match(
        r"^(.*?)\b(?:softcore|teaser) outfit is (.*?)(?: for the (?:hardcore|sex) scene)?;\s*(?:softcore visual reference|teaser outfit detail):\s*(.*?)\.?$",
        text,
        flags=re.IGNORECASE,
    )
    if match:
        owner = natural_label_text(match.group(1).strip(" 's"), ["Woman A", "Man A"]).strip() or "the woman"
        state = _clean(match.group(2)).lower()
        outfit = _clean(match.group(3)).rstrip(".")
        if "fully nude" in state or "fully exposed" in state or "no clothing covering" in state:
            return f"{owner.capitalize()}'s body is fully exposed, bare skin unobstructed"
        if "nude-adjacent" in state:
            return f"{owner.capitalize()}'s body is partly exposed"
        if "partially removed" in state or "pushed aside" in state:
            return f"{owner.capitalize()}'s {outfit} is pushed aside or partly removed where needed, {clothing_access_phrase(action_text)}"
        if "keeps" in state:
            return f"{owner.capitalize()} keeps the {outfit} on while {clothing_access_phrase(action_text)}"
    text = re.sub(r";\s*(?:softcore visual reference|teaser outfit detail):\s*", ". Visual clothing state: ", text, flags=re.IGNORECASE)
    text = text.replace("softcore outfit", "outfit")
    text = text.replace("teaser outfit", "outfit")
    text = text.replace("hardcore scene", "sex scene")
    return text
