from __future__ import annotations

from typing import Any

try:
    from . import item_axis_policy
    from . import outercourse_action_policy as outercourse_policy
except ImportError:  # Allows local smoke tests with top-level imports.
    import item_axis_policy
    import outercourse_action_policy as outercourse_policy


def _context_text(item_text: str, item_axis_values: dict[str, Any] | None) -> str:
    return item_axis_policy.context_text(item_text, axis_values=item_axis_values)


def build_outercourse_role_graph(
    woman: str,
    man: str,
    item_text: str,
    item_axis_values: dict[str, Any] | None = None,
    pov_labels: list[str] | None = None,
) -> str:
    position_text = item_axis_policy.key_text(item_axis_values, "position")
    text = _context_text(item_text, item_axis_values)
    action_kind = outercourse_policy.infer_outercourse_action_kind(position_text)
    if action_kind == outercourse_policy.OUTERCOURSE_GENERIC:
        action_kind = outercourse_policy.infer_outercourse_action_kind(text)
    man_is_pov = man in set(pov_labels or [])
    if action_kind == outercourse_policy.OUTERCOURSE_BOOBJOB:
        if man_is_pov:
            return (
                f"{woman} kneels low between the POV viewer's open thighs with her torso bent forward over his pelvis, "
                "both hands pushing her breasts inward around the POV viewer's penis, the penis held between her breasts in the lower foreground, "
                "her chin and lips directly above the glans at the tip."
            )
        return (
            f"{man} sits with legs apart while {woman} kneels low between his open thighs with her torso bent forward over his pelvis, "
            f"{woman}'s hands pushing her breasts inward around {man}'s penis, the penis held between her breasts, "
            "her chin and lips directly above the glans at the tip."
        )
    if action_kind == outercourse_policy.OUTERCOURSE_TESTICLE:
        if man_is_pov:
            return (
                f"{woman} lies low in a side-pelvis POV beside the POV viewer's open thighs, "
                "her face is the closest visible partner part, her cheek against the POV viewer's inner thigh and her head low under his pelvis, "
                "with the POV viewer's scrotum at her mouth; scrotum is the mouth surface, testicles resting across her open lips while her tongue cups them from below, "
                "scrotal skin is the nearest mouth surface and both testicles rest against her tongue from below, "
                "and his abdomen and inner thighs frame the close foreground."
            )
        return (
            f"{man} reclines with legs apart while {woman} lies low beside his inner thigh, "
            f"her face as the closest visible partner part, her cheek against his thigh and her head low under his pelvis, "
            f"with {man}'s scrotum at her mouth; scrotum is the mouth surface, scrotal skin is the nearest mouth surface, and testicles resting across her open lips while both testicles rest against her tongue from below."
        )
    if action_kind == outercourse_policy.OUTERCOURSE_PENIS_LICKING:
        prone_laying = any(
            term in f"{position_text} {text}"
            for term in ("reclining", "prone", "belly-down", "belly down", "lying")
        )
        if prone_laying:
            if man_is_pov:
                return (
                    f"{woman} lies belly-down between the POV viewer's open thighs while his thighs form a wide V-frame in the foreground, "
                    "her torso stretched low and horizontal between his knees, her front-facing mouth and tongue aligned to the POV viewer's penis, "
                    "and her hands wrap the base of the POV viewer's penis."
                )
            return (
                f"{woman} lies belly-down between {man}'s open thighs while his thighs form a wide V-frame in the foreground, "
                f"her torso stretched low and horizontal between his knees, her front-facing mouth and tongue aligned to {man}'s penis, "
                f"and her hands wrap the base of {man}'s penis."
            )
        if man_is_pov:
            return (
                f"{woman} bends forward between the POV viewer's open thighs with her head low under the POV viewer's penis, "
                "her face just under the penis while her tongue touches the underside from the base toward the glans at the tip, "
                "one hand steadying the base of the POV viewer's penis."
            )
        return (
            f"{woman} bends forward between {man}'s open thighs with her head low under {man}'s penis, "
            f"her face just under the penis while her tongue touches the underside from the base toward the glans at the tip, "
            f"one hand steadying the base of {man}'s penis."
        )
    if action_kind == outercourse_policy.OUTERCOURSE_FOOTJOB:
        if man_is_pov:
            return (
                f"{woman} faces the POV viewer with hips back, torso visible behind her raised legs, and both knees bent open toward the camera, "
                "while two large overlapping soles dominate the POV viewer's lower center foreground and clamp the POV viewer's upright shaft between them. "
                "Her inner arches press inward from both sides, toes curl around both edges, a narrow visible strip of shaft and glans rises between the compressed feet, "
                "and her face and torso stay visible behind the large foreground feet."
            )
        return (
            f"{man} reclines with hips forward while {woman} faces him with her hips back and both knees bent open, "
            f"two large overlapping soles dominating the lower center foreground as her inner arches press inward around {man}'s upright shaft, "
            "her toes curl around both edges, and a narrow visible strip of shaft and glans rises between the compressed feet."
        )
    if action_kind == outercourse_policy.OUTERCOURSE_HANDJOB:
        if man_is_pov:
            return (
                f"{woman} kneels between the POV viewer's open thighs with her torso leaning forward and face visible behind the POV viewer's penis, "
                "one hand grips and strokes the POV viewer's penis in the lower foreground while the other hand steadies its base, "
                "thumb and fingers visible around the penis as she strokes toward the glans."
            )
        return (
            f"{woman} kneels between {man}'s open thighs with her torso leaning forward and face visible behind {man}'s penis, "
            f"one hand grips and strokes {man}'s penis while the other hand steadies its base, "
            "thumb and fingers visible around the penis as she strokes toward the glans."
        )
    if man_is_pov:
        return (
            f"{woman} kneels close to the POV viewer's hips and keeps the POV viewer's penis centered in clear non-penetrative contact, "
            "with her mouth, hands, breasts, or feet visibly working around the penis shaft."
        )
    return (
        f"{woman} kneels close to {man}'s hips and keeps {man}'s penis centered in clear non-penetrative contact, "
        "with her mouth, hands, breasts, or feet visibly working around the penis shaft."
    )
