from __future__ import annotations

from typing import Any

try:
    from . import cast_context as cast_context_policy
    from . import character_appearance as character_appearance_policy
    from . import character_profile as character_profile_policy
    from . import character_slot as character_slot_policy
    from . import pair_cast
    from . import pov_policy
    from . import seed_config as seed_policy
    from . import subject_context as subject_context_policy
except ImportError:  # Allows local smoke tests from the repository root.
    import cast_context as cast_context_policy
    import character_appearance as character_appearance_policy
    import character_profile as character_profile_policy
    import character_slot as character_slot_policy
    import pair_cast
    import pov_policy
    import seed_config as seed_policy
    import subject_context as subject_context_policy


def resolve_subject_route(
    *,
    subject_type: str,
    seed_config: dict[str, int],
    seed: int,
    row_number: int,
    ethnicity: str,
    figure: str,
    no_plus_women: bool,
    no_black: bool,
    women_count: int,
    men_count: int,
    character_profile: str | dict[str, Any] | None = None,
    character_cast: str | dict[str, Any] | list[Any] | None = None,
) -> dict[str, Any]:
    person_rng = seed_policy.axis_rng(seed_config, "person", seed, row_number)
    context = subject_context_policy.subject_context(
        person_rng,
        subject_type,
        ethnicity,
        figure,
        no_plus_women,
        no_black,
        women_count,
        men_count,
    )
    character_slots = character_slot_policy.parse_character_cast(character_cast)
    character_slot_map = cast_context_policy.character_slot_label_map(character_slots)
    applied_slot: dict[str, Any] = {}
    slot_status = "none"
    if context.get("subject_type") in ("woman", "man"):
        slot_label = "Woman A" if context["subject_type"] == "woman" else "Man A"
        if slot_label in character_slot_map:
            context, applied_slot = character_appearance_policy.character_context_for_label(
                slot_label,
                character_slot_map,
                person_rng,
                ethnicity,
                figure,
                no_plus_women,
                no_black,
            )
            slot_status = f"applied:{slot_label}"
            applied_profile, profile_status = {}, "skipped_character_slot"
        else:
            context, applied_profile, profile_status = character_profile_policy.apply_character_profile_to_context(
                context,
                character_profile,
            )
    else:
        context, applied_profile, profile_status = character_profile_policy.apply_character_profile_to_context(
            context,
            character_profile,
        )

    resolved_subject_type = str(context.get("subject_type") or subject_type)
    pov_character_labels = (
        pov_policy.pov_character_labels(character_slot_map, men_count)
        if resolved_subject_type == "configured_cast"
        else []
    )
    cast_descriptors: list[str] = []
    cast_descriptor_text = ""
    if resolved_subject_type == "configured_cast" and character_slots:
        cast_descriptors, _descriptor_slots = pair_cast.cast_descriptor_entries_from_slots(
            seed_config=seed_config,
            seed=seed,
            row_number=row_number,
            ethnicity=ethnicity,
            figure=figure,
            no_plus_women=no_plus_women,
            no_black=no_black,
            women_count=women_count,
            men_count=men_count,
            character_slots=character_slots,
            character_slot_map=character_slot_map,
            primary_descriptor="",
            axis_rng=seed_policy.axis_rng,
            character_context_for_label=character_appearance_policy.character_context_for_label,
            slot_is_pov=pov_policy.slot_is_pov,
        )
        cast_descriptor_text = pair_cast.prompt_cast_descriptors("; ".join(cast_descriptors))

    return {
        "context": context,
        "subject_type": resolved_subject_type,
        "character_slots": character_slots,
        "character_slot_map": character_slot_map,
        "applied_slot": applied_slot or {},
        "character_slot_status": slot_status,
        "applied_profile": applied_profile or {},
        "character_profile_status": profile_status,
        "pov_character_labels": pov_character_labels,
        "cast_descriptors": cast_descriptors,
        "cast_descriptor_text": cast_descriptor_text,
    }
